Lightline.vim: ALE Linting causes lightline to frantically switch the position of the active statusline

Created on 4 Mar 2019  路  5Comments  路  Source: itchyny/lightline.vim

Symptoms:

When ALE needs to update the quickfix/location window, the active lightline statusline keeps moving from the currently active window to the qf window, in some situations going back after some other event fires. This either results in lightline being active on the "wrong" window or unpleasantly "flickering" by switching rapidly between the two positions. Sometimes the statusline stays on the qf window despite the fact that my cursor is in the window I was writing in and everything seems to indicate the focus is not in the qf window at all.

Things I tried that didn't work:

  • Tried catching the moment where ALE switches to the qf buffer, but then I realized that never happens. So all my efforts to fix it on the ALE side didn't succeed since I could not find any lines that would switch the active buffer.
  • Made Lightline update on more autocmd events to switch it back. This made the statusline stay on the active window but created more flickering between the active window and qf window.
  • Tried every combination of ALE settings. Specifically putting ALE in 'normal' + lint on insert leave mode instead of 'always' mode. This fixed a large quantity of the undesirable statusline location switches but ultimately it would still happen, primarily when ALE had no errors and was keeping the qf window open.

Why this issue happens:

According to https://vimhelp.org/quickfix.txt.html when the qf window is filled, two autocommand events are triggered: FileType and BufWinEnter.

The doc says that the autocommands should not be triggered when adding to an existing quickfix list.

ALE uses setloclist and setqflist to fill the qf window. It either uses 'r' as the action parameter, which replaces items from the current quickfix list, or leaves the action parameter empty, which creates a new quickfix list. In both cases the two autocommands should be triggered.

To confirm this was the case, I set the following autocommands in my .vimrc:

augroup Testing_ALE_Lightline_Interaction
    autocmd!
    autocmd FileType * echom "FileType triggered."
    autocmd BufWinEnter * echom "BufWinEnter triggered."
augroup END

Then opened vim, did something to trigger ALE to open a qf window, then called setloclist(2, []) and setloclist(2, [], 'r') from vim's cmd. This immediately caused lightline to switch to the qf window and echo the test messages set earlier.

What fixed it:

Going to autoload/lightline.vim and plugin/lightline.vim and changing this line

autocmd WinEnter,BufWinEnter,FileType,SessionLoadPost * call lightline#update()

to this line

autocmd WinEnter,BufEnter,SessionLoadPost * call lightline#update()

As far as I can see, I've not had any loss of functionality from doing this, though there probably is in some cases. I don't know Vim/Lightline well enough to tell what is the correct move here. But this issue was driving me crazy and I thought there should at least be an issue detailing this as a workaround.

I wasn't sure whether to open an issue here or on ALE's repo, but after the research I did, I don't see how it could be fixed on ALE's side.

bug

Most helpful comment

I feel sorry for keeping this issue open for months. Thank you for your detail issue report. Your observations are almost correct and I appreciate it.

There is one problem. Removing the FileType causes the plugin fail to update the statusline of quickfix window, on call setloclist(2, [], 'r'). This is caused by the default ftplugin https://github.com/vim/vim/blob/7964873afe59d0896a921b7c585167674bb784d5/runtime/ftplugin/qf.vim#L16, so we could not remove the FileType here to keep the plugin statusline applied to the quickfix window.

But there is a good news. I submitted a pull request to add an option to disable the default statusline of quickfix (https://github.com/vim/vim/pull/4662). And the patch was included at https://github.com/vim/vim/commit/85850f3a5ef9f5a9d22e908ef263de8faa265a95, so this option is available since 8.1.1715.

I'm thinking of submitting some changes soon

  • use BufEnter instead of BufWinEnter
  • take care of FileType event before 8.1.1715
  • disable the default statusline of the quickfix

I'm a bit in indecision that overwriting the global option, because currently g:lightline is the only global variable that this plugin interacts with. But I believe this is ok, the plugin has been overwritten the statusline of quickfix so long, and no one would complain about a statusline plugin overwriting a global option related to the statusline.
The problem remains in the old versions of Vim but I hope users see this comment upgrade the Vim version.

All 5 comments

I feel sorry for keeping this issue open for months. Thank you for your detail issue report. Your observations are almost correct and I appreciate it.

There is one problem. Removing the FileType causes the plugin fail to update the statusline of quickfix window, on call setloclist(2, [], 'r'). This is caused by the default ftplugin https://github.com/vim/vim/blob/7964873afe59d0896a921b7c585167674bb784d5/runtime/ftplugin/qf.vim#L16, so we could not remove the FileType here to keep the plugin statusline applied to the quickfix window.

But there is a good news. I submitted a pull request to add an option to disable the default statusline of quickfix (https://github.com/vim/vim/pull/4662). And the patch was included at https://github.com/vim/vim/commit/85850f3a5ef9f5a9d22e908ef263de8faa265a95, so this option is available since 8.1.1715.

I'm thinking of submitting some changes soon

  • use BufEnter instead of BufWinEnter
  • take care of FileType event before 8.1.1715
  • disable the default statusline of the quickfix

I'm a bit in indecision that overwriting the global option, because currently g:lightline is the only global variable that this plugin interacts with. But I believe this is ok, the plugin has been overwritten the statusline of quickfix so long, and no one would complain about a statusline plugin overwriting a global option related to the statusline.
The problem remains in the old versions of Vim but I hope users see this comment upgrade the Vim version.

It was worth the wait to get a proper response like this!

Good to hear the PR went through too. I think the overwriting the global option is okay as long as it's documented. It has the advantage that it introduces the least complexity. One flag vs writing additional code for handling the FileType event properly. And if someone is using Lightline, it's very likely they want it like this anyway.

Most users will probably have this issue fixed whenever maintainers update their packages to >=8.1.1715.

Wondering if there's a workaround to this for those stuck with older versions? Debian stable still doesn't have 1715, and Neovim 0.4.4 seems to lack the patch as well.

I tried creating .vim/ftplugin/qf.vim with just:

let b:did_ftplugin = 1

But the problem persists, it looks like the runtime's qf.vim is still executed.

Ah, Neovim does actually have g:qf_disable_statusline support, but you're guarding the autocmd FileTypewith has('patch-8.1.1715') which won't match in Neovim.

I'll remove autocmd FileType and install Neovim or patch the runtime's qf.vim as a workaround for our Debian machines for now until Bullseye is released.

The issue is related to https://github.com/neovim/neovim/issues/9635. Wait until Neovim includes all the 8.0 patches or help them do it. The patch detection of lightline is correct and there is no reason to do workaround for Neovim.

Was this page helpful?
0 / 5 - 0 ratings