Search code examples
vim

vim - What's the best way to set statusline color to change, based on mode


I've tried to improve my vim experience trying to have the vim statusline color to change everytime the mode changes.

I've triend this: (found here)

    "Automatically change the statusline color depending on mode
function! ChangeStatuslineColor()
  if (mode() =~# '\v(n|no)')
    exe 'hi! StatusLine ctermfg=008'
  elseif (mode() =~# '\v(v|V)' || g:currentmode[mode()] ==# 'V·Block' || get(g:currentmode, mode(), '') ==# 't')
    exe 'hi! StatusLine ctermfg=005'
  elseif (mode() ==# 'i')
    exe 'hi! StatusLine ctermfg=004'
  else
    exe 'hi! StatusLine ctermfg=006'
  endif

  return ''
endfunction

...and include:

set statusline+=%{ChangeStatuslineColor()} 

But there's an issue, if you switch to insert mode and then press Esc to come back to normal mode, it doesn't change back the color. It'll change back the color only when you manually enter a different mode.


Solution

  • Sorry for necroposting, but I think I found a way better solution for this task. Set up desired colors like this

    hi NormalColor guifg=Black guibg=Green ctermbg=46 ctermfg=0
    hi InsertColor guifg=Black guibg=Cyan ctermbg=51 ctermfg=0
    hi ReplaceColor guifg=Black guibg=maroon1 ctermbg=165 ctermfg=0
    hi VisualColor guifg=Black guibg=Orange ctermbg=202 ctermfg=0
    

    Now add to statusline

    set statusline+=%#NormalColor#%{(mode()=='n')?'\ \ NORMAL\ ':''}
    set statusline+=%#InsertColor#%{(mode()=='i')?'\ \ INSERT\ ':''}
    set statusline+=%#ReplaceColor#%{(mode()=='R')?'\ \ REPLACE\ ':''}
    set statusline+=%#VisualColor#%{(mode()=='v')?'\ \ VISUAL\ ':''}
    

    It works perfect, doesn't need any workarounds for visual mode and doesn't require additional cursor movements to trigger color change.