From fb0b1e28258585d1e0cf912340592e9495a19cc0 Mon Sep 17 00:00:00 2001 From: "Kenneth Benzie (Benie)" Date: Sun, 7 Feb 2021 21:06:11 +0000 Subject: [PATCH] Replace vim-airline with a custom statusline Finally got round to making a custom statusline after being inspired by https://pastebin.com/Fm1NEgBf --- plugin/settings.vim | 6 -- plugin/statusline.vim | 164 ++++++++++++++++++++++++++++++++++++++++++ vimrc | 8 --- 3 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 plugin/statusline.vim diff --git a/plugin/settings.vim b/plugin/settings.vim index 82c2b8c..55a4c64 100644 --- a/plugin/settings.vim +++ b/plugin/settings.vim @@ -16,12 +16,6 @@ if !has('nvim') && &ttimeoutlen == -1 set ttimeoutlen=100 endif -" TODO: These might be irrelevant with vim-airline -" Show 2 line status -set laststatus=2 -" Show the line and colum number of a cursor position -set ruler - " Enhanced command line completion set wildmenu " Command line history diff --git a/plugin/statusline.vim b/plugin/statusline.vim new file mode 100644 index 0000000..1d0299d --- /dev/null +++ b/plugin/statusline.vim @@ -0,0 +1,164 @@ +" Show the statusline above the commandline. +set laststatus=2 + +" Define color variables. +let g:statusline#light_green = {'fg': ['235', '#080808'], 'bg': [ '35', '#0087ff']} +let g:statusline#light_blue = {'fg': ['235', '#080808'], 'bg': [ '33', '#0087ff']} +let g:statusline#light_orange = {'fg': ['235', '#080808'], 'bg': ['209', '#eb754d']} +let g:statusline#light_red = {'fg': ['235', '#080808'], 'bg': ['124', '#af0000']} +let g:statusline#light_grey = {'fg': ['250', "#bcbcbc"], 'bg': ['236', "#303030"]} +let g:statusline#light_violet = {'fg': ['235', '#080808'], 'bg': [ '99', '#986fec']} +let g:statusline#dark_white = {'fg': [ '15', '#ffffff'], 'bg': ['233', '#121212']} +let g:statusline#dark_yellow = {'fg': ['179', '#dfaf5f'], 'bg': ['233', '#121212']} + +" Create highlight groups. +function! s:hi(group, color) abort + execute 'highlight '.a:group + \.' ctermfg='.a:color['fg'][0].' ctermbg='.a:color['bg'][0] + \.' guifg='.a:color['fg'][1].' guibg='.a:color['fg'][1] +endfunction + +" StatusLineLight is shows the mode and cursor information, it is dynamically +" changed by statusline#mode(), give it a default. +call s:hi('StatusLineLight', g:statusline#light_grey) +" StatusLineDusk is shows additional information which is not always present, +" give it a muted color. +call s:hi('StatusLineDusk', g:statusline#light_grey) +" StatusLineDark shows the filename and filetype and takes up most of the +" statusline, give it a dark background. +call s:hi('StatusLineDark', g:statusline#dark_white) +" StatusLineChange show changes in the file by changing the colour of the +" filename, give if a dark background. +call s:hi('StatusLineChange', g:statusline#dark_yellow) + +" Construct a statusline for special buffer types. +function! statusline#special(group, name, title) + " Display current mode with dynamic highlights. + let l:mode = '%#'.a:group.'# '.a:name.' ' + " Display filename with dark highlights. + let l:file = '%#StatusLineDark# '.a:title + " Display current/total lines and column with dynamic highlights. + let l:line = '%#'.a:group.'# ☰ %l/%L ㏑%2c ' + " Combine the elements into a single string to be evaluated. + return l:mode.l:file.'%='.l:line +endfunction + +" Construct a statusline for generic buffer types. +function! statusline#generic(group, mode) + " Display current mode with dynamic highlights. + let l:mode = '%#'.a:group.'# '.a:mode.' ' + " Display spell or paste if set with dusk highlights in a group to swallow + " the spaces when empty. + let l:edit = '%#StatusLineDusk#%( ' + \.'%{&spell ? "Spell " : ""}' + \.'%{&paste ? "Paste " : ""}' + \.'%)' + " Display filename with dark or changed highlights. + let l:file = (&modified ? '%#StatusLineChange#' : '%#StatusLineDark#').' %f' + " Display readonly and nomodifiable if set. + let l:state = '%#StatusLineDark#' + \.'%{&readonly ? " 🔒" : ""}' + \.'%{&modifiable ? "" : " ⛔"}' + " Display filetype if set. + let l:type = '%#StatusLineDark# %{&filetype} ' + " Display fileencoding if not utf-8 and fileformat if not unix with dusk + " highlights in a group to swallow spaces when empty. + let l:format = '%#StatusLineDusk#%( ' + \.'%{&fileencoding ==# "utf-8" ? "" : &fileencoding}' + \.'%{&fileformat ==# "unix" ? "" : "[".&fileformat."]"}' + \.' %)' + " Display current/total lines and column with dynamic highlights. + let l:line = '%#'.a:group.'# ☰ %l/%L ㏑%2c ' + " Combine the elements into a single string to be evaluated. + return l:mode.l:edit.l:file.l:state.'%='.l:type.l:format.l:line +endfunction + +" Define active statusline, this statusline is dynamic with StatusLineLight +" being updated based on the current mode and only used for current buffer. +function! statusline#active() + " TODO: Specialize for: + " * [x] help + " * [x] quickfix + " * [x] location + " * [ ] preview + " * [x] terminal + let l:mode = statusline#mode() + if &buftype ==# 'help' + if l:mode ==# 'Normal' + let l:mode = 'Help' + endif + return statusline#special('StatusLineLight', l:mode, '%F') + elseif &buftype ==# 'quickfix' + " Quickfix list and location list have the same buftype, the window has a + " loclist flag, query the window info. + let l:info = getwininfo(win_getid())[0] + if l:mode ==# 'Normal' + let l:mode = l:info['loclist'] ? 'Location' : 'Quickfix' + endif + return statusline#special('StatusLineLight', l:mode, + \ get(l:info['variables'], 'quickfix_title', '')) + elseif &buftype ==# 'terminal' + return statusline#special('StatusLineLight', 'Terminal', '%f') + endif + return statusline#generic('StatusLineLight', l:mode) +endfunction + +" Define inactive statusline, this remains static until the buffer gains +" focus again. +function! statusline#inactive() + " TODO: Specialize for: + " * [x] help + " * [x] quickfix + " * [x] location + " * [ ] preview + " * [x] terminal + if &buftype ==# 'help' + let l:statusline = statusline#special('StatusLineDusk', 'Help', '%F') + elseif &buftype ==# 'quickfix' + " Quickfix list and location list have the same buftype, the window has a + " loclist flag, query the window info. + let l:info = getwininfo(win_getid())[0] + let l:statusline = statusline#special('StatusLineDusk', + \ l:info['loclist'] ? 'Location' : 'Quickfix', + \ get(l:info['variables'], 'quickfix_title', '')) + elseif &buftype ==# 'terminal' + let l:statusline = statusline#special('StatusLineDusk', 'Terminal', '%f') + else + let l:statusline = statusline#generic('StatusLineDusk', 'Idle') + endif + " Escape spaces and double quotes for use in setlocal. + let l:statusline = substitute(l:statusline, '\([ "]\)', '\\\0', 'g') + execute 'setlocal statusline='.l:statusline +endfunction + +" Get statusline mode and update StatusLineLight. +function! statusline#mode() + " Map modes to a human readable name and a color. + let l:mode = { + \ 'n': ['Normal', g:statusline#light_green], + \ 'i': ['Insert', g:statusline#light_blue], + \ 'c': ['Command', g:statusline#light_green], + \ 'v': ['Visual', g:statusline#light_orange], + \ 'V': ['V-Line', g:statusline#light_orange], + \ '': ['V-Block', g:statusline#light_orange], + \ 'R': ['Replace', g:statusline#light_red], + \ 's': ['Select', g:statusline#light_violet], + \ 'S': ['S-Line', g:statusline#light_violet], + \ '': ['S-Block', g:statusline#light_violet], + \ 't': ['Terminal', g:statusline#light_grey], + \ '!': ['Shell', g:statusline#light_grey], + \}[mode()] + " Update the StatusLineLight color. + call s:hi('StatusLineLight', l:mode[1]) + return l:mode[0] +endfunction + +" Setup autocmds to set the statusline per buffer. +augroup benieStatusLine + autocmd! + " Dynamically update the current buffer mode and color changes using %! to + " call a function which is always evaluated on statusline update. + autocmd BufEnter,WinEnter,BufWinEnter * setlocal statusline=%!statusline#active() + " Statically set the statusline when leaving the buffer. + autocmd BufLeave,WinLeave * call statusline#inactive() +augroup END diff --git a/vimrc b/vimrc index 81fc9c1..df542d7 100644 --- a/vimrc +++ b/vimrc @@ -23,14 +23,6 @@ endif set runtimepath+=~/.config/work set packpath+=~/.config/work -" vim-airline - improved status bar -Pack 'vim-airline/vim-airline' -let g:airline#extensions#branch#enabled = 0 -let g:airline#extensions#hunks#enabled = 0 -let g:airline#extensions#wordcount#enabled = 0 -for s:setting in ['left_sep', 'right_sep', 'section_error', 'section_warning'] - exec 'let g:airline_'.s:setting.' = ""' -endfor " tabline.vim - sanely numbered tabs Pack 'mkitt/tabline.vim'