This repository has been archived on 2023-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
dotfiles/.config/nvim/lua/statusline.lua

257 lines
7.0 KiB
Lua
Raw Normal View History

-- Author : swytch
-- Created : Friday Mar 12, 2021 21:45:21 CET
-- License : GPLv3
-- Description : neovim statusline file
-- based on github/nihilistkitten's work
local function gen_section(hl_string, items)
local out = ""
for _, item in pairs(items) do
if item ~= "" then
out = out .. " " .. item
end
end
if out ~= "" then
return hl_string .. out .. " "
else
return out
end
end
-- sensible names for vim modes
local function get_mode(m)
local mode_group = {
["n"] = "Normal",
["no"] = "O-Pending",
["nov"] = "O-Pending",
["noV"] = "O-Pending",
["no"] = "O-Pending",
["niI"] = "Normal",
["niR"] = "Normal",
["niV"] = "Normal",
["v"] = "Visual",
["V"] = "V-Line",
[""] = "V-Block",
["s"] = "Select",
["S"] = "S-Line",
[""] = "S-Block",
["i"] = "Insert",
["ic"] = "Insert",
["ix"] = "Insert",
["R"] = "Replace",
["Rc"] = "Replace",
["Rv"] = "V-Replace",
["Rx"] = "Replace",
["c"] = "Command",
["cv"] = "Ex",
["ce"] = "Ex",
["r"] = "Prompt",
["rm"] = "Prompt",
["r?"] = "Prompt",
["!"] = "Shell",
["t"] = "Terminal",
}
return mode_group[m] or "None"
end
local function get_mode_display_name(m)
local mode = {
["Normal"] = "[ NRM ]",
["O-Pending"] = "[ OTR ]",
["Visual"] = "[ VSL ]",
["V-Line"] = "[ V·L ]",
["V-Block"] = "[ V·B ]",
["Select"] = "[ SEL ]",
["S-Line"] = "[ S·L ]",
["S-Block"] = "[ S·B ]",
["Insert"] = "[ INS ]",
["Replace"] = "[ RPL ]",
["Command"] = "[ CMD ]",
["Prompt"] = "[ PMT ]",
["Shell"] = "[ SHL ]",
["Terminal"] = "[ TRM ]",
["None"] = "[ --- ]"
}
return mode[m]
end
-- get the highlight group for a mode group
local function get_mode_color(m)
local color = {
["Normal"] = "%#NormalMode#",
["O-Pending"] = "%#NormalMode#",
["Visual"] = "%#VisualMode#",
["V-Line"] = "%#VisualMode#",
["V-Block"] = "%#VisualMode#",
["Select"] = "%#NormalMode#",
["S-Line"] = "%#NormalMode#",
["S-Block"] = "%#NormalMode#",
["Insert"] = "%#InsertMode#",
["Replace"] = "%#ReplaceMode#",
["Command"] = "%#CommandMode#",
["Prompt"] = "%#NormalMode#",
["Shell"] = "%#NormalMode#",
["Terminal"] = "%#NormalMode#",
["None"] = "%#NormalMode#"
}
return color[m]
end
-- from https://github.com/nvim-lualine/lualine.nvim/blob/master/lua/lualine/components/filename.lua
local function shorten_path(path, max_len)
local sep = '/'
local len = #path
if len <= max_len then
return path
end
local segments = vim.split(path, sep)
local start = 1
if segments[1] == "~" then
start = start + 1
end
for idx = start, #segments - 1 do
if len <= max_len then
break
end
local segment = segments[idx]
local short_end = 1
if (vim.startswith(segment, '.') or vim.startswith(segment, '_')) then
short_end = 2
end
local shortened = segment:sub(1, short_end)
segments[idx] = shortened
len = len - (#segment - #shortened)
end
if (len > max_len and #segments > 3) then
while (len > max_len and #segments > 3) do
table.remove(segments, 2)
end
table.insert(segments,2, "...")
end
return table.concat(segments, sep)
end
-- from https://github.com/nvim-lua/lsp-status.nvim/blob/master/lua/lsp-status/diagnostics.lua
local function get_lsp_diagnostics()
local result = {}
local levels = {
error = "Error",
warn = "Warn",
info = "Info",
hint = "Hint"
}
for k, level in pairs(levels) do
local count = 0
local diags = vim.diagnostic.get(0, { severity = level })
for _, _ in pairs(diags) do
count = count + 1
end
result[k] = count
end
return result
end
local function process_diagnostics(prefix, n, hl)
if n > 0 then
return hl .. prefix .. n
else
return ""
end
end
local function spell_check()
if vim.wo.spell then
local lang = vim.o.spelllang
return "[SPELL=" .. lang .. "]"
else
return ""
end
end
local function statusline_focused()
local file = vim.fn.expand("%:p:~")
local diagnostics = get_lsp_diagnostics()
local mode = vim.fn.mode()
local mg = get_mode(mode)
local accent_color = get_mode_color(mg)
local winwidth = vim.fn.winwidth(0)
local left = table.concat {
gen_section(accent_color, { get_mode_display_name(mg) }),
gen_section("%#Middle#", { shorten_path(file, winwidth / 2) }),
gen_section("%#Bottom#", { "%m", "%r" }),
gen_section(
"%#Alert#",
{
process_diagnostics(
globals.sign_error .. " ",
diagnostics.error,
"%#DiagnosticVirtualTextError#"
),
process_diagnostics(
globals.sign_warn .. " ",
diagnostics.warn,
"%#DiagnosticVirtualTextWarn#"
),
process_diagnostics(
globals.sign_info .. " ",
diagnostics.info,
"%#DiagnosticVirtualTextInfo#"
)
}
)
}
local right = table.concat {
gen_section(
"%#Bottom#",
{
spell_check(),
vim.bo.filetype
}
),
gen_section("%#Middle#", { "%03.p%%" }),
gen_section("%#Top#", { "-%03.c-" })
}
return table.concat {
left,
"%#Statusline#",
"%=",
right
}
end
local function statusline_not_focused()
local bufnr = vim.fn.winbufnr(vim.g.statusline_winid)
local file = vim.fn.expand("#" .. bufnr .. ":p:~")
local winwidth = vim.fn.winwidth(0)
return table.concat {
gen_section("%#StatuslineNF#", {
shorten_path(file, winwidth / 2),
"%m"
}),
"%=",
gen_section("%#StatuslineNF#", { "%03.p%%" }),
gen_section("%#StatuslineNF#", { "-%03.c-" })
}
end
2021-05-21 21:45:36 +02:00
function _G.gen_statusline()
if vim.g.statusline_winid == vim.fn.win_getid() then
return statusline_focused()
else
return statusline_not_focused()
end
end
vim.o.statusline = "%!luaeval(\"gen_statusline()\")"