summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ale_linters/rust/langserver.vim33
-rw-r--r--autoload/ale/linter.vim6
-rw-r--r--autoload/ale/lsp.vim10
3 files changed, 47 insertions, 2 deletions
diff --git a/ale_linters/rust/langserver.vim b/ale_linters/rust/langserver.vim
new file mode 100644
index 00000000..5e42a97f
--- /dev/null
+++ b/ale_linters/rust/langserver.vim
@@ -0,0 +1,33 @@
+" 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/autoload/ale/linter.vim b/autoload/ale/linter.vim
index 0af42af9..8fc68510 100644
--- a/autoload/ale/linter.vim
+++ b/autoload/ale/linter.vim
@@ -377,6 +377,12 @@ function! ale#linter#StartLSP(buffer, linter, callback) abort
let l:address = ''
let l:root = ale#util#GetFunction(a:linter.project_root_callback)(a:buffer)
+ if empty(l:root) && a:linter.lsp !=# 'tsserver'
+ " If there's no project root, then we can't check files with LSP,
+ " unless we are using tsserver, which doesn't use project roots.
+ return {}
+ endif
+
if a:linter.lsp ==# 'socket'
let l:address = ale#linter#GetAddress(a:buffer, a:linter)
let l:conn_id = ale#lsp#ConnectToAddress(
diff --git a/autoload/ale/lsp.vim b/autoload/ale/lsp.vim
index 855abb11..eb66eb47 100644
--- a/autoload/ale/lsp.vim
+++ b/autoload/ale/lsp.vim
@@ -190,7 +190,13 @@ function! ale#lsp#HandleOtherInitializeResponses(conn, response) abort
return
endif
- if get(a:response, 'method', '') ==# 'textDocument/publishDiagnostics'
+ if get(a:response, 'method', '') ==# ''
+ if has_key(get(a:response, 'result', {}), 'capabilities')
+ for [l:dir, l:project] in l:uninitialized_projects
+ call s:MarkProjectAsInitialized(a:conn, l:project)
+ endfor
+ endif
+ elseif get(a:response, 'method', '') ==# 'textDocument/publishDiagnostics'
let l:filename = ale#path#FromURI(a:response.params.uri)
for [l:dir, l:project] in l:uninitialized_projects
@@ -237,7 +243,7 @@ function! s:HandleCommandMessage(job_id, message) abort
endfunction
function! s:RegisterProject(conn, project_root) abort
- if !has_key(a:conn, a:project_root)
+ if !has_key(a:conn.projects, a:project_root)
" Tools without project roots are ready right away, like tsserver.
let a:conn.projects[a:project_root] = {
\ 'initialized': empty(a:project_root),