summaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2018-05-28 16:24:15 +0100
committerw0rp <devw0rp@gmail.com>2018-05-28 16:24:15 +0100
commitd9717147bf735a37adc20f1e8a068806f9ba56be (patch)
tree831669f35417ebde730fbf090401324dcb7d904e /autoload
parent3c55cb087d4f48b16e05c6f60e70a12442003a12 (diff)
downloadale-d9717147bf735a37adc20f1e8a068806f9ba56be.zip
Close #1559 - Report errors from LSP servers in :ALEInfo
Diffstat (limited to 'autoload')
-rw-r--r--autoload/ale/debugging.vim25
-rw-r--r--autoload/ale/engine.vim37
-rw-r--r--autoload/ale/lsp/response.vim42
3 files changed, 97 insertions, 7 deletions
diff --git a/autoload/ale/debugging.vim b/autoload/ale/debugging.vim
index bec79a85..f32e4308 100644
--- a/autoload/ale/debugging.vim
+++ b/autoload/ale/debugging.vim
@@ -168,6 +168,30 @@ function! s:EchoLinterAliases(all_linters) abort
endfor
endfunction
+function! s:EchoLSPErrorMessages(all_linter_names) abort
+ let l:lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
+ let l:header_echoed = 0
+
+ for l:linter_name in a:all_linter_names
+ let l:error_list = get(l:lsp_error_messages, l:linter_name, [])
+
+ if !empty(l:error_list)
+ if !l:header_echoed
+ call s:Echo(' LSP Error Messages:')
+ call s:Echo('')
+ endif
+
+ call s:Echo('(Errors for ' . l:linter_name . ')')
+
+ for l:message in l:error_list
+ for l:line in split(l:message, "\n")
+ call s:Echo(l:line)
+ endfor
+ endfor
+ endif
+ endfor
+endfunction
+
function! ale#debugging#Info() abort
let l:filetype = &filetype
@@ -200,6 +224,7 @@ function! ale#debugging#Info() abort
call s:Echo(' Global Variables:')
call s:Echo('')
call s:EchoGlobalVariables()
+ call s:EchoLSPErrorMessages(l:all_names)
call s:Echo(' Command History:')
call s:Echo('')
call s:EchoCommandHistory()
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index e1c41552..5cd12187 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -81,6 +81,11 @@ function! ale#engine#ClearLSPData() abort
let s:lsp_linter_map = {}
endfunction
+" Just for tests.
+function! ale#engine#SetLSPLinterMap(replacement_map) abort
+ let s:lsp_linter_map = a:replacement_map
+endfunction
+
" This function is documented and part of the public API.
"
" Return 1 if ALE is busy checking a given buffer
@@ -270,20 +275,38 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
call ale#engine#HandleLoclist('tsserver', l:buffer, l:loclist)
endfunction
-function! s:HandleLSPErrorMessage(error_message) abort
- execute 'echoerr ''Error from LSP:'''
+function! s:HandleLSPErrorMessage(linter_name, response) abort
+ if !g:ale_history_enabled || !g:ale_history_log_output
+ return
+ endif
+
+ if empty(a:linter_name)
+ return
+ endif
- for l:line in split(a:error_message, "\n")
- execute 'echoerr l:line'
- endfor
+ let l:message = ale#lsp#response#GetErrorMessage(a:response)
+
+ if empty(l:message)
+ return
+ endif
+
+ " This global variable is set here so we don't load the debugging.vim file
+ " until someone uses :ALEInfo.
+ let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
+
+ if !has_key(g:ale_lsp_error_messages, a:linter_name)
+ let g:ale_lsp_error_messages[a:linter_name] = []
+ endif
+
+ call add(g:ale_lsp_error_messages[a:linter_name], l:message)
endfunction
function! ale#engine#HandleLSPResponse(conn_id, response) abort
let l:method = get(a:response, 'method', '')
+ let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
- " Uncomment this line to print LSP error messages.
- " call s:HandleLSPErrorMessage(a:response.error.message)
+ call s:HandleLSPErrorMessage(l:linter_name, a:response)
elseif l:method is# 'textDocument/publishDiagnostics'
call s:HandleLSPDiagnostics(a:conn_id, a:response)
elseif get(a:response, 'type', '') is# 'event'
diff --git a/autoload/ale/lsp/response.vim b/autoload/ale/lsp/response.vim
index 5a431287..94794e98 100644
--- a/autoload/ale/lsp/response.vim
+++ b/autoload/ale/lsp/response.vim
@@ -1,6 +1,20 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Parsing and transforming of LSP server responses.
+" Constants for error codes.
+" Defined by JSON RPC
+let s:PARSE_ERROR = -32700
+let s:INVALID_REQUEST = -32600
+let s:METHOD_NOT_FOUND = -32601
+let s:INVALID_PARAMS = -32602
+let s:INTERNAL_ERROR = -32603
+let s:SERVER_ERROR_START = -32099
+let s:SERVER_ERROR_END = -32000
+let s:SERVER_NOT_INITIALIZED = -32002
+let s:UNKNOWN_ERROR_CODE = -32001
+" Defined by the protocol.
+let s:REQUEST_CANCELLED = -32800
+
" Constants for message severity codes.
let s:SEVERITY_ERROR = 1
let s:SEVERITY_WARNING = 2
@@ -72,3 +86,31 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
return l:loclist
endfunction
+
+function! ale#lsp#response#GetErrorMessage(response) abort
+ if type(get(a:response, 'error', 0)) isnot type({})
+ return ''
+ endif
+
+ let l:code = get(a:response.error, 'code')
+
+ " Only report things for these error codes.
+ if l:code isnot s:INVALID_PARAMS && l:code isnot s:INTERNAL_ERROR
+ return ''
+ endif
+
+ let l:message = get(a:response.error, 'message', '')
+
+ if empty(l:message)
+ return ''
+ endif
+
+ " Include the traceback as details, if it's there.
+ let l:traceback = get(get(a:response.error, 'data', {}), 'traceback', [])
+
+ if type(l:traceback) is type([]) && !empty(l:traceback)
+ let l:message .= "\n" . join(l:traceback, "\n")
+ endif
+
+ return l:message
+endfunction