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 " internal state for whether it is enabled or not to avoid multiple subscriptions
3 let s:namespace_id = '' " will be set when enabled
5 let s:severity_sign_names_mapping = {
12 if !hlexists('LspErrorHighlight')
13 highlight link LspErrorHighlight Error
16 if !hlexists('LspWarningHighlight')
17 highlight link LspWarningHighlight Todo
20 if !hlexists('LspInformationHighlight')
21 highlight link LspInformationHighlight Normal
24 if !hlexists('LspHintHighlight')
25 highlight link LspHintHighlight Normal
28 function! lsp#internal#diagnostics#highlights#_enable() abort
29 " don't even bother registering if the feature is disabled
30 if !lsp#utils#_has_highlights() | return | endif
31 if !g:lsp_diagnostics_highlights_enabled | return | endif
33 if s:enabled | return | endif
36 if empty(s:namespace_id)
38 let s:namespace_id = nvim_create_namespace('vim_lsp_diagnostics_highlights')
40 let s:namespace_id = 'vim_lsp_diagnostics_highlights'
41 for l:severity in keys(s:severity_sign_names_mapping)
42 let l:hl_group = s:severity_sign_names_mapping[l:severity] . 'Highlight'
43 call prop_type_add(s:get_prop_type_name(l:severity),
44 \ {'highlight': l:hl_group, 'combine': v:true, 'priority': lsp#internal#textprop#priority('diagnostics_highlight') })
49 let s:Dispose = lsp#callbag#pipe(
53 \ lsp#callbag#filter({x->has_key(x, 'server') && has_key(x, 'response')
54 \ && has_key(x['response'], 'method') && x['response']['method'] ==# '$/vimlsp/lsp_diagnostics_updated'
55 \ && !lsp#client#is_error(x['response'])}),
56 \ lsp#callbag#map({x->x['response']['params']}),
59 \ lsp#callbag#fromEvent(['InsertEnter', 'InsertLeave']),
60 \ lsp#callbag#filter({_->!g:lsp_diagnostics_highlights_insert_mode_enabled}),
61 \ lsp#callbag#map({_->{ 'uri': lsp#utils#get_buffer_uri() }}),
64 \ lsp#callbag#filter({_->g:lsp_diagnostics_highlights_enabled}),
65 \ lsp#callbag#debounceTime(g:lsp_diagnostics_highlights_delay),
66 \ lsp#callbag#tap({x->s:clear_highlights(x)}),
67 \ lsp#callbag#tap({x->s:set_highlights(x)}),
68 \ lsp#callbag#subscribe(),
72 function! lsp#internal#diagnostics#highlights#_disable() abort
73 if !s:enabled | return | endif
74 if exists('s:Dispose')
78 call s:clear_all_highlights()
82 function! s:get_prop_type_name(severity) abort
83 return s:namespace_id . '_' . get(s:severity_sign_names_mapping, a:severity, 'LspError')
86 function! s:clear_all_highlights() abort
87 for l:bufnr in range(1, bufnr('$'))
88 if bufexists(l:bufnr) && bufloaded(l:bufnr)
90 call nvim_buf_clear_namespace(l:bufnr, s:namespace_id, 0, -1)
92 for l:severity in keys(s:severity_sign_names_mapping)
94 " TODO: need to check for valid range before calling prop_add
95 " See https://github.com/prabirshrestha/vim-lsp/pull/721
96 silent! call prop_remove({
97 \ 'type': s:get_prop_type_name(l:severity),
101 call lsp#log('diagnostics', 'clear_all_highlights', 'prop_remove', v:exception, v:throwpoint)
109 function! s:clear_highlights(params) abort
110 " TODO: optimize by looking at params
111 call s:clear_all_highlights()
114 function! s:set_highlights(params) abort
115 " TODO: optimize by looking at params
116 if !g:lsp_diagnostics_highlights_insert_mode_enabled
117 if mode()[0] ==# 'i' | return | endif
120 for l:bufnr in range(1, bufnr('$'))
121 if lsp#internal#diagnostics#state#_is_enabled_for_buffer(l:bufnr) && bufexists(l:bufnr) && bufloaded(l:bufnr)
122 let l:uri = lsp#utils#get_buffer_uri(l:bufnr)
123 for [l:server, l:diagnostics_response] in items(lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri))
124 call s:place_highlights(l:server, l:diagnostics_response, l:bufnr)
130 function! s:place_highlights(server, diagnostics_response, bufnr) abort
131 " TODO: make diagnostics highlights same across vim and neovim
132 for l:item in lsp#utils#iteratable(a:diagnostics_response['params']['diagnostics'])
133 let [l:start_line, l:start_col] = lsp#utils#position#lsp_to_vim(a:bufnr, l:item['range']['start'])
134 let [l:end_line, l:end_col] = lsp#utils#position#lsp_to_vim(a:bufnr, l:item['range']['end'])
135 let l:severity = get(l:item, 'severity', 3)
136 let l:hl_group = get(s:severity_sign_names_mapping, l:severity, 'LspError') . 'Highlight'
138 for l:line in range(l:start_line, l:end_line)
139 if l:line == l:start_line
140 let l:highlight_start_col = l:start_col
142 let l:highlight_start_col = 1
145 if l:line == l:end_line
146 let l:highlight_end_col = l:end_col
148 " neovim treats -1 as end of line, special handle it later
149 " when calling nvim_buf_add_higlight
150 let l:highlight_end_col = -1
153 if l:start_line == l:end_line && l:highlight_start_col == l:highlight_end_col
154 " higlighting same start col and end col on same line
155 " doesn't work so use -1 for start col
156 let l:highlight_start_col -= 1
157 if l:highlight_start_col <= 0
158 let l:highlight_start_col = 1
162 call nvim_buf_add_highlight(a:bufnr, s:namespace_id, l:hl_group,
163 \ l:line - 1, l:highlight_start_col - 1, l:highlight_end_col == -1 ? -1 : l:highlight_end_col - 1)
166 if l:start_line == l:end_line
168 " TODO: need to check for valid range before calling prop_add
169 " See https://github.com/prabirshrestha/vim-lsp/pull/721
170 silent! call prop_add(l:start_line, l:start_col, {
171 \ 'end_col': l:end_col,
173 \ 'type': s:get_prop_type_name(l:severity),
176 call lsp#log('diagnostics', 'place_highlights', 'prop_add', v:exception, v:throwpoint)
179 for l:line in range(l:start_line, l:end_line)
180 if l:line == l:start_line
181 let l:highlight_start_col = l:start_col
183 let l:highlight_start_col = 1
186 if l:line == l:end_line
187 let l:highlight_end_col = l:end_col
189 if has('patch-9.0.0916')
190 let l:highlight_end_col = strlen(getbufoneline(a:bufnr, l:line)) + 1
192 let l:highlight_end_col = strlen(getbufline(a:bufnr, l:line)[0]) + 1
197 " TODO: need to check for valid range before calling prop_add
198 " See https://github.com/prabirshrestha/vim-lsp/pull/721
199 silent! call prop_add(l:line, l:highlight_start_col, {
200 \ 'end_col': l:highlight_end_col,
202 \ 'type': s:get_prop_type_name(l:severity),
205 call lsp#log('diagnostics', 'place_highlights', 'prop_add', v:exception, v:throwpoint)