From 0be0254b1df784654a7cc27ae8e339155b3fea14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Wed, 11 May 2022 14:28:04 +0200 Subject: [PATCH] Rewrite statusline in lua --- .../nvim/lua/esensar/lsp/diagnostic.lua | 3 +- .../config/nvim/lua/esensar/ui/statusline.lua | 217 ++++++++++++++++++ symlinks/config/nvim/plugin/statusline.lua | 5 + symlinks/config/nvim/plugin/statusline.vim | 185 --------------- 4 files changed, 224 insertions(+), 186 deletions(-) create mode 100644 symlinks/config/nvim/lua/esensar/ui/statusline.lua create mode 100644 symlinks/config/nvim/plugin/statusline.lua delete mode 100644 symlinks/config/nvim/plugin/statusline.vim diff --git a/symlinks/config/nvim/lua/esensar/lsp/diagnostic.lua b/symlinks/config/nvim/lua/esensar/lsp/diagnostic.lua index 737e4cb..14a8749 100644 --- a/symlinks/config/nvim/lua/esensar/lsp/diagnostic.lua +++ b/symlinks/config/nvim/lua/esensar/lsp/diagnostic.lua @@ -62,5 +62,6 @@ null_ls.setup({ vim.keymap.set("n", "]w", vim.diagnostic.goto_next) vim.keymap.set("n", "[w", vim.diagnostic.goto_prev) -vim.api.nvim_create_user_command("Warnings", vim.diagnostic.setloclist, {}) +vim.api.nvim_create_user_command("Warnings", vim.diagnostic.setqflist, {}) +vim.api.nvim_create_user_command("WarningsLoc", vim.diagnostic.setloclist, {}) vim.api.nvim_create_user_command("Format", vim.lsp.buf.formatting, {}) diff --git a/symlinks/config/nvim/lua/esensar/ui/statusline.lua b/symlinks/config/nvim/lua/esensar/ui/statusline.lua new file mode 100644 index 0000000..83af260 --- /dev/null +++ b/symlinks/config/nvim/lua/esensar/ui/statusline.lua @@ -0,0 +1,217 @@ +-- Lua personal statusline + +local filetype_glyphs = { + rust = "%2*%*", + c = "%4*%*", + cs = "%4*%*", + python = "%3*%*", + javascript = "", + typescript = "%4*%*", + vim = "%1*%*", + clojure = "", + html = "", + haskell = "", + markdown = "", + org = "", + scss = "", + scala = "", + elixir = "%5*%*", + kotlin = "%2*洞%*", + yml = "", + toml = "", + json = "", +} + +local edit_modes = { + n = "N", + i = "%3*I%*", + v = "%1*V%*", + V = "%1*V.%*", + [""] = "%1*VB%*", + c = "%4*C%*", +} + +local function update_colors() + local status_line_hl = vim.api.nvim_get_hl_by_name("StatusLine", true) + local bg = status_line_hl.foreground + + local function set_user_highlight_based_on(user_hl_name, based_on) + local hl_based_on = vim.api.nvim_get_hl_by_name(based_on, true) + local user_config = { + foreground = hl_based_on.foreground, + background = bg, + bold = true, + } + vim.api.nvim_set_hl(0, user_hl_name, user_config) + end + + set_user_highlight_based_on("User1", "Function") + set_user_highlight_based_on("User2", "WarningMsg") + set_user_highlight_based_on("User3", "MoreMsg") + set_user_highlight_based_on("User4", "Identifier") + set_user_highlight_based_on("User5", "Number") +end + +local function get_filetype_string() + return filetype_glyphs[vim.o.filetype] or "%y" +end + +local function get_mode_string() + local mode = vim.fn.mode() + local mode_fallback = "[mode: " .. mode .. "]" + return edit_modes[mode] or mode_fallback +end + +local function get_paste_string() + if vim.o.paste then + return " [paste] " + else + return "" + end +end + +local function get_diagnostics_status() + local diagnostics = vim.diagnostic.get(0) + + local error_count = #vim.tbl_filter(function(d) + return d.severity == vim.diagnostic.severity.ERROR + end, diagnostics) + local non_error_count = #diagnostics - error_count + + if #diagnostics == 0 then + return "%1*OK%*" + else + return string.format("%%3*%d%%* %%2*%d%%*", non_error_count, error_count) + end +end + +local function blank_override() + return "" +end + +local function centered_title_override(title) + return { + left = function() + return "%= " .. title .. " %=" + end, + right = blank_override, + } +end + +local dapui_override = { + active = centered_title_override("%f"), +} + +local ft_overrides = { + fugitive = { + active = centered_title_override("===GIT FUGITIVE==="), + inactive = centered_title_override("GIT FUGITIVE"), + }, + help = { + active = { + left = function() + return " Documentation: %2*%f%*" + end, + }, + inactive = centered_title_override("Documentation: %f"), + }, + dbui = { + active = centered_title_override("DBUI"), + inactive = centered_title_override("DBUI"), + }, + ["dap-repl"] = { + active = centered_title_override("DAP REPL"), + inactive = centered_title_override("DAP REPL"), + }, + dapui_watches = dapui_override, + dapui_stacks = dapui_override, + dapui_breakpoints = dapui_override, + dapui_scopes = dapui_override, +} + +local function get_override(filetype) + return vim.tbl_extend("keep", ft_overrides[filetype] or {}, { + active = {}, + inactive = {}, + }) +end + +local function get_current_override() + local bufnr = vim.fn.winbufnr(vim.g.statusline_winid) + return get_override(vim.api.nvim_buf_get_option(bufnr, "filetype")) +end + +local statuslines = { + active = function() + local override = get_current_override().active + + local function build_left_side() + if override.left then + return override.left() + end + local status = " " .. get_mode_string() .. " " -- starting with current mode + if vim.g.loaded_fugitive then -- then git status + local head = vim.fn.FugitiveHead() + if string.len(head) > 0 then + status = status .. "%4* " .. head .. "%*" + end + end + status = status .. " %f" -- Filename + status = status .. " %1*%M%*" -- Modified + status = status .. " %2*%r%*" -- Read only + status = status .. get_paste_string() + -- TODO: Add lsp status + -- TODO: Add current container if devcontainer is used + return status + end + + local function build_right_side() + if override.right then + return override.right() + end + local status = "%= " -- Align right + status = status .. get_diagnostics_status() + status = status .. " %2c:%3l/%3L (%3p%%) " -- col, line, tot. lines + status = status .. get_filetype_string() .. " " -- File type + return status + end + + return build_left_side() .. build_right_side() + end, + inactive = function() + local override = get_current_override().inactive + + local build_left_side = override.left or centered_title_override("%f").left + local build_right_side = override.right or blank_override + return build_left_side() .. build_right_side() + end, +} + +return { + statuslines = statuslines, + setup = function() + update_colors() + local au_id = vim.api.nvim_create_augroup("statuslineconf", {}) + vim.api.nvim_create_autocmd("ColorScheme", { + pattern = "*", + group = au_id, + callback = function() + update_colors() + end, + }) + vim.api.nvim_create_autocmd({ "WinEnter", "BufEnter" }, { + pattern = "*", + group = au_id, + callback = function() + vim.wo.statusline = "%!v:lua.require'esensar.ui.statusline'.statuslines.active()" + end, + }) + vim.api.nvim_create_autocmd({ "WinLeave", "BufLeave" }, { + pattern = "*", + group = au_id, + callback = function() + vim.wo.statusline = "%!v:lua.require'esensar.ui.statusline'.statuslines.inactive()" + end, + }) + end, +} diff --git a/symlinks/config/nvim/plugin/statusline.lua b/symlinks/config/nvim/plugin/statusline.lua new file mode 100644 index 0000000..7801379 --- /dev/null +++ b/symlinks/config/nvim/plugin/statusline.lua @@ -0,0 +1,5 @@ +------------------------------------------------------------------------------- +-- - Statusline setup - +------------------------------------------------------------------------------- + +require("esensar.ui.statusline").setup() diff --git a/symlinks/config/nvim/plugin/statusline.vim b/symlinks/config/nvim/plugin/statusline.vim deleted file mode 100644 index f0f98c6..0000000 --- a/symlinks/config/nvim/plugin/statusline.vim +++ /dev/null @@ -1,185 +0,0 @@ -" ----------------------------------------------------------------------------- -" - Statusline setup - -" ----------------------------------------------------------------------------- - -function s:UpdateColors() - let ctermbg = synIDattr(synIDtrans(hlID('StatusLine')), 'fg', 'cterm') - let guibg = synIDattr(synIDtrans(hlID('StatusLine')), 'fg', 'gui') - let idguifg1 = synIDattr(synIDtrans(hlID('Function')), 'fg', 'gui') - let idctermfg1 = synIDattr(synIDtrans(hlID('Function')), 'fg', 'cterm') - " Green in gruvbox - exec 'hi User1 guifg=' . l:idguifg1 . - \' guibg=' . l:guibg . - \' cterm=bold gui=bold' - if l:idctermfg1 - exec 'hi User1 ctermfg=' . l:idctermfg1 - endif - let idguifg2 = synIDattr(synIDtrans(hlID('WarningMsg')), 'fg', 'gui') - let idctermfg2 = synIDattr(synIDtrans(hlID('WarningMsg')), 'fg', 'cterm') - " Red in gruvbox - exec 'hi User2 guifg=' . l:idguifg2 . - \' guibg=' . l:guibg . - \' cterm=bold gui=bold' - if l:idctermfg2 - exec 'hi User2 ctermfg=' . l:idctermfg2 - endif - let idguifg3 = synIDattr(synIDtrans(hlID('MoreMsg')), 'fg', 'gui') - let idctermfg3 = synIDattr(synIDtrans(hlID('MoreMsg')), 'fg', 'cterm') - " Yellow in gruvbox - exec 'hi User3 guifg=' . l:idguifg3 . - \' guibg=' . l:guibg . - \' cterm=bold gui=bold' - if l:idctermfg3 - exec 'hi User3 ctermfg=' . l:idctermfg3 - endif - let idguifg4 = synIDattr(synIDtrans(hlID('Identifier')), 'fg', 'gui') - let idctermfg4 = synIDattr(synIDtrans(hlID('Identifier')), 'fg', 'cterm') - " Blue in gruvbox - exec 'hi User4 guifg=' . l:idguifg4 - \' guibg=' . l:guibg . - \' cterm=bold gui=bold' - if l:idctermfg4 - exec 'hi User4 ctermfg=' . l:idctermfg4 - endif - let idguifg5 = synIDattr(synIDtrans(hlID('Number')), 'fg', 'gui') - let idctermfg5 = synIDattr(synIDtrans(hlID('Number')), 'fg', 'cterm') - " Blue in gruvbox - exec 'hi User5 guifg=' . l:idguifg5 . - \' guibg=' . l:guibg . - \' cterm=bold gui=bold' - if l:idctermfg5 - exec 'hi User5 ctermfg=' . l:idctermfg5 - endif - - if l:ctermbg - exec 'hi User1 ctermbg=' . l:ctermbg - exec 'hi User2 ctermbg=' . l:ctermbg - exec 'hi User3 ctermbg=' . l:ctermbg - exec 'hi User4 ctermbg=' . l:ctermbg - exec 'hi User5 ctermbg=' . l:ctermbg - endif -endfunction - -augroup statuslineconf - autocmd! - autocmd ColorScheme * call s:UpdateColors() -augroup END - -call s:UpdateColors() - - -" Checks file type to add a pretty glyph if available -function s:GetFileType() - if &filetype ==# "rust" - return "%2*%*" - elseif &filetype ==# "c" - return "%4*%*" - elseif &filetype ==# "cs" - return "%4*%*" - elseif &filetype ==# "python" - return "%3*%*" - elseif &filetype ==# "javascript" - return "" - elseif &filetype ==# "typescript" - return "%4*%*" - elseif &filetype ==# "vim" - return "%1*%*" - elseif &filetype ==# "clojure" - return "" - elseif &filetype ==# "html" - return "" - elseif &filetype ==# "haskell" - return "" - elseif &filetype ==# "markdown" - return "" - elseif &filetype ==# "org" - return "" - elseif &filetype ==# "scss" - return "" - elseif &filetype ==# "scala" - return "" - elseif &filetype ==# "elixir" - return "%5*%*" - elseif &filetype ==# "kotlin" - return "%2*洞%*" - elseif &filetype ==# "yml" - return "" - elseif &filetype ==# "toml" - return "" - elseif &filetype ==# "json" - return "" - else - return "%y" -endfunction - -" Check current mode to add colorized mode -function s:GetMode() - if mode() == "n" - return "N" - elseif mode() == "i" - return "%3*I%*" - elseif mode() == "v" - return "%1*V%*" - elseif mode() == "V" - return "%1*V.%*" - elseif mode() == "\" - return "%1*VB%*" - elseif mode() == "c" - return "%4*C%*" - else - return "[mode: " . mode() . "]" -endfunction - -" Add basic [paste] if paste mode is enabled -function! s:PasteForStatusline() - let paste_status = &paste - if paste_status == 1 - return " [paste] " - else - return "" - endif -endfunction - -function! s:LinterStatus() abort - let l:counts = ale#statusline#Count(bufnr('')) - - let l:all_errors = l:counts.error + l:counts.style_error - let l:all_non_errors = l:counts.total - l:all_errors - - return l:counts.total == 0 ? '%1*OK%*' : printf( - \ '%%3*%dW%%* %%2*%dE%%*', - \ all_non_errors, - \ all_errors - \) -endfunction - -function GetStatusLine() - let l:status_line_left = " " . s:GetMode() . " " - if exists('g:loaded_fugitive') - let l:fugitive_head = FugitiveHead() - if strlen(l:fugitive_head) - let l:status_line_left .= "%4* " . l:fugitive_head . "%*" - endif - endif - let l:status_line_left .= " %f" " Filename - let l:status_line_left .= " %1*%M%*" " Modified - let l:status_line_left .= " %2*%r%*" " Read only - let l:status_line_left .= s:PasteForStatusline() - if exists('g:did_coc_loaded') - let l:coc_status = coc#status() - if strlen(l:coc_status) - let l:status_line_left .= "%2*" . l:coc_status . "%*" - endif - endif - if exists('g:currentContainer') - let l:status_line_left .= "%5*" . g:currentContainer . "%*" - endif - let l:status_line_right = "%= " " Align right statusline - if exists('g:loaded_ale') - let l:status_line_right .= s:LinterStatus() " ALE status - endif - let l:status_line_right .= " %2c:%3l/%3L (%3p%%) " " col, line, tot. lines - let l:status_line_right .= s:GetFileType() . " " " File type - return l:status_line_left . l:status_line_right -endfunction -set statusline=%!GetStatusLine()