File: response.vim

package info (click to toggle)
vim-ale 4.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,764 kB
  • sloc: sh: 499; python: 311; perl: 31; makefile: 4; xml: 4; javascript: 1
file content (152 lines) | stat: -rw-r--r-- 5,027 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
" 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

" Parse the message for textDocument/publishDiagnostics
function! ale#lsp#response#ReadDiagnostics(response) abort
    let l:loclist = []

    for l:diagnostic in a:response.params.diagnostics
        let l:severity = get(l:diagnostic, 'severity', 0)
        let l:loclist_item = {
        \   'text': substitute(l:diagnostic.message, '\(\r\n\|\n\|\r\)', ' ', 'g'),
        \   '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