'Vim cannot change the statusline appearance when a new window is open for some filetype

I wrote a few function to ask vim to set different statusline style for current and non-current window using setl for each type of window.

The basic idea is that vim will draw an "activated" statusline upon entering a new window (WinEnter), while turn the statusline of the previous window (WinLeave) into "deactivated" one.

Although switching between windows work as expected, a newly opened window will sometimes get the "deactivated" statusline defined.

I upload a short video on youtube showing the behaviour I mention, please take a look.

Edit: Here is the code:

autocmd VimEnter * call SttLine_Activate()
autocmd WinNew   * call SttLine_NewAuto()
autocmd WinEnter * call SttLine_Activate()
autocmd WinLeave * call SttLine_Deactivate()



" + Status line
"--------------
set laststatus=2
set noshowmode

" * Get the current mode
let g:currentmode={
            \ 'n'  : 'NORMAL',
            \ 'v'  : 'VISUAL',
            \ 'V'  : 'V·LINE',
            \ '' : 'V·BLOCK',
            \ 's'  : 'SELECT',
            \ 'S'  : 'S·LINE',
            \ '' : 'S·BLOCK',
            \ 'i'  : 'INSERT',
            \ 'R'  : 'REPLACE',
            \ 'r'  : 'REPLACE',
            \ 'Rv' : 'V·REPLACE',
            \ 'c'  : 'COMMAND',
            \ 't'  : 'TERM',
            \}


" * Status line for current window
function! SttLine_Activate()
    if (winnr()==winnr())
        setl statusline=

        setl statusline+=\%#StatusBlockColour#
        setl statusline+=\ %{g:currentmode[mode()]}
        setl statusline+=\ %0*

        setl statusline+=\%#StatusLineColour#
        setl statusline+=\ %p%%\(%L)\ ≡\ L%l\:%c\ \|

        setl statusline+=\%#StatusFileColour#
        setl statusline+=\ %f\ %m
        setl statusline+=%=

        setl statusline+=\%#StatusBlockColour#
        setl statusline+=\ ⌨\ %{&fileformat}:\ %y
        setl statusline+=\ %{&fileencoding?&fileencoding:&encoding}
        setl statusline+=\ %0*
    endif
endfunction

" * Status line for non-current window
function! SttLine_Deactivate()
    setl statusline=

    setl statusline+=\%#StatusBlockGrey#
    setl statusline+=\ %{g:currentmode[mode()]}
    setl statusline+=\ %0*

    setl statusline+=\%#StatusLineGrey#
    setl statusline+=\ %p%%\(%L)\ ≡\ L%l\:%c\ \|

    setl statusline+=\%#StatusFileGrey#
    setl statusline+=\ %f\ %m
    setl statusline+=%=

    setl statusline+=\%#StatusBlockGrey#
    setl statusline+=\ ⌨\ %{&fileformat}:\ %y
    setl statusline+=\ %{&fileencoding?&fileencoding:&encoding}
    setl statusline+=\ %0*
endfunction

" * Auto detect current window (switching window)
function! SttLine_NewAuto()
    let winID = winnr()
    let nWin  = bufnr("$")+1

    let iwin     = 0
    let hasnetrw = 0
    while (iwin < nWin)
        wincmd w
        if (getbufvar(iwin, "&filetype") == "netrw")
            let hasnetrw += 1
        endif

        let iwin += 1
    endwhile

    if (hasnetrw>0)
        vert res
        vert res -25
    endif
endfunction


Solution 1:[1]

Here's how you can define different status line for active and inactive windows. Change StatuslineActive and StatuslineNotActive functions with you desired status line.

" Return the active status line configuration
function! StatuslineActive() abort
  let l:statusline ='['. mode() . '] %f'  " [ mode ] + filename
  let l:statusline.=' Active'
  return l:statusline
endfunction

" Return the inactive status line configuration
function! StatuslineNotActive() abort
  let l:statusline ='[' . mode() .'] %f' " [ mode ] + filename
  let l:statusline.=' Not Active'
  return l:statusline
endfunction
set statusline=%!StatuslineActive()

" Set the corresponding status line when entering and leaving windows
augroup set_active_statusline
  autocmd!
  autocmd WinEnter * :setlocal statusline=%!StatuslineActive()
  autocmd WinLeave * :setlocal statusline=%!StatuslineNotActive()
augroup END

Here it is in action: Status line change from active to inactive

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1