ale icon indicating copy to clipboard operation
ale copied to clipboard

Sidebar remains visible once all problems fixed when fixing multiple eslint issues one-by-one

Open Arro opened this issue 3 years ago • 7 comments

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:

  1. fix one issue
  2. save
  3. fix the second issue
  4. 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:

  1. navigate to the very top of the file
  2. visual select the entire document
  3. delete
  4. paste
  5. 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"
  1. Save... you'll get 2 errors.
  2. The first one is eslint's no-undef
  3. The second one is eslint's no-unused-vars.
  4. Now delete the entire line of the first error. (The one that says cahcahuchuac.)
  5. Save
  6. You should now have just one error.
  7. Now add console.log(blah) below the only remaining error.
  8. Save
  9. 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>>>

Arro avatar Jun 30 '22 11:06 Arro

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.

hsanson avatar Jul 03 '22 11:07 hsanson

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.)

Arro avatar Jul 14 '22 17:07 Arro

Were you able to reproduce? This is still happening every 10 minutes while I code, and it's driving me nuts.

Arro avatar Jul 24 '22 14:07 Arro

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.

hsanson avatar Jul 25 '22 13:07 hsanson

To confirm this is a neovim issue I made this test:

  1. Edit a new text file with empty configuration:
 nvim -u NONE /tmp/test.txt
  1. Write a few line like:
this is line 1

this is line 2

this is line 3
  1. 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
  1. 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
  1. 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.

hsanson avatar Jul 25 '22 14:07 hsanson

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 avatar Jul 26 '22 14:07 Arro

@Arro Would be great if you report the issue to neovim. Also fixed the unplace command in my comment, thanks.

hsanson avatar Jul 27 '22 01:07 hsanson

This has been addressed upstream, should be in the next nightly: https://github.com/neovim/neovim/pull/20400

erquhart avatar Sep 29 '22 10:09 erquhart

Closing since is not ALE related.

hsanson avatar Sep 30 '22 00:09 hsanson