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
4 let s:severity_sign_names_mapping = {
11 if !hlexists('LspErrorVirtualText')
12 if !hlexists('LspErrorText')
13 highlight link LspErrorVirtualText Error
15 highlight link LspErrorVirtualText LspErrorText
19 if !hlexists('LspWarningVirtualText')
20 if !hlexists('LspWarningText')
21 highlight link LspWarningVirtualText Todo
23 highlight link LspWarningVirtualText LspWarningText
27 if !hlexists('LspInformationVirtualText')
28 if !hlexists('LspInformationText')
29 highlight link LspInformationVirtualText Normal
31 highlight link LspInformationVirtualText LspInformationText
35 if !hlexists('LspHintVirtualText')
36 if !hlexists('LspHintText')
37 highlight link LspHintVirtualText Normal
39 highlight link LspHintVirtualText LspHintText
44 let s:Buffer = vital#lsp#import('VS.Vim.Buffer')
46 function! lsp#internal#diagnostics#virtual_text#_enable() abort
47 " don't even bother registering if the feature is disabled
48 if !lsp#utils#_has_nvim_virtual_text() && !lsp#utils#_has_vim_virtual_text() | return | endif
49 if !g:lsp_diagnostics_virtual_text_enabled | return | endif
51 if s:enabled | return | endif
55 if empty(s:namespace_id)
56 let s:namespace_id = nvim_create_namespace('vim_lsp_diagnostic_virtual_text')
59 if index(prop_type_list(), 'vim_lsp_LspError_virtual_text') ==# -1
60 call prop_type_add('vim_lsp_LspError_virtual_text', { 'highlight': 'LspErrorVirtualText' })
61 call prop_type_add('vim_lsp_LspWarning_virtual_text', { 'highlight': 'LspWarningVirtualText' })
62 call prop_type_add('vim_lsp_LspInformation_virtual_text', { 'highlight': 'LspInformationVirtualText' })
63 call prop_type_add('vim_lsp_LspHint_virtual_text', { 'highlight': 'LspHintVirtualText' })
67 let s:Dispose = lsp#callbag#pipe(
71 \ lsp#callbag#filter({x->has_key(x, 'server') && has_key(x, 'response')
72 \ && has_key(x['response'], 'method') && x['response']['method'] ==# '$/vimlsp/lsp_diagnostics_updated'
73 \ && !lsp#client#is_error(x['response'])}),
74 \ lsp#callbag#map({x->x['response']['params']}),
77 \ lsp#callbag#fromEvent(['InsertEnter', 'InsertLeave']),
78 \ lsp#callbag#filter({_->!g:lsp_diagnostics_virtual_text_insert_mode_enabled}),
79 \ lsp#callbag#map({_->{ 'uri': lsp#utils#get_buffer_uri() }}),
82 \ lsp#callbag#filter({_->g:lsp_diagnostics_virtual_text_enabled}),
83 \ lsp#callbag#debounceTime(g:lsp_diagnostics_virtual_text_delay),
84 \ lsp#callbag#tap({x->s:clear_virtual_text(x)}),
85 \ lsp#callbag#tap({x->s:set_virtual_text(x)}),
86 \ lsp#callbag#subscribe(),
90 function! lsp#internal#diagnostics#virtual_text#_disable() abort
91 if !s:enabled | return | endif
92 if exists('s:Dispose')
96 call s:clear_all_virtual_text()
100 function! s:clear_all_virtual_text() abort
102 for l:bufnr in nvim_list_bufs()
103 if bufexists(l:bufnr) && bufloaded(l:bufnr)
104 call nvim_buf_clear_namespace(l:bufnr, s:namespace_id, 0, -1)
108 let l:types = ['vim_lsp_LspError_virtual_text', 'vim_lsp_LspWarning_virtual_text', 'vim_lsp_LspInformation_virtual_text', 'vim_lsp_LspHint_virtual_text']
109 for l:bufnr in map(copy(getbufinfo()), 'v:val.bufnr')
110 if lsp#utils#_has_prop_remove_types()
111 call prop_remove({'types': l:types, 'bufnr': l:bufnr, 'all': v:true})
113 for l:type in l:types
114 call prop_remove({'type': l:type, 'bufnr': l:bufnr, 'all': v:true})
122 " server: '' " optional
125 function! s:clear_virtual_text(params) abort
126 " TODO: optimize by looking at params
127 call s:clear_all_virtual_text()
131 " server: '' " optional
134 function! s:set_virtual_text(params) abort
135 " TODO: optimize by looking at params
136 if !g:lsp_diagnostics_virtual_text_insert_mode_enabled
137 if mode()[0] ==# 'i' | return | endif
141 for l:bufnr in nvim_list_bufs()
142 if lsp#internal#diagnostics#state#_is_enabled_for_buffer(l:bufnr) && bufexists(l:bufnr) && bufloaded(l:bufnr)
143 let l:uri = lsp#utils#get_buffer_uri(l:bufnr)
144 for [l:server, l:diagnostics_response] in items(lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri))
145 call s:place_virtual_text(l:server, l:diagnostics_response, l:bufnr)
150 for l:bufnr in map(copy(getbufinfo()), 'v:val.bufnr')
151 if lsp#internal#diagnostics#state#_is_enabled_for_buffer(l:bufnr) && bufexists(l:bufnr) && bufloaded(l:bufnr)
152 let l:uri = lsp#utils#get_buffer_uri(l:bufnr)
153 for [l:server, l:diagnostics_response] in items(lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri))
154 call s:place_virtual_text(l:server, l:diagnostics_response, l:bufnr)
161 function! s:place_virtual_text(server, diagnostics_response, bufnr) abort
162 let l:linecount = s:Buffer.get_line_count(a:bufnr)
163 for l:item in lsp#utils#iteratable(a:diagnostics_response['params']['diagnostics'])
164 let l:line = lsp#utils#position#lsp_line_to_vim(a:bufnr, l:item['range']['start'])
165 let l:name = get(s:severity_sign_names_mapping, get(l:item, 'severity', 3), 'LspError')
166 let l:text = g:lsp_diagnostics_virtual_text_prefix . l:item['message']
168 " Some language servers report an unexpected EOF one line past the end
169 if l:line == l:linecount + 1
170 let l:line = l:line - 1
174 let l:hl_name = l:name . 'VirtualText'
175 " need to do -1 for virtual text
176 call nvim_buf_set_virtual_text(a:bufnr, s:namespace_id, l:line - 1,
177 \ [[l:text, l:hl_name]], {})
179 " it's an error to add virtual text on lines that don't exist
180 " anymore due to async processing, just skip such diagnostics
181 if l:line <= l:linecount
182 let l:type = 'vim_lsp_' . l:name . '_virtual_text'
183 call prop_remove({'all': v:true, 'type': l:type, 'bufnr': a:bufnr}, l:line)
187 \ 'type': l:type, 'text': l:text, 'bufnr': a:bufnr,
188 \ 'text_align': g:lsp_diagnostics_virtual_text_align,
189 \ 'text_padding_left': g:lsp_diagnostics_virtual_text_padding_left,
190 \ 'text_wrap': g:lsp_diagnostics_virtual_text_wrap,