]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/vim-lsp/autoload/lsp/internal/diagnostics/state.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

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.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge commit '294584081929424aec883f90c7d6515b3743358d' as '.vim/bundle/vim-lsp-ale'
[etc/vim.git] / .vim / bundle / vim-lsp / autoload / lsp / internal / diagnostics / state.vim
1 " https://microsoft.github.io/language-server-protocol/specifications/specification-current/#diagnostic
2 "
3 " Refer to https://github.com/microsoft/language-server-protocol/pull/1019 on normalization of urls.
4 " {
5 "   'normalized_uri': {
6 "       'server_name': {
7 "           'method': 'textDocument/publishDiagnostics',
8 "           'params': {
9 "               'uri': 'uri',        " this uri is not normalized and is exactly what server returns
10 "               'dignostics': [      " array can never be null but can be empty
11 "                   https://microsoft.github.io/language-server-protocol/specifications/specification-current/#diagnostic
12 "                   { range, message, severity?, code?, codeDesciption?, source?, tags?, relatedInformation?, data? }
13 "               ]
14 "           }
15 "       }
16 "   }
17 " Note: Do not remove when buffer unloads or doesn't exist since some server
18 " may send diagnsotics information regardless of textDocument/didOpen.
19 " buffer state is removed when server exits.
20 " TODO: reset buffer state when server initializes. ignoring for now for perf.
21 let s:diagnostics_state = {}
22
23 " internal state for whether it is enabled or not to avoid multiple subscriptions
24 let s:enabled = 0
25
26 let s:diagnostic_kinds = {
27     \ 1: 'error',
28     \ 2: 'warning',
29     \ 3: 'information',
30     \ 4: 'hint',
31     \ }
32
33 function! lsp#internal#diagnostics#state#_enable() abort
34     " don't even bother registering if the feature is disabled
35     if !g:lsp_diagnostics_enabled | return | endif
36
37     if s:enabled | return | endif
38     let s:enabled = 1
39
40     call lsp#internal#diagnostics#state#_reset()
41
42     let s:Dispose = lsp#callbag#pipe(
43         \ lsp#callbag#merge(
44         \   lsp#callbag#pipe(
45         \       lsp#stream(),
46         \       lsp#callbag#filter({x->has_key(x, 'server') && has_key(x, 'response')
47         \           && get(x['response'], 'method', '') ==# 'textDocument/publishDiagnostics'}),
48         \       lsp#callbag#tap({x->s:on_text_documentation_publish_diagnostics(x['server'], x['response'])}),
49         \   ),
50         \   lsp#callbag#pipe(
51         \       lsp#stream(),
52         \       lsp#callbag#filter({x->has_key(x, 'server') && has_key(x, 'response')
53         \           && get(x['response'], 'method', '') ==# '$/vimlsp/lsp_server_exit' }),
54         \       lsp#callbag#tap({x->s:on_exit(x['response'])}),
55         \   ),
56         \ ),
57         \ lsp#callbag#subscribe(),
58         \ )
59
60     call s:notify_diagnostics_update()
61 endfunction
62
63 function! lsp#internal#diagnostics#state#_disable() abort
64     if !s:enabled | return | endif
65     if exists('s:Dispose')
66         call s:Dispose()
67         unlet s:Dispose
68     endif
69     call lsp#internal#diagnostics#state#_reset()
70     call s:notify_diagnostics_update()
71     let s:enabled = 0
72 endfunction
73
74 function! lsp#internal#diagnostics#state#_reset() abort
75     let s:diagnostics_state = {}
76     let s:diagnostics_disabled_buffers = {}
77 endfunction
78
79 " callers should always treat the return value as immutable
80 " @return {
81 "   'servername': response
82 " }
83 function! lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(uri) abort
84     return get(s:diagnostics_state, lsp#utils#normalize_uri(a:uri), {})
85 endfunction
86
87 " callers should always treat the return value as immutable.
88 " callers should treat uri as normalized via lsp#utils#normalize_uri
89 " @return {
90 "   'normalized_uri': {
91 "       'servername': response
92 "   }
93 " }
94 function! lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_uri_and_server() abort
95     return s:diagnostics_state
96 endfunction
97
98 function! s:on_text_documentation_publish_diagnostics(server, response) abort
99     if lsp#client#is_error(a:response) | return | endif
100     let l:normalized_uri = lsp#utils#normalize_uri(a:response['params']['uri'])
101     if !has_key(s:diagnostics_state, l:normalized_uri)
102         let s:diagnostics_state[l:normalized_uri] = {}
103     endif
104     let s:diagnostics_state[l:normalized_uri][a:server] = a:response
105     call s:notify_diagnostics_update(a:server, l:normalized_uri)
106 endfunction
107
108 function! s:on_exit(response) abort
109     let l:server = a:response['params']['server']
110     let l:notify = 0
111     for [l:key, l:value] in items(s:diagnostics_state)
112         if has_key(l:value, l:server)
113             let l:notify = 1
114             call remove(l:value, l:server)
115         endif
116     endfor
117     if l:notify | call s:notify_diagnostics_update(l:server) | endif
118 endfunction
119
120 function! lsp#internal#diagnostics#state#_force_notify_buffer(buffer) abort
121     " TODO: optimize buffer only
122     call s:notify_diagnostics_update()
123 endfunction
124
125 " call s:notify_diagnostics_update()
126 " call s:notify_diagnostics_update('server')
127 " call s:notify_diagnostics_update('server', 'uri')
128 function! s:notify_diagnostics_update(...) abort
129     let l:data = { 'server': '$vimlsp', 'response': { 'method': '$/vimlsp/lsp_diagnostics_updated', 'params': {} } }
130     " if a:0 > 0 | let l:data['response']['params']['server'] = a:1 | endif
131     " if a:0 > 1 | let l:data['response']['params']['uri'] = a:2 | endif
132     call lsp#stream(1, l:data)
133     doautocmd <nomodeline> User lsp_diagnostics_updated
134 endfunction
135
136 function! lsp#internal#diagnostics#state#_enable_for_buffer(bufnr) abort
137     if getbufvar(a:bufnr, 'lsp_diagnostics_enabled', 1) == 0
138         call setbufvar(a:bufnr, 'lsp_diagnostics_enabled', 1)
139         call s:notify_diagnostics_update()
140     endif
141 endfunction
142
143 function! lsp#internal#diagnostics#state#_disable_for_buffer(bufnr) abort
144     if getbufvar(a:bufnr, 'lsp_diagnostics_enabled', 1) != 0
145         call setbufvar(a:bufnr, 'lsp_diagnostics_enabled', 0)
146         call s:notify_diagnostics_update()
147     endif
148 endfunction
149
150 function! lsp#internal#diagnostics#state#_is_enabled_for_buffer(bufnr) abort
151     return getbufvar(a:bufnr, 'lsp_diagnostics_enabled', 1) == 1
152 endfunction
153
154 " Return dict with diagnostic counts for the specified buffer
155 " { 'error': 1, 'warning': 0, 'information': 0, 'hint': 0 }
156 function! lsp#internal#diagnostics#state#_get_diagnostics_count_for_buffer(bufnr) abort
157     let l:counts = {
158         \ 'error': 0,
159         \ 'warning': 0,
160         \ 'information': 0,
161         \ 'hint': 0,
162         \ }
163     if lsp#internal#diagnostics#state#_is_enabled_for_buffer(a:bufnr)
164         let l:uri = lsp#utils#get_buffer_uri(a:bufnr)
165         for [l:_, l:response] in items(lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri))
166             for l:diagnostic in lsp#utils#iteratable(l:response['params']['diagnostics'])
167                 let l:key = get(s:diagnostic_kinds, get(l:diagnostic, 'severity', 1) , 'error')
168                 let l:counts[l:key] += 1
169             endfor
170         endfor
171     end
172     return l:counts
173 endfunction