All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
1 " Author: w0rp <devw0rp@gmail.com>
2 " Description: Parsing and transforming of LSP server responses.
4 " Constants for error codes.
6 let s:PARSE_ERROR = -32700
7 let s:INVALID_REQUEST = -32600
8 let s:METHOD_NOT_FOUND = -32601
9 let s:INVALID_PARAMS = -32602
10 let s:INTERNAL_ERROR = -32603
11 let s:SERVER_ERROR_START = -32099
12 let s:SERVER_ERROR_END = -32000
13 let s:SERVER_NOT_INITIALIZED = -32002
14 let s:UNKNOWN_ERROR_CODE = -32001
15 " Defined by the protocol.
16 let s:REQUEST_CANCELLED = -32800
18 " Constants for message severity codes.
19 let s:SEVERITY_ERROR = 1
20 let s:SEVERITY_WARNING = 2
21 let s:SEVERITY_INFORMATION = 3
22 let s:SEVERITY_HINT = 4
24 " Convert Diagnostic[] data from a language server to an ALE loclist.
25 function! ale#lsp#response#ReadDiagnostics(diagnostics) abort
28 for l:diagnostic in a:diagnostics
29 let l:severity = get(l:diagnostic, 'severity', 0)
30 let l:loclist_item = {
31 \ 'text': substitute(l:diagnostic.message, '\(\r\n\|\n\|\r\)', ' ', 'g'),
33 \ 'lnum': l:diagnostic.range.start.line + 1,
34 \ 'col': l:diagnostic.range.start.character + 1,
35 \ 'end_lnum': l:diagnostic.range.end.line + 1,
36 \ 'end_col': l:diagnostic.range.end.character,
39 if l:severity == s:SEVERITY_WARNING
40 let l:loclist_item.type = 'W'
41 elseif l:severity == s:SEVERITY_INFORMATION
42 " TODO: Use 'I' here in future.
43 let l:loclist_item.type = 'W'
44 elseif l:severity == s:SEVERITY_HINT
45 " TODO: Use 'H' here in future
46 let l:loclist_item.type = 'W'
49 if has_key(l:diagnostic, 'code')
50 if type(l:diagnostic.code) == v:t_string
51 let l:loclist_item.code = l:diagnostic.code
52 elseif type(l:diagnostic.code) == v:t_number && l:diagnostic.code != -1
53 let l:loclist_item.code = string(l:diagnostic.code)
54 let l:loclist_item.nr = l:diagnostic.code
58 if has_key(l:diagnostic, 'relatedInformation')
59 \ && l:diagnostic.relatedInformation isnot v:null
60 let l:related = deepcopy(l:diagnostic.relatedInformation)
61 call map(l:related, {key, val ->
62 \ ale#util#ToResource(val.location.uri) .
63 \ ':' . (val.location.range.start.line + 1) .
64 \ ':' . (val.location.range.start.character + 1) .
65 \ ":\n\t" . val.message
67 let l:loclist_item.detail = l:diagnostic.message . "\n" . join(l:related, "\n")
70 if has_key(l:diagnostic, 'source')
71 let l:loclist_item.detail = printf(
73 \ l:diagnostic.source,
74 \ l:diagnostic.message
78 call add(l:loclist, l:loclist_item)
84 function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
87 for l:diagnostic in a:response.body.diagnostics
88 let l:loclist_item = {
89 \ 'text': l:diagnostic.text,
91 \ 'lnum': l:diagnostic.start.line,
92 \ 'col': l:diagnostic.start.offset,
93 \ 'end_lnum': l:diagnostic.end.line,
94 \ 'end_col': l:diagnostic.end.offset - 1,
97 if has_key(l:diagnostic, 'code')
98 if type(l:diagnostic.code) == v:t_string
99 let l:loclist_item.code = l:diagnostic.code
100 elseif type(l:diagnostic.code) == v:t_number && l:diagnostic.code != -1
101 let l:loclist_item.code = string(l:diagnostic.code)
102 let l:loclist_item.nr = l:diagnostic.code
106 if get(l:diagnostic, 'category') is# 'warning'
107 let l:loclist_item.type = 'W'
110 if get(l:diagnostic, 'category') is# 'suggestion'
111 let l:loclist_item.type = 'I'
114 call add(l:loclist, l:loclist_item)
120 function! ale#lsp#response#GetErrorMessage(response) abort
121 if type(get(a:response, 'error', 0)) isnot v:t_dict
125 let l:code = get(a:response.error, 'code')
127 " Only report things for these error codes.
128 if l:code isnot s:INVALID_PARAMS && l:code isnot s:INTERNAL_ERROR
132 let l:message = get(a:response.error, 'message', '')
138 " Include the traceback or error data as details, if present.
139 let l:error_data = get(a:response.error, 'data', {})
141 if type(l:error_data) is v:t_string
142 let l:message .= "\n" . l:error_data
143 elseif type(l:error_data) is v:t_dict
144 let l:traceback = get(l:error_data, 'traceback', [])
146 if type(l:traceback) is v:t_list && !empty(l:traceback)
147 let l:message .= "\n" . join(l:traceback, "\n")