summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ale_linters/rust/langserver.vim33
-rw-r--r--ale_linters/rust/rls.vim33
-rw-r--r--autoload/ale/completion.vim2
-rw-r--r--autoload/ale/engine.vim22
-rw-r--r--autoload/ale/lsp.vim2
-rw-r--r--test/command_callback/rust-rls-project/Cargo.toml0
-rw-r--r--test/command_callback/test_rust_rls_callbacks.vader32
-rw-r--r--test/test_engine_lsp_response_handling.vader12
8 files changed, 91 insertions, 45 deletions
diff --git a/ale_linters/rust/langserver.vim b/ale_linters/rust/langserver.vim
deleted file mode 100644
index 5e42a97f..00000000
--- a/ale_linters/rust/langserver.vim
+++ /dev/null
@@ -1,33 +0,0 @@
-" Author: w0rp <devw0rp@gmail.com>
-" Description: A language server for Rust
-
-call ale#Set('rust_langserver_executable', 'rls')
-
-function! ale_linters#rust#langserver#GetExecutable(buffer) abort
- return ale#Var(a:buffer, 'rust_langserver_executable')
-endfunction
-
-function! ale_linters#rust#langserver#GetCommand(buffer) abort
- let l:executable = ale_linters#rust#langserver#GetExecutable(a:buffer)
-
- return ale#Escape(l:executable) . ' +nightly'
-endfunction
-
-function! ale_linters#rust#langserver#GetLanguage(buffer) abort
- return 'rust'
-endfunction
-
-function! ale_linters#rust#langserver#GetProjectRoot(buffer) abort
- let l:cargo_file = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
-
- return !empty(l:cargo_file) ? fnamemodify(l:cargo_file, ':h') : ''
-endfunction
-
-call ale#linter#Define('rust', {
-\ 'name': 'langserver',
-\ 'lsp': 'stdio',
-\ 'executable_callback': 'ale_linters#rust#langserver#GetExecutable',
-\ 'command_callback': 'ale_linters#rust#langserver#GetCommand',
-\ 'language_callback': 'ale_linters#rust#langserver#GetLanguage',
-\ 'project_root_callback': 'ale_linters#rust#langserver#GetProjectRoot',
-\})
diff --git a/ale_linters/rust/rls.vim b/ale_linters/rust/rls.vim
new file mode 100644
index 00000000..c49d2682
--- /dev/null
+++ b/ale_linters/rust/rls.vim
@@ -0,0 +1,33 @@
+" Author: w0rp <devw0rp@gmail.com>
+" Description: A language server for Rust
+
+call ale#Set('rust_rls_executable', 'rls')
+
+function! ale_linters#rust#rls#GetExecutable(buffer) abort
+ return ale#Var(a:buffer, 'rust_rls_executable')
+endfunction
+
+function! ale_linters#rust#rls#GetCommand(buffer) abort
+ let l:executable = ale_linters#rust#rls#GetExecutable(a:buffer)
+
+ return ale#Escape(l:executable) . ' +nightly'
+endfunction
+
+function! ale_linters#rust#rls#GetLanguage(buffer) abort
+ return 'rust'
+endfunction
+
+function! ale_linters#rust#rls#GetProjectRoot(buffer) abort
+ let l:cargo_file = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
+
+ return !empty(l:cargo_file) ? fnamemodify(l:cargo_file, ':h') : ''
+endfunction
+
+call ale#linter#Define('rust', {
+\ 'name': 'rls',
+\ 'lsp': 'stdio',
+\ 'executable_callback': 'ale_linters#rust#rls#GetExecutable',
+\ 'command_callback': 'ale_linters#rust#rls#GetCommand',
+\ 'language_callback': 'ale_linters#rust#rls#GetLanguage',
+\ 'project_root_callback': 'ale_linters#rust#rls#GetProjectRoot',
+\})
diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim
index 214891fb..3eeb6173 100644
--- a/autoload/ale/completion.vim
+++ b/autoload/ale/completion.vim
@@ -170,7 +170,7 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
return l:results
endfunction
-function! s:HandleTSServerLSPResponse(response) abort
+function! s:HandleTSServerLSPResponse(conn_id, response) abort
if !s:CompletionStillValid(get(a:response, 'request_seq'))
return
endif
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index 52acfe7f..a5a5f524 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -11,6 +11,11 @@ if !has_key(s:, 'job_info_map')
let s:job_info_map = {}
endif
+" Associates LSP connection IDs with linter names.
+if !has_key(s:, 'lsp_linter_map')
+ let s:lsp_linter_map = {}
+endif
+
let s:executable_cache_map = {}
" Check if files are executable, and if they are, remember that they are
@@ -192,12 +197,18 @@ function! s:HandleExit(job_id, exit_code) abort
call s:HandleLoclist(l:linter.name, l:buffer, l:loclist)
endfunction
-function! s:HandleLSPDiagnostics(response) abort
+function! s:HandleLSPDiagnostics(conn_id, response) abort
+ let l:linter_name = s:lsp_linter_map[a:conn_id]
let l:filename = ale#path#FromURI(a:response.params.uri)
let l:buffer = bufnr(l:filename)
+
+ if l:buffer <= 0
+ return
+ endif
+
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
- call s:HandleLoclist('langserver', l:buffer, l:loclist)
+ call s:HandleLoclist(l:linter_name, l:buffer, l:loclist)
endfunction
function! s:HandleTSServerDiagnostics(response, error_type) abort
@@ -233,14 +244,14 @@ function! s:HandleLSPErrorMessage(error_message) abort
endfor
endfunction
-function! ale#engine#HandleLSPResponse(response) abort
+function! ale#engine#HandleLSPResponse(conn_id, response) abort
let l:method = get(a:response, 'method', '')
if get(a:response, 'jsonrpc', '') ==# '2.0' && has_key(a:response, 'error')
" Uncomment this line to print LSP error messages.
" call s:HandleLSPErrorMessage(a:response.error.message)
elseif l:method ==# 'textDocument/publishDiagnostics'
- call s:HandleLSPDiagnostics(a:response)
+ call s:HandleLSPDiagnostics(a:conn_id, a:response)
elseif get(a:response, 'type', '') ==# 'event'
\&& get(a:response, 'event', '') ==# 'semanticDiag'
call s:HandleTSServerDiagnostics(a:response, 'semantic')
@@ -617,6 +628,9 @@ function! s:CheckWithLSP(buffer, linter) abort
let l:id = l:lsp_details.connection_id
let l:root = l:lsp_details.project_root
+ " Remember the linter this connection is for.
+ let s:lsp_linter_map[l:id] = a:linter.name
+
let l:change_message = a:linter.lsp ==# 'tsserver'
\ ? ale#lsp#tsserver_message#Geterr(a:buffer)
\ : ale#lsp#message#DidChange(a:buffer)
diff --git a/autoload/ale/lsp.vim b/autoload/ale/lsp.vim
index eb66eb47..bb9a24f2 100644
--- a/autoload/ale/lsp.vim
+++ b/autoload/ale/lsp.vim
@@ -222,7 +222,7 @@ function! ale#lsp#HandleMessage(conn, message) abort
" Call all of the registered handlers with the response.
for l:Callback in a:conn.callback_list
- call ale#util#GetFunction(l:Callback)(l:response)
+ call ale#util#GetFunction(l:Callback)(a:conn.id, l:response)
endfor
endif
endfor
diff --git a/test/command_callback/rust-rls-project/Cargo.toml b/test/command_callback/rust-rls-project/Cargo.toml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/rust-rls-project/Cargo.toml
diff --git a/test/command_callback/test_rust_rls_callbacks.vader b/test/command_callback/test_rust_rls_callbacks.vader
new file mode 100644
index 00000000..76e69927
--- /dev/null
+++ b/test/command_callback/test_rust_rls_callbacks.vader
@@ -0,0 +1,32 @@
+Before:
+ Save g:ale_rust_rls_executable
+
+ unlet! g:ale_rust_rls_executable
+
+ runtime ale_linters/rust/rls.vim
+
+ call ale#test#SetDirectory('/testplugin/test/command_callback')
+
+After:
+ Restore
+
+ call ale#test#RestoreDirectory()
+ call ale#linter#Reset()
+
+Execute(The default executable path should be correct):
+ AssertEqual 'rls', ale_linters#rust#rls#GetExecutable(bufnr(''))
+ AssertEqual
+ \ ale#Escape('rls') . ' +nightly',
+ \ ale_linters#rust#rls#GetCommand(bufnr(''))
+
+Execute(The language string should be correct):
+ AssertEqual 'rust', ale_linters#rust#rls#GetLanguage(bufnr(''))
+
+Execute(The project root should be detected correctly):
+ AssertEqual '', ale_linters#rust#rls#GetProjectRoot(bufnr(''))
+
+ call ale#test#SetFilename('rust-rls-project/test.rs')
+
+ AssertEqual
+ \ g:dir . '/rust-rls-project',
+ \ ale_linters#rust#rls#GetProjectRoot(bufnr(''))
diff --git a/test/test_engine_lsp_response_handling.vader b/test/test_engine_lsp_response_handling.vader
index 1f766baf..b3a45b14 100644
--- a/test/test_engine_lsp_response_handling.vader
+++ b/test/test_engine_lsp_response_handling.vader
@@ -15,7 +15,7 @@ Execute(tsserver syntax error responses should be handled correctly):
" When we get syntax errors and no semantic errors, we should keep the
" syntax errors.
- call ale#engine#HandleLSPResponse({
+ call ale#engine#HandleLSPResponse(1, {
\ 'seq': 0,
\ 'type': 'event',
\ 'event': 'syntaxDiag',
@@ -37,7 +37,7 @@ Execute(tsserver syntax error responses should be handled correctly):
\ ],
\ },
\})
- call ale#engine#HandleLSPResponse({
+ call ale#engine#HandleLSPResponse(1, {
\ 'seq': 0,
\ 'type': 'event',
\ 'event': 'semanticDiag',
@@ -65,7 +65,7 @@ Execute(tsserver syntax error responses should be handled correctly):
\ getloclist(0)
" After we get empty syntax errors, we should clear them.
- call ale#engine#HandleLSPResponse({
+ call ale#engine#HandleLSPResponse(1, {
\ 'seq': 0,
\ 'type': 'event',
\ 'event': 'syntaxDiag',
@@ -88,7 +88,7 @@ Execute(tsserver semantic error responses should be handled correctly):
" When we get syntax errors and no semantic errors, we should keep the
" syntax errors.
- call ale#engine#HandleLSPResponse({
+ call ale#engine#HandleLSPResponse(1, {
\ 'seq': 0,
\ 'type': 'event',
\ 'event': 'syntaxDiag',
@@ -98,7 +98,7 @@ Execute(tsserver semantic error responses should be handled correctly):
\ ],
\ },
\})
- call ale#engine#HandleLSPResponse({
+ call ale#engine#HandleLSPResponse(1, {
\ 'seq': 0,
\ 'type': 'event',
\ 'event': 'semanticDiag',
@@ -138,7 +138,7 @@ Execute(tsserver semantic error responses should be handled correctly):
\ getloclist(0)
" After we get empty syntax errors, we should clear them.
- call ale#engine#HandleLSPResponse({
+ call ale#engine#HandleLSPResponse(1, {
\ 'seq': 0,
\ 'type': 'event',
\ 'event': 'semanticDiag',