dense-analysis / ale

Check syntax in Vim/Neovim asynchronously and fix files, with Language Server Protocol (LSP) support
BSD 2-Clause "Simplified" License
13.59k stars 1.44k forks source link

Statusline info cache doesn't refresh correctly with integrating with third-party sources like coc.nvim #4737

Open sainnhe opened 9 months ago

sainnhe commented 9 months ago

Information

VIM version

VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Mar 05 2024 19:39:07) macOS version - arm64

Operating System:

$ uname -a
Darwin wenzhen.local 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000 arm64

What went wrong

I use ale to display coc diagnostic info, and I configured displayByAle setting in coc to let coc pass its diagnostic data to ale.

But sometimes, the error info in status line just disappeared when saving a file. That means:

  1. The error counts in status line can be displayed correctly before saving a file.
  2. After saving the file, the error counts goes to 0.
  3. But I can use :ALENext to jump to the error location, and use :ALEDetail to display detailed information. That means the detailed info actually exists, only the status line counts is incorrect.
  4. If I execute :echo g:ale_buffer_info, I'll have the following outputs:
{'1': {'active_linter_list': [], 'loclist': [{'lnum': 164, 'bufnr': 1, 'col': 22, 'linter_name': 'coctsserver', 'vcol': 0, 'from_other_source': 1, 'nr': -1, 'end_lnum': 164, 'type': 'I', 'code': 6133, 'end_col': 30
, 'text': '''prevProps'' is declared but its value is never read.', 'sign_id': 1000001}, {'lnum': 189, 'bufnr': 1, 'col': 12, 'linter_name': 'coceslint', 'vcol': 0, 'from_other_source': 1, 'nr': -1, 'end_lnum': 189
, 'type': 'E', 'code': 'react/jsx-no-undef', 'end_col': 17, 'text': '''Option'' is not defined.', 'sign_id': 1000002}, {'lnum': 190, 'bufnr': 1, 'col': 12, 'linter_name': 'coceslint', 'vcol': 0, 'from_other_source'
: 1, 'nr': -1, 'end_lnum': 190, 'type': 'E', 'code': 'react/jsx-no-undef', 'end_col': 17, 'text': '''Option'' is not defined.', 'sign_id': 1000003}, {'lnum': 191, 'bufnr': 1, 'col': 12, 'linter_name': 'coceslint',
'vcol': 0, 'from_other_source': 1, 'nr': -1, 'end_lnum': 191, 'type': 'E', 'code': 'react/jsx-no-undef', 'end_col': 17, 'text': '''Option'' is not defined.', 'sign_id': 1000004}, {'lnum': 192, 'bufnr': 1, 'col': 12
, 'linter_name': 'coceslint', 'vcol': 0, 'from_other_source': 1, 'nr': -1, 'end_lnum': 192, 'type': 'E', 'code': 'react/jsx-no-undef', 'end_col': 17, 'text': '''Option'' is not defined.', 'sign_id': 1000005}], 'fir
st_problems': {}, 'count': {'0': 0, '1': 0, 'style_warning': 0, 'info': 0, 'warning': 0, 'total': 0, 'style_error': 0, 'error': 0}, 'active_other_sources_list': []}}

So you can see, the outputs is very strange. There are actually some errors, but the count section is 0.

After some investigation, I found that comment out the if condition in s:UpdateCacheIfNecessary, forcing refresh the cache, the status line info count can be correctly refreshed on save.

function! s:UpdateCacheIfNecessary(buffer) abort
    " Cache is cold, so manually ask for an update.
    " if !has_key(g:ale_buffer_info[a:buffer], 'count')
        call ale#statusline#Update(
        \   a:buffer,
        \   g:ale_buffer_info[a:buffer].loclist
        \)
    " endif
endfunction

So IMO there might be some logic error in cache refreshing.

Related issues:

Reproducing the bug

The reproducing steps are detailed described in the related issues above, so I'm just going to skip this.

:ALEInfo

Expand ```text Current Filetype: javascriptreact Available Linters: ['biome', 'cspell', 'deno', 'eslint', 'fecs', 'flow', 'flow_ls', 'jscs', 'jshint', 'standard', 'tsserver', 'xo'] Enabled Linters: [] Ignored Linters: [] Suggested Fixers: '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. Global Variables: " Press Space to read :help for a setting let g:ale_cache_executable_check_failures = v:null let g:ale_change_sign_column_color = 0 let g:ale_command_wrapper = v:null let g:ale_completion_delay = v:null let g:ale_completion_enabled = 0 let g:ale_completion_max_suggestions = v:null let g:ale_disable_lsp = 1 let g:ale_echo_cursor = 0 let g:ale_echo_msg_error_str = 'ERR' let g:ale_echo_msg_format = '%code: %%s' let g:ale_echo_msg_info_str = 'INFO' let g:ale_echo_msg_warning_str = 'WARN' 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_info_default_mode = 'preview' 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 = {'ps1': 'powershell', 'rmarkdown': 'r', 'javascriptreact': ['javascript', 'jsx'], 'rmd': 'r', 'html': ['html', 'javascript', 'css'], 'vue': ['vue', 'javascript'], 'Dockerfile': 'dockerfile', 'vader': ['vim', 'vader'], 'xslt': ['xslt', 'xml'], 'plaintex': 'tex', 'typescriptreact': ['typescript', 'tsx'], 'zsh': 'sh', 'csh': 'sh', 'systemverilog': 'verilog', 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], 'xsd': ['xsd', 'xml'], 'vimwiki': 'markdown'} let g:ale_linters = {'sh': ['shellcheck'], 'java': ['pmd']} let g:ale_linters_explicit = 1 let g:ale_linters_ignore = {} let g:ale_list_vertical = 0 let g:ale_list_window_size = 10 let g:ale_loclist_msg_format = '%code: %%s' let g:ale_max_buffer_history_size = v:null 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_root = {} 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_type_map = {} let g:ale_use_neovim_diagnostics_api = 0 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: ```

Edit:

I fount that not only the status line count cannot be refreshed correctly, the column information also cannot be refreshed correctly. The column indicator also disappeared when saving file.


Edit:

Execute :call ale#sign#SetSigns(1, g:ale_buffer_info[1].loclist) will refresh the sign column info correctly.

A temporary fix of this two bug is adding a autocmd which will refresh both sign column and status line info:

autocmd BufWritePost * call ale#engine#SetResults(bufnr(''), g:ale_buffer_info[bufnr('')].loclist)
justinmiller61 commented 8 months ago

I believe I'm hitting this, specifically with respect to the referenced coc issues. I've just lived with it, but it is annoying.

Thanks for submitting this.