" Show the statusline above the commandline. scriptencoding utf-8 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']} let g:statusline#dark_grey = {'fg': ['244', '#808080'], '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 shows changes in the file by changing the colour of the " filename, give if a dark background. call s:hi('StatusLineChange', g:statusline#dark_yellow) " StatusLineFade shows the status of completion engines but using colors which " fade into the background to avoid grabbing attention. call s:hi('StatusLineDuskFade', g:statusline#dark_grey) " 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 coc.nvim status. let l:coc = '%#StatusLineDuskFade#%( %{coc#status()}%)' " 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:coc.'%='.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() 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') elseif &previewwindow if l:mode ==# 'Normal' let l:mode = 'Preview' endif return statusline#generic('StatusLineLight', l:mode) elseif &filetype ==# 'man' return statusline#special('StatusLineDusk', 'Manual', '%f') endif return statusline#generic('StatusLineLight', l:mode) endfunction " Define inactive statusline, this remains static until the buffer gains " focus again. function! statusline#inactive() 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') elseif &previewwindow let l:statusline = statusline#generic('StatusLineDusk', 'Preview') elseif &filetype ==# 'man' let l:statusline = statusline#special('StatusLineDusk', 'Manual', '%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_blue], \ '!': ['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