itchyny/lightline.vim

Update tabline color on mode change

dkaszews opened this issue · 3 comments

I would like to be able to change tabline colors depending on the current mode, so that they match statusline. Currently I managed to hack it together with the following autocmd:

function! TablineModeColorUpdate() abort
    let l:palette = g:lightline#colorscheme#{g:lightline.colorscheme}#palette
    let l:mode = tolower(lightline#mode())
    if l:mode ==# 'terminal'
        let l:mode = 'insert'
    elseif l:mode =~# 'v-'
        let l:mode = 'visual'
    elseif l:mode =~# 's-'
        let l:mode = 'select'
    elseif !has_key(l:palette, l:mode)
        let l:mode = 'normal'
    endif
    let l:palette.tabline = extend(l:palette.tabline, l:palette[l:mode])
    call lightline#colorscheme()
endfunction

augroup TablineModeColor
    autocmd!
    autocmd ModeChanged * call TablineModeColorUpdate()
augroup end

Still, a native solution would be nicer, at minimum something like lightline#palette_mode() to eliminate all the if-else. I can see some of it implemented in autoload#lightline.vim:146:

      \   '_mode_': {
      \     'n': 'normal', 'i': 'insert', 'R': 'replace', 'v': 'visual', 'V': 'visual', "\<C-v>": 'visual',
      \     'c': 'command', 's': 'select', 'S': 'select', "\<C-s>": 'select', 't': 'terminal'
      \   },
      \   'mode_fallback': { 'replace': 'insert', 'terminal': 'insert', 'select': 'visual' },

By noticing some patterns and defaults, I managed to shorten the function. Note it may not work on schemes which define different colors (e.g. define command, or don't define replace):

function! TablineModeColorUpdate() abort
    let l:palette = g:lightline#colorscheme#{g:lightline.colorscheme}#palette
    let l:map = { 'i': 'insert', 't': 'insert', 'r': 'replace', 'v': 'visual', 's': 'visual' }
    let l:mode = get(l:map, tolower(lightline#mode()[0]), 'normal')
    call lightline#colorscheme()
endfunction

It is a design decision to have tabline and inactive be configured as if it is a mode in the lightline colorscheme. So I don't support changing colors of tabline and inactive window statusline on mode changes, since this is very minor use case.

Understood, perfectly reasonable. I am perfectly happy with my solution and sharing it with those who might want to use it.

One thing to consider is maybe to provide some API to get effective configuration, as I have found it useful in other places. E.g. tabline_separator defaulting to separator defaulting to empty string - I needed effective tabline separator for some width calculations, so had to replicate the fallbacks and defaults from the plugin.