Ale: rust-analyzer appears to completely ignore the LSP configuration

Created on 12 Sep 2020  路  4Comments  路  Source: dense-analysis/ale

Information

VIM version

NVIM v0.4.4
Build type: Release

Operating System: Arch Linux:

Linux roach 5.8.8-arch1-1 #1 SMP PREEMPT Wed, 09 Sep 2020 18:59:45 +0000 x86_64 GNU/Linux

What went wrong

ALE allows you to configure the LSP settings for rust-analyzer using let g:ale_rust_analyzer_config, which is set to a dictionary. Unfortunately, it appears that no matter what I try, rust-analyzer is ignoring these settings. For example, there is a setting called diagnostics.enable that can be used to enable/disable diagnostics (that way you don't get errors while still typing). I have tried the following formats, but none appear to have any impact:

let g:ale_rust_analyzer_config = {
  \ 'rust-analyzer.diagnostics.enable': v:false
  \ }

let g:ale_rust_analyzer_config = {
  \ 'rust-analyzer': { 'diagnostics.enable': v:false }
  \ }

let g:ale_rust_analyzer_config = {
  \ 'rust-analyzer': { 'diagnostics': { 'enable': v:false } }
  \ }

let g:ale_rust_analyzer_config = {
  \ 'diagnostics.enable': v:false
  \ }

let g:ale_rust_analyzer_config = {
  \ 'diagnostics': { 'enable': v:false }
  \ }

I also tried using 0 instead of v:false, but couldn't get this to work either. The PR https://github.com/dense-analysis/ale/pull/3130 makes it sound like ALE perhaps doesn't implement the necessary LSP commands properly.

Reproducing the bug

Create /tmp/test.vim with the following content:

let g:plug_url_format = '[email protected]:%s.git'

call plug#begin('~/.config/nvim/plugged')

Plug 'dense-analysis/ale'

call plug#end()

let g:ale_completion_enabled = 1
let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_insert_leave = 0
let g:ale_linters = { 'rust': ['analyzer'] }

let g:ale_rust_analyzer_config = {
  \ 'rust-analyzer.diagnostics.enable': v:false
  \ }

Next, run cargo init --bin ale followed by cd ale. Then run nvim/vim as follows:

nvim -u /tmp/test.vim src/main.rs

Change this file to the following:

fn main() {
    let mut numbers = Vec::with_capacity(10);

    numbers.push(10);
}

Then move your cursor to the empty line, enter insert mode, and type foo. The code should now be as follows:

fn main() {
    let mut numbers = Vec::with_capacity(10);

    foo|

    numbers.push(10);
}

Here | indicates the cursor position. With the above configuration, rust-analyzer will produce a error Syntax Error: expected SEMICOLON. It will produce this error regardless of how we set g:ale_rust_analyzer_config. For example, even with this the configuration is ignored:

let g:plug_url_format = '[email protected]:%s.git'

call plug#begin('~/.config/nvim/plugged')

Plug 'dense-analysis/ale'

call plug#end()

let g:ale_completion_enabled = 1
let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_insert_leave = 0
let g:ale_linters = { 'rust': ['analyzer'] }

let g:ale_rust_analyzer_config = {
  \ 'rust-analyzer.diagnostics.enable': v:false,
  \ 'rust-analyzer': {
  \   'diagnostics.enable': v:false,
  \   'diagnostics': {
  \     'enable': v:false
  \   }
  \ },
  \ 'diagnostics.enable': v:false,
  \ 'diagnostics': { 'enable': v:false }
  \ }

Worth mentioning that this worked fine when I was playing around with CoC and its support for rust-analyzer via https://github.com/fannheyward/coc-rust-analyzer; so I don't believe this to be an issue with rust-analyzer.

:ALEInfo



 Current Filetype: rust
Available Linters: ['analyzer', 'cargo', 'rls', 'rustc']
  Enabled Linters: ['analyzer']
  Ignored Linters: []
 Suggested Fixers:
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'rustfmt' - Fix Rust files with Rustfmt.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 Linter Variables:

let g:ale_rust_analyzer_config = {'diagnostics': {'enable': v:false}, 'rust-analyzer.diagnostics.enable': v:false, 'rust-analyzer': {'diagnostics': {'enable': v:false}, 'diagnostics.enable': v:false}, 'diagnostics.enable': v:false}
let g:ale_rust_analyzer_executable = 'rust-analyzer'
 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 = 100
let g:ale_completion_enabled = 1
let g:ale_completion_max_suggestions = 50
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 = 0
let g:ale_fixers = {}
let b:ale_fixers = ['rustfmt']
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 = 0
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'never'
let g:ale_linter_aliases = {}
let g:ale_linters = {'rust': ['analyzer']}
let g:ale_linters_explicit = 0
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_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 - success) rust-analyzer
(started) ['/bin/sh', '-c', '''rust-analyzer''']
bug

Most helpful comment

I made this change:

diff --git a/ale_linters/rust/analyzer.vim b/ale_linters/rust/analyzer.vim
index 3666ec03..77d946f7 100644
--- a/ale_linters/rust/analyzer.vim
+++ b/ale_linters/rust/analyzer.vim
@@ -17,7 +17,7 @@ endfunction
 call ale#linter#Define('rust', {
 \   'name': 'analyzer',
 \   'lsp': 'stdio',
-\   'lsp_config': {b -> ale#Var(b, 'rust_analyzer_config')},
+\   'initialization_options': {b -> ale#Var(b, 'rust_analyzer_config')},
 \   'executable': {b -> ale#Var(b, 'rust_analyzer_executable')},
 \   'command': function('ale_linters#rust#analyzer#GetCommand'),
 \   'project_root': function('ale_linters#rust#analyzer#GetProjectRoot'),

And now this configuration works:

let g:ale_rust_analyzer_config = {
      \ 'diagnostics': { 'disabled': ['unresolved-import'] },
      \ 'cargo': { 'loadOutDirsFromCheck': v:true },
      \ 'procMacro': { 'enable': v:true },
      \ 'checkOnSave': { 'command': 'clippy', 'enable': v:true }
      \ }

All 4 comments

I made this change:

diff --git a/ale_linters/rust/analyzer.vim b/ale_linters/rust/analyzer.vim
index 3666ec03..77d946f7 100644
--- a/ale_linters/rust/analyzer.vim
+++ b/ale_linters/rust/analyzer.vim
@@ -17,7 +17,7 @@ endfunction
 call ale#linter#Define('rust', {
 \   'name': 'analyzer',
 \   'lsp': 'stdio',
-\   'lsp_config': {b -> ale#Var(b, 'rust_analyzer_config')},
+\   'initialization_options': {b -> ale#Var(b, 'rust_analyzer_config')},
 \   'executable': {b -> ale#Var(b, 'rust_analyzer_executable')},
 \   'command': function('ale_linters#rust#analyzer#GetCommand'),
 \   'project_root': function('ale_linters#rust#analyzer#GetProjectRoot'),

And now this configuration works:

let g:ale_rust_analyzer_config = {
      \ 'diagnostics': { 'disabled': ['unresolved-import'] },
      \ 'cargo': { 'loadOutDirsFromCheck': v:true },
      \ 'procMacro': { 'enable': v:true },
      \ 'checkOnSave': { 'command': 'clippy', 'enable': v:true }
      \ }

@user827 that diff worked perfectly for me, thanks!

Happy to submit a PR if people think this is the right fix.

I'm ok with someone submitting the PR. I'm no longer using ale for lsp though but neovim's native implementation and there the initilizationOptions stopped working. I think the lsp_config does not work because ale incorrectly handles the workspace/configuration request send by the server.

Works for me, thanks @user827. :+1: for @blinsay to submit a PR.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

trevordmiller picture trevordmiller  路  3Comments

kronos29296 picture kronos29296  路  4Comments

glepnir picture glepnir  路  3Comments

EdmundsEcho picture EdmundsEcho  路  3Comments

plexigras picture plexigras  路  3Comments