ale
ale copied to clipboard
Suspending neovim causes ALE highlights to be cleared
Information
VIM version
Neovim: NVIM v0.4.3 Build type: Release
Vim: VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Jan 11 2020 12:16:09) Included patches: 1-111
Operating System: Linux
What went wrong
On Neovim (but not Vim), suspending with C-Z causes all ALE highlights to be gone on resume. You have to trigger ALE to run again (reload the file, call :ALELint, etc). Everything is gone: the gutter is no longer open, and nothing is highlighted.
With Vim, all the errors stick around on resume.
With Neovim, switching between buffers doesn't cause this issue, so it's not just when the buffer is hidden. So far the only thing I've seen trigger it is suspending the process.
I'm not sure if it's a Neovim or ALE issue. This doesn't occur with the vim-signify plugin (its gutter remains open on suspend and resume), so that slightly points in ALE's direction, but is obviously not conclusive.
Reproducing the bug
I pared down my .vimrc just enough to set up vim-plug and included only ALE as the plugin, to avoid other plugins/settings interfering. I used the same config for both Neovim and Vim.
- Create a file with an obvious syntax error that ALE will highlight
- Have ALE run on the file, showing a highlighted problem
- Suspend Neovim with C-Z
- Resume Neovim
:ALEInfo
Current Filetype: c
Available Linters: ['ccls', 'clang', 'clangd', 'clangtidy', 'cppcheck', 'cquery', 'flawfinder', 'gcc']
Enabled Linters: ['ccls', 'clang', 'clangd', 'clangtidy', 'cppcheck', 'cquery', 'flawfinder', 'gcc']
Suggested Fixers:
'clang-format' - Fix C/C++ and cuda files with clang-format.
'clangtidy' - Fix C/C++ and ObjectiveC files with clang-tidy.
'remove_trailing_lines' - Remove all blank lines at the end of a file.
'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
'uncrustify' - Fix C, C++, C#, ObjectiveC, ObjectiveC++, D, Java, Pawn, and VALA files with uncrustify.
Linter Variables:
let g:ale_c_build_dir = ''
let g:ale_c_build_dir_names = ['build', 'bin']
let g:ale_c_ccls_executable = 'ccls'
let g:ale_c_ccls_init_options = {}
let g:ale_c_clang_executable = 'clang'
let g:ale_c_clang_options = '-std=c11 -Wall'
let g:ale_c_clangd_executable = 'clangd'
let g:ale_c_clangd_options = ''
let g:ale_c_clangtidy_checks = []
let g:ale_c_clangtidy_executable = 'clang-tidy'
let g:ale_c_clangtidy_extra_options = ''
let g:ale_c_clangtidy_options = ''
let g:ale_c_cppcheck_executable = 'cppcheck'
let g:ale_c_cppcheck_options = '--enable=style'
let g:ale_c_cquery_cache_directory = '/home/chris/.cache/cquery'
let g:ale_c_cquery_executable = 'cquery'
let g:ale_c_flawfinder_error_severity = 6
let g:ale_c_flawfinder_executable = 'flawfinder'
let g:ale_c_flawfinder_minlevel = 1
let g:ale_c_flawfinder_options = ''
let g:ale_c_gcc_executable = 'gcc'
let g:ale_c_gcc_options = '-std=c11 -Wall'
let g:ale_c_parse_compile_commands = 0
let g:ale_c_parse_makefile = 0
Global Variables:
let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_info = '--'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
let g:ale_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
Command History:
(executable check - failure) cquery
(executable check - failure) flawfinder
(finished - exit code 1) ['/bin/zsh', '-c', '''gcc'' -S -x c -o /dev/null -iquote ''/home/chris'' -std=c11 -Wall - < ''/tmp/nvim4ptF35/16/t.c''']
<<<OUTPUT STARTS>>>
<stdin>: In function ‘main’:
<stdin>:7:5: error: ‘invalid’ undeclared (first use in this function)
<stdin>:7:5: note: each undeclared identifier is reported only once for each function it appears in
<stdin>:7:12: error: expected ‘;’ before ‘return’
<<<OUTPUT ENDS>>>
(finished - exit code 1) ['/bin/zsh', '-c', '''clang'' -S -x c -fsyntax-only -iquote ''/home/chris'' -std=c11 -Wall - < ''/tmp/nvim4ptF35/17/t.c''']
<<<OUTPUT STARTS>>>
<stdin>:7:5: error: use of undeclared identifier 'invalid'
invalid
^
1 error generated.
<<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/home/chris'' && ''cppcheck'' -q --language=c --enable=style -I''/home/chris'' ''/tmp/nvim4ptF35/18/t.c''']
<<<NO OUTPUT RETURNED>>>
(executable check - failure) cquery
(executable check - failure) flawfinder
(finished - exit code 1) ['/bin/zsh', '-c', '''gcc'' -S -x c -o /dev/null -iquote ''/home/chris'' -std=c11 -Wall - < ''/tmp/nvim4ptF35/19/t.c''']
<<<OUTPUT STARTS>>>
<stdin>: In function ‘main’:
<stdin>:7:5: error: ‘invalid’ undeclared (first use in this function)
<stdin>:7:5: note: each undeclared identifier is reported only once for each function it appears in
<stdin>:7:12: error: expected ‘;’ before ‘return’
<<<OUTPUT ENDS>>>
(finished - exit code 1) ['/bin/zsh', '-c', '''clang'' -S -x c -fsyntax-only -iquote ''/home/chris'' -std=c11 -Wall - < ''/tmp/nvim4ptF35/20/t.c''']
<<<OUTPUT STARTS>>>
<stdin>:7:5: error: use of undeclared identifier 'invalid'
invalid
^
1 error generated.
<<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', '''clang-tidy'' ''/home/chris/t.c'' -p ''/home/chris''']
<<<NO OUTPUT RETURNED>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/home/chris'' && ''cppcheck'' -q --language=c --project=''compile_commands.json'' --enable=style ''/tmp/nvim4ptF
35/21/t.c''']
<<<NO OUTPUT RETURNED>>>
(executable check - failure) cquery
(executable check - failure) flawfinder
(finished - exit code 1) ['/bin/zsh', '-c', '''gcc'' -S -x c -o /dev/null -iquote ''/home/chris'' -std=c11 -Wall - < ''/tmp/nvim4ptF35/22/t.c''']
<<<OUTPUT STARTS>>>
<stdin>: In function ‘main’:
<stdin>:7:5: error: ‘invalid’ undeclared (first use in this function)
<stdin>:7:5: note: each undeclared identifier is reported only once for each function it appears in
<stdin>:7:12: error: expected ‘;’ before ‘return’
<<<OUTPUT ENDS>>>
(finished - exit code 1) ['/bin/zsh', '-c', '''clang'' -S -x c -fsyntax-only -iquote ''/home/chris'' -std=c11 -Wall - < ''/tmp/nvim4ptF35/23/t.c''']
<<<OUTPUT STARTS>>>
<stdin>:7:5: error: use of undeclared identifier 'invalid'
invalid
^
1 error generated.
<<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', '''clang-tidy'' ''/home/chris/t.c'' -p ''/home/chris''']
<<<NO OUTPUT RETURNED>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/home/chris'' && ''cppcheck'' -q --language=c --project=''compile_commands.json'' --enable=style ''/tmp/nvim4ptF
35/24/t.c''']
<<<NO OUTPUT RETURNED>>>
(executable check - failure) cquery
(executable check - failure) flawfinder
(finished - exit code 1) ['/bin/zsh', '-c', '''gcc'' -S -x c -o /dev/null -iquote ''/home/chris'' -std=c11 -Wall - < ''/tmp/nvim4ptF35/25/t.c''']
<<<OUTPUT STARTS>>>
<stdin>: In function ‘main’:
<stdin>:7:5: error: ‘invalid’ undeclared (first use in this function)
<stdin>:7:5: note: each undeclared identifier is reported only once for each function it appears in
<stdin>:7:12: error: expected ‘;’ before ‘return’
<<<OUTPUT ENDS>>>
I know it's been a while since this was posted, but I'll note that I experience the same issue on vanilla vim (8.2.2375 on macOS). My suspicion is that it's related to https://github.com/dense-analysis/ale/issues/1898, as it doesn't appear to consistently impact all of my dev machines and some are (I believe) using an older version of Ale. I just updated to the latest version of Ale (92f08b5af2f6316312c95c5160c6e02b76370e04) and still experience it on my main system.
This is caused by linters not being re-run on VimResume. Not only are the highlights cleared but all linter info is deleted. I can't see any logic there that uses VimResume at all. My one line workaround relies on nvim_list_bufs() from neovim (vim users may need some kind of spiritual ritual instead to get a list of buffer numbers):
autocmd VimResume * call map(nvim_list_bufs(), 'ale#Queue(0, "lint_file", v:val)')
Caveat: it could be a bad idea to rerun all linters on all buffers if you are in the habit of keeping lots of buffers open.