Sidebar remains visible once all problems fixed when fixing multiple eslint issues one-by-one
Information
VIM version
NVIM v0.7.2 Build type: Release LuaJIT 2.1.0-beta3
Operating System: macOS Monterrey 12.4
What went wrong
While editing javascript, if I have multiple errors on screen at once, it makes sense to do this:
- fix one issue
- save
- fix the second issue
- save
However, the "sidebar" (I'm not sure the exact term.... the grey bar on the left that displays warning/error icons) will sometimes not dismiss itself after step 4.
The only way to reliably remedy this is to:
- navigate to the very top of the file
- visual select the entire document
- delete
- paste
- save
Reproducing the bug
See this video. I'll list out the steps below it.
https://user-images.githubusercontent.com/180387/176670243-4cc50397-af5d-4264-a218-b25e2c31561d.mp4
Start with this text:
export const myString1 = "foo"
cahcahuchuac
export const streamToString = (stream) =>
new Promise((resolve, reject) => {
const chunks = []
stream.on("data", (chunk) => chunks.push(chunk))
stream.on("error", reject)
stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
})
const blah = 0
export const myString2 = "bar"
- Save... you'll get 2 errors.
- The first one is eslint's
no-undef - The second one is eslint's
no-unused-vars. - Now delete the entire line of the first error. (The one that says
cahcahuchuac.) - Save
- You should now have just one error.
- Now add
console.log(blah)below the only remaining error. - Save
- Note that the sidebar remains, even though there are no errors.
:ALEInfo
Current Filetype: javascript Available Linters: ['cspell', 'deno', 'eslint', 'fecs', 'flow', 'flow-language-server', 'jscs', 'jshint', 'standard', 'tsserver', 'xo'] Enabled Linters: ['eslint'] Ignored Linters: [] Suggested Fixers: 'dprint' - Pluggable and configurable code formatting platform 'eslint' - Apply eslint --fix to a file. 'fecs' - Apply fecs format to a file. 'importjs' - automatic imports for javascript 'prettier' - Apply prettier to a file. 'prettier_eslint', 'prettier-eslint' - Apply prettier-eslint to a file. 'prettier_standard', 'prettier-standard' - Apply prettier-standard to a file. 'remove_trailing_lines' - Remove all blank lines at the end of a file. 'standard' - Fix JavaScript files using standard --fix 'trim_whitespace' - Remove all trailing whitespace characters at the end of every line. 'xo' - Fix JavaScript/TypeScript files using xo --fix. Linter Variables:
let g:ale_javascript_eslint_executable = 'eslint' let g:ale_javascript_eslint_options = '' let g:ale_javascript_eslint_suppress_eslintignore = 0 let g:ale_javascript_eslint_suppress_missing_config = 0 let g:ale_javascript_eslint_use_global = 0 let g:ale_javascript_prettier_executable = 'prettier' let g:ale_javascript_prettier_options = '' let g:ale_javascript_prettier_standard_executable = 'prettier-standard' let g:ale_javascript_prettier_standard_options = '' let g:ale_javascript_prettier_standard_use_global = 0 let g:ale_javascript_prettier_use_global = 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_disable_lsp = 0 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 = 1 let g:ale_fixers = {'xhtml': ['prettier', 'prettier_standard'], 'svelte': ['prettier', 'prettier_standard'], 'markdown': ['prettier', 'prettier_standard'], 'scss': ['prettier'], 'json': ['prettier', 'prettier_standard'], 'graphql': ['prettier', 'prettier_standard'], 'html': ['prettier', 'prettier_standard'], 'javascript': ['prettier', 'prettier_standard'], 'css': ['stylelint'], 'python': ['black']} 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 = 0 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 = 'never' let g:ale_linter_aliases = {'svelte': ['javascript', 'html', 'scss', 'css']} let g:ale_linters = {'svelte': ['eslint'], 'scss': ['stylelint'], 'json': ['eslint'], 'javascript': ['eslint'], 'css': ['stylelint'], 'python': ['flake8']} 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 = 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_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_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:
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family/src'' && ''/Users/phil/Code/nimble-family/node_modules/.bin/prettier'' --stdin-filepath ''/Users/phil/Code/nimble-family/src/test-file.js'' --stdin < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/313/test-file.js'''] (finished - exit code 127) ['/bin/zsh', '-c', '''prettier-standard'' --stdin --stdin-filepath=''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/314/test-file.js'''] (finished - exit code 1) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family'' && ''/Users/phil/Code/nimble-family/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/315/test-file.js''']
<<<OUTPUT STARTS>>> [{"filePath":"/Users/phil/Code/nimble-family/src/test-file.js","messages":[{"ruleId":"no-undef","severity":2,"message":"'achacuhacahuchu' is not defined.","line":2,"column":1,"nodeType":"Identifier","messageId":"undef","endLine":2,"endColumn":16},{"ruleId":"no-unused-vars","severity":2,"message":"'blah' is assigned a value but never used.","line":12,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":12,"endColumn":11}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"export const myString1 = "foo"\nachacuhacahuchu\n\nexport const streamToString = (stream) =>\n new Promise((resolve, reject) => {\n const chunks = []\n stream.on("data", (chunk) => chunks.push(chunk))\n stream.on("error", reject)\n stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))\n })\n\nconst blah = 0\n\nexport const myString2 = "bar"\n","usedDeprecatedRules":[]}] <<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family/src'' && ''/Users/phil/Code/nimble-family/node_modules/.bin/prettier'' --stdin-filepath ''/Users/phil/Code/nimble-family/src/test-file.js'' --stdin < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/316/test-file.js'''] (finished - exit code 127) ['/bin/zsh', '-c', '''prettier-standard'' --stdin --stdin-filepath=''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/317/test-file.js'''] (finished - exit code 1) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family'' && ''/Users/phil/Code/nimble-family/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/318/test-file.js''']
<<<OUTPUT STARTS>>> [{"filePath":"/Users/phil/Code/nimble-family/src/test-file.js","messages":[{"ruleId":"no-unused-vars","severity":2,"message":"'blah' is assigned a value but never used.","line":11,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":11,"endColumn":11}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"export const myString1 = "foo"\n\nexport const streamToString = (stream) =>\n new Promise((resolve, reject) => {\n const chunks = []\n stream.on("data", (chunk) => chunks.push(chunk))\n stream.on("error", reject)\n stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))\n })\n\nconst blah = 0\n\nexport const myString2 = "bar"\n","usedDeprecatedRules":[]}] <<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family'' && ''/Users/phil/Code/nimble-family/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/319/test-file.js''']
<<<OUTPUT STARTS>>> [{"filePath":"/Users/phil/Code/nimble-family/src/test-file.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]}] <<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family/src'' && ''/Users/phil/Code/nimble-family/node_modules/.bin/prettier'' --stdin-filepath ''/Users/phil/Code/nimble-family/src/test-file.js'' --stdin < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/320/test-file.js'''] (finished - exit code 127) ['/bin/zsh', '-c', '''prettier-standard'' --stdin --stdin-filepath=''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/321/test-file.js'''] (finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family'' && ''/Users/phil/Code/nimble-family/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/322/test-file.js''']
<<<OUTPUT STARTS>>> [{"filePath":"/Users/phil/Code/nimble-family/src/test-file.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]}] <<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family/src'' && ''/Users/phil/Code/nimble-family/node_modules/.bin/prettier'' --stdin-filepath ''/Users/phil/Code/nimble-family/src/test-file.js'' --stdin < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/323/test-file.js'''] (finished - exit code 127) ['/bin/zsh', '-c', '''prettier-standard'' --stdin --stdin-filepath=''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/324/test-file.js'''] (finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family'' && ''/Users/phil/Code/nimble-family/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/325/test-file.js''']
<<<OUTPUT STARTS>>> [{"filePath":"/Users/phil/Code/nimble-family/src/test-file.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]}] <<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family/src'' && ''/Users/phil/Code/nimble-family/node_modules/.bin/prettier'' --stdin-filepath ''/Users/phil/Code/nimble-family/src/test-file.js'' --stdin < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/326/test-file.js'''] (finished - exit code 127) ['/bin/zsh', '-c', '''prettier-standard'' --stdin --stdin-filepath=''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/327/test-file.js'''] (finished - exit code 1) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family'' && ''/Users/phil/Code/nimble-family/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/328/test-file.js''']
<<<OUTPUT STARTS>>> [{"filePath":"/Users/phil/Code/nimble-family/src/test-file.js","messages":[{"ruleId":"no-undef","severity":2,"message":"'cahcahuchuac' is not defined.","line":2,"column":1,"nodeType":"Identifier","messageId":"undef","endLine":2,"endColumn":13},{"ruleId":"no-unused-vars","severity":2,"message":"'blah' is assigned a value but never used.","line":12,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":12,"endColumn":11}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"export const myString1 = "foo"\ncahcahuchuac\n\nexport const streamToString = (stream) =>\n new Promise((resolve, reject) => {\n const chunks = []\n stream.on("data", (chunk) => chunks.push(chunk))\n stream.on("error", reject)\n stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))\n })\n\nconst blah = 0\n\nexport const myString2 = "bar"\n","usedDeprecatedRules":[]}] <<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family'' && ''/Users/phil/Code/nimble-family/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/329/test-file.js''']
<<<OUTPUT STARTS>>> [{"filePath":"/Users/phil/Code/nimble-family/src/test-file.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]}] <<<OUTPUT ENDS>>>
(finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family/src'' && ''/Users/phil/Code/nimble-family/node_modules/.bin/prettier'' --stdin-filepath ''/Users/phil/Code/nimble-family/src/test-file.js'' --stdin < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/330/test-file.js'''] (finished - exit code 127) ['/bin/zsh', '-c', '''prettier-standard'' --stdin --stdin-filepath=''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/331/test-file.js'''] (finished - exit code 0) ['/bin/zsh', '-c', 'cd ''/Users/phil/Code/nimble-family'' && ''/Users/phil/Code/nimble-family/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/Users/phil/Code/nimble-family/src/test-file.js'' < ''/var/folders/70/m9wf9dcd5j5b_0r2z607c70c0000gn/T/nvimL1FLn5/332/test-file.js''']
<<<OUTPUT STARTS>>> [{"filePath":"/Users/phil/Code/nimble-family/src/test-file.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]}] <<<OUTPUT ENDS>>>
I tested this with neovim 0.7 and vim 8.2 and cannot replicate the issue. In my case the signs column dissappears as expected when all linter issues are solved.
Can you try testing this with a minimal vim configuration to ensure no other plugins are causing issues. Also update ALE to latest version if possible.
I tested it with a .vimrc with only these lines:
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'dense-analysis/ale'
call vundle#end()
filetype plugin indent on
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_fixers = {}
let g:ale_linters.javascript = ['eslint']
It still happens. One interesting discovery though....
When following the steps above, at step 4, if you comment out the line, the issue doesn't occur. It's only when deleting the line (with dd) that contains the eslint error, that the sidebar remains.
(Edit: also, my ALE is updated to the latest version, btw.)
Were you able to reproduce? This is still happening every 10 minutes while I code, and it's driving me nuts.
Yes, problem happens in neovim but not in vim so I belive this is a bug in neovim itself. So far I am unable to pinpoint the exact issue making it difficult to provide a fix.
To confirm this is a neovim issue I made this test:
- Edit a new text file with empty configuration:
nvim -u NONE /tmp/test.txt
- Write a few line like:
this is line 1
this is line 2
this is line 3
- Define a new sign and add it to the first and last line:
:sign define piet text=>>
:sign place 10001 line=1 name=piet
:sign place 10002 line=5 name=piet
:sign place # We can see both signs are present
Sign column should be visible and the signs should appear in line 1 and 5:
>> this is line 1
this is line 2
>> this is line 3
- Delete the first line with dd comand and then unplace the sign in line 5:
ggdd
:sign place # We see that the first sign dissapears with the deleted line.
:sign unplace 10003
:sign place # We see that the second sign dissapears with the unplace command
- There are no signs but the sign column stays demonstrating there is some bug in neovim. According to documentation once there are no more signs the sign column should dissappear.
:sign place # You can see no signs are present
My take on this is that when a sign is removed by some edit action (e.g delete line with the sign) a bug is triggered that causes neovim to keep the sign column even after all signs are removed.
Thanks for the response @hsanson! Do you want me to create in issue on the neovim github repo? I searched and couldn't find this issue being reported.
Also the :unplace command seems to be :sign uplace instead. And the id of the sign changed after dding the line. But I was able to replicate in this way.
@Arro Would be great if you report the issue to neovim. Also fixed the unplace command in my comment, thanks.
This has been addressed upstream, should be in the next nightly: https://github.com/neovim/neovim/pull/20400
Closing since is not ALE related.