mirror of
https://github.com/dense-analysis/ale.git
synced 2026-11-07 20:55:56 +08:00
CI / build_image (push) Has been cancelled
CI / test_ale (--linters-only) (push) Has been cancelled
CI / test_ale (--lua-only) (push) Has been cancelled
CI / test_ale (--neovim-07-only) (push) Has been cancelled
CI / test_ale (--neovim-08-only) (push) Has been cancelled
CI / test_ale (--vim-80-only) (push) Has been cancelled
CI / test_ale (--vim-90-only) (push) Has been cancelled
* Updates `ale#lsp#response#ReadDiagnostics` to always store the full, unaltered diagnostic message from the LSP in question. The current process is to replace all newline characters with whitespace (' '), which then leads to broken formatting when viewing complex output from an LSP with `:ALEDetail` and other commands.
* Updates `ale#cursor#TruncatedEcho` to replace newline characters with a space ' ' instead of an empty string '' to retain the previous style of formatting for echoed messages.
Fixes: #2356
Fixes: #3068
Fixes: #2301
153 lines
4.9 KiB
VimL
153 lines
4.9 KiB
VimL
" 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
|
|
let s:SEVERITY_INFORMATION = 3
|
|
let s:SEVERITY_HINT = 4
|
|
|
|
" Convert Diagnostic[] data from a language server to an ALE loclist.
|
|
function! ale#lsp#response#ReadDiagnostics(diagnostics) abort
|
|
let l:loclist = []
|
|
|
|
for l:diagnostic in a:diagnostics
|
|
let l:severity = get(l:diagnostic, 'severity', 0)
|
|
let l:loclist_item = {
|
|
\ 'text': l:diagnostic.message,
|
|
\ 'type': 'E',
|
|
\ 'lnum': l:diagnostic.range.start.line + 1,
|
|
\ 'col': l:diagnostic.range.start.character + 1,
|
|
\ 'end_lnum': l:diagnostic.range.end.line + 1,
|
|
\ 'end_col': l:diagnostic.range.end.character,
|
|
\}
|
|
|
|
if l:severity == s:SEVERITY_WARNING
|
|
let l:loclist_item.type = 'W'
|
|
elseif l:severity == s:SEVERITY_INFORMATION
|
|
" TODO: Use 'I' here in future.
|
|
let l:loclist_item.type = 'W'
|
|
elseif l:severity == s:SEVERITY_HINT
|
|
" TODO: Use 'H' here in future
|
|
let l:loclist_item.type = 'W'
|
|
endif
|
|
|
|
if has_key(l:diagnostic, 'code')
|
|
if type(l:diagnostic.code) == v:t_string
|
|
let l:loclist_item.code = l:diagnostic.code
|
|
elseif type(l:diagnostic.code) == v:t_number && l:diagnostic.code != -1
|
|
let l:loclist_item.code = string(l:diagnostic.code)
|
|
let l:loclist_item.nr = l:diagnostic.code
|
|
endif
|
|
endif
|
|
|
|
if has_key(l:diagnostic, 'relatedInformation')
|
|
\ && l:diagnostic.relatedInformation isnot v:null
|
|
let l:related = deepcopy(l:diagnostic.relatedInformation)
|
|
call map(l:related, {key, val ->
|
|
\ ale#util#ToResource(val.location.uri) .
|
|
\ ':' . (val.location.range.start.line + 1) .
|
|
\ ':' . (val.location.range.start.character + 1) .
|
|
\ ":\n\t" . val.message
|
|
\})
|
|
let l:loclist_item.detail = l:diagnostic.message . "\n" . join(l:related, "\n")
|
|
endif
|
|
|
|
if has_key(l:diagnostic, 'source')
|
|
let l:loclist_item.detail = printf(
|
|
\ '[%s] %s',
|
|
\ l:diagnostic.source,
|
|
\ l:diagnostic.message
|
|
\)
|
|
endif
|
|
|
|
call add(l:loclist, l:loclist_item)
|
|
endfor
|
|
|
|
return l:loclist
|
|
endfunction
|
|
|
|
function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
|
|
let l:loclist = []
|
|
|
|
for l:diagnostic in a:response.body.diagnostics
|
|
let l:loclist_item = {
|
|
\ 'text': l:diagnostic.text,
|
|
\ 'type': 'E',
|
|
\ 'lnum': l:diagnostic.start.line,
|
|
\ 'col': l:diagnostic.start.offset,
|
|
\ 'end_lnum': l:diagnostic.end.line,
|
|
\ 'end_col': l:diagnostic.end.offset - 1,
|
|
\}
|
|
|
|
if has_key(l:diagnostic, 'code')
|
|
if type(l:diagnostic.code) == v:t_string
|
|
let l:loclist_item.code = l:diagnostic.code
|
|
elseif type(l:diagnostic.code) == v:t_number && l:diagnostic.code != -1
|
|
let l:loclist_item.code = string(l:diagnostic.code)
|
|
let l:loclist_item.nr = l:diagnostic.code
|
|
endif
|
|
endif
|
|
|
|
if get(l:diagnostic, 'category') is# 'warning'
|
|
let l:loclist_item.type = 'W'
|
|
endif
|
|
|
|
if get(l:diagnostic, 'category') is# 'suggestion'
|
|
let l:loclist_item.type = 'I'
|
|
endif
|
|
|
|
call add(l:loclist, l:loclist_item)
|
|
endfor
|
|
|
|
return l:loclist
|
|
endfunction
|
|
|
|
function! ale#lsp#response#GetErrorMessage(response) abort
|
|
if type(get(a:response, 'error', 0)) isnot v:t_dict
|
|
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 or error data as details, if present.
|
|
let l:error_data = get(a:response.error, 'data', {})
|
|
|
|
if type(l:error_data) is v:t_string
|
|
let l:message .= "\n" . l:error_data
|
|
elseif type(l:error_data) is v:t_dict
|
|
let l:traceback = get(l:error_data, 'traceback', [])
|
|
|
|
if type(l:traceback) is v:t_list && !empty(l:traceback)
|
|
let l:message .= "\n" . join(l:traceback, "\n")
|
|
endif
|
|
endif
|
|
|
|
return l:message
|
|
endfunction
|