Add support for virtual text diagnostics in Vim9 (#1358)

* Fix virtual-text link in lsp_inlay_hints_enabled docs
* Add support for virtual text diagnostics in Vim9
This commit is contained in:
Björn Steinbrink
2022-12-20 04:23:29 +01:00
committed by GitHub
parent 0a8d2dfaed
commit ed2c818b1e
4 changed files with 79 additions and 24 deletions

View File

@@ -42,14 +42,23 @@ endif
function! lsp#internal#diagnostics#virtual_text#_enable() abort
" don't even bother registering if the feature is disabled
if !lsp#utils#_has_nvim_virtual_text() | return | endif
if !lsp#utils#_has_nvim_virtual_text() && !lsp#utils#_has_vim_virtual_text() | return | endif
if !g:lsp_diagnostics_virtual_text_enabled | return | endif
if s:enabled | return | endif
let s:enabled = 1
if empty(s:namespace_id)
let s:namespace_id = nvim_create_namespace('vim_lsp_diagnostic_virtual_text')
if has('nvim')
if empty(s:namespace_id)
let s:namespace_id = nvim_create_namespace('vim_lsp_diagnostic_virtual_text')
endif
else
if index(prop_type_list(), 'vim_lsp_LspError_virtual_text') ==# -1
call prop_type_add('vim_lsp_LspError_virtual_text', { 'highlight': 'LspErrorVirtualText' })
call prop_type_add('vim_lsp_LspWarning_virtual_text', { 'highlight': 'LspWarningVirtualText' })
call prop_type_add('vim_lsp_LspInformation_virtual_text', { 'highlight': 'LspInformationVirtualText' })
call prop_type_add('vim_lsp_LspHint_virtual_text', { 'highlight': 'LspHintVirtualText' })
endif
endif
let s:Dispose = lsp#callbag#pipe(
@@ -86,11 +95,24 @@ function! lsp#internal#diagnostics#virtual_text#_disable() abort
endfunction
function! s:clear_all_virtual_text() abort
for l:bufnr in nvim_list_bufs()
if bufexists(l:bufnr) && bufloaded(l:bufnr)
call nvim_buf_clear_namespace(l:bufnr, s:namespace_id, 0, -1)
endif
endfor
if has('nvim')
for l:bufnr in nvim_list_bufs()
if bufexists(l:bufnr) && bufloaded(l:bufnr)
call nvim_buf_clear_namespace(l:bufnr, s:namespace_id, 0, -1)
endif
endfor
else
let l:types = ['vim_lsp_LspError_virtual_text', 'vim_lsp_LspWarning_virtual_text', 'vim_lsp_LspInformation_virtual_text', 'vim_lsp_LspHint_virtual_text']
for l:bufnr in map(copy(getbufinfo()), 'v:val.bufnr')
if lsp#utils#_has_prop_remove_types()
call prop_remove({'types': l:types, 'bufnr': l:bufnr, 'all': v:true})
else
for l:type in l:types
call prop_remove({'type': l:type, 'bufnr': l:bufnr, 'all': v:true})
endfor
endif
endfor
endif
endfunction
" params => {
@@ -112,23 +134,50 @@ function! s:set_virtual_text(params) abort
if mode()[0] ==# 'i' | return | endif
endif
for l:bufnr in nvim_list_bufs()
if lsp#internal#diagnostics#state#_is_enabled_for_buffer(l:bufnr) && bufexists(l:bufnr) && bufloaded(l:bufnr)
let l:uri = lsp#utils#get_buffer_uri(l:bufnr)
for [l:server, l:diagnostics_response] in items(lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri))
call s:place_virtual_text(l:server, l:diagnostics_response, l:bufnr)
endfor
endif
endfor
if has('nvim')
for l:bufnr in nvim_list_bufs()
if lsp#internal#diagnostics#state#_is_enabled_for_buffer(l:bufnr) && bufexists(l:bufnr) && bufloaded(l:bufnr)
let l:uri = lsp#utils#get_buffer_uri(l:bufnr)
for [l:server, l:diagnostics_response] in items(lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri))
call s:place_virtual_text(l:server, l:diagnostics_response, l:bufnr)
endfor
endif
endfor
else
for l:bufnr in map(copy(getbufinfo()), 'v:val.bufnr')
if lsp#internal#diagnostics#state#_is_enabled_for_buffer(l:bufnr) && bufexists(l:bufnr) && bufloaded(l:bufnr)
let l:uri = lsp#utils#get_buffer_uri(l:bufnr)
for [l:server, l:diagnostics_response] in items(lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri))
call s:place_virtual_text(l:server, l:diagnostics_response, l:bufnr)
endfor
endif
endfor
endif
endfunction
function! s:place_virtual_text(server, diagnostics_response, bufnr) abort
for l:item in lsp#utils#iteratable(a:diagnostics_response['params']['diagnostics'])
" need to do -1 for virtual text
let l:line = lsp#utils#position#lsp_line_to_vim(a:bufnr, l:item['range']['start']) - 1
let l:line = lsp#utils#position#lsp_line_to_vim(a:bufnr, l:item['range']['start'])
let l:name = get(s:severity_sign_names_mapping, get(l:item, 'severity', 3), 'LspError')
let l:hl_name = l:name . 'VirtualText'
call nvim_buf_set_virtual_text(a:bufnr, s:namespace_id, l:line,
\ [[g:lsp_diagnostics_virtual_text_prefix . l:item['message'], l:hl_name]], {})
let l:text = g:lsp_diagnostics_virtual_text_prefix . l:item['message']
" Some language servers report an unexpected EOF one line past the end
if l:line == getbufinfo(a:bufnr)[0].linecount + 1
let l:line = l:line - 1
endif
if has('nvim')
let l:hl_name = l:name . 'VirtualText'
" need to do -1 for virtual text
call nvim_buf_set_virtual_text(a:bufnr, s:namespace_id, l:line - 1,
\ [[l:text, l:hl_name]], {})
else
" it's an error to add virtual text on lines that don't exist
" anymore due to async processing, just skip such diagnostics
if l:line <= getbufinfo(a:bufnr)[0].linecount
let l:type = 'vim_lsp_' . l:name . '_virtual_text'
call prop_add(l:line, 0, {'type': l:type, 'text': l:text, 'text_padding_left': 1, 'bufnr': a:bufnr})
endif
endif
endfor
endfunction

View File

@@ -29,6 +29,11 @@ function! lsp#utils#_has_vim_virtual_text() abort
return s:has_vim9textprops
endfunction
let s:has_prop_remove_types = exists('*prop_remove') && has('patch-9.0.0233')
function! lsp#utils#_has_prop_remove_types() abort
return s:has_prop_remove_types
endfunction
let s:has_higlights = has('nvim') ? lsp#utils#_has_nvim_buf_highlight() : lsp#utils#_has_textprops()
function! lsp#utils#_has_highlights() abort
return s:has_higlights

View File

@@ -657,7 +657,8 @@ g:lsp_diagnostics_virtual_text_enabled
Default: `1` for neovim 0.3+
Enables virtual text to be shown next to diagnostic errors. Requires
NeoVim with version 0.3 or newer and |g:lsp_diagnostics_enabled| set to `1`.
NeoVim with version 0.3 or newer or Vim with |virtual-text| and
patch 9.0.0178, and |g:lsp_diagnostics_enabled| set to `1`.
Virtual text uses the same highlight groups used for signs (eg LspErrorText),
but can be uniquely defined if you want to have different highlight groups
for signs and virtual text. To set unique virtual text highlighting, you
@@ -748,7 +749,7 @@ g:lsp_inlay_hints_enabled
Type: |Number|
Default: `0`
Enables inlay-hints. Requires Vim9 with |virtualtext|.
Enables inlay-hints. Requires Vim9 with |virtual-text|.
patch 9.0.0167 or newer.
Example: >

View File

@@ -32,7 +32,7 @@ let g:lsp_diagnostics_signs_information = get(g:, 'lsp_diagnostics_signs_informa
let g:lsp_diagnostics_signs_hint = get(g:, 'lsp_diagnostics_signs_hint', {})
let g:lsp_diagnostics_signs_priority = get(g:, 'lsp_diagnostics_signs_priority', 10)
let g:lsp_diagnostics_signs_priority_map = get(g:, 'lsp_diagnostics_signs_priority_map', {})
let g:lsp_diagnostics_virtual_text_enabled = get(g:, 'lsp_diagnostics_virtual_text_enabled', lsp#utils#_has_nvim_virtual_text())
let g:lsp_diagnostics_virtual_text_enabled = get(g:, 'lsp_diagnostics_virtual_text_enabled', lsp#utils#_has_nvim_virtual_text() || lsp#utils#_has_vim_virtual_text())
let g:lsp_diagnostics_virtual_text_insert_mode_enabled = get(g:, 'lsp_diagnostics_virtual_text_insert_mode_enabled', 0)
let g:lsp_diagnostics_virtual_text_delay = get(g:, 'lsp_diagnostics_virtual_text_delay', 500)
let g:lsp_diagnostics_virtual_text_prefix = get(g:, 'lsp_diagnostics_virtual_text_prefix', '')