diff --git a/autoload/lsp/internal/diagnostics/virtual_text.vim b/autoload/lsp/internal/diagnostics/virtual_text.vim index a343ea545..2ee2e7687 100644 --- a/autoload/lsp/internal/diagnostics/virtual_text.vim +++ b/autoload/lsp/internal/diagnostics/virtual_text.vim @@ -159,10 +159,13 @@ function! s:set_virtual_text(params) abort endfunction function! s:place_virtual_text(server, diagnostics_response, bufnr) abort + let l:line_props = {} + let l:linecount = s:Buffer.get_line_count(a:bufnr) for l:item in lsp#utils#iteratable(a:diagnostics_response['params']['diagnostics']) 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:severity = get(l:item, 'severity', 3) + let l:name = get(s:severity_sign_names_mapping, l:severity, 'LspError') let l:text = g:lsp_diagnostics_virtual_text_prefix . l:item['message'] " Some language servers report an unexpected EOF one line past the end @@ -179,9 +182,18 @@ function! s:place_virtual_text(server, diagnostics_response, bufnr) abort " 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 <= l:linecount + if g:lsp_diagnostics_virtual_text_tidy && has_key(l:line_props, l:line) + " Replace the existing virtual text with the one that has higher severity + if l:severity <= l:line_props[l:line]['severity'] + call prop_remove({'id': l:line_props[l:line]['prop_id']}, l:line) + else + continue + endif + endif + let l:type = 'vim_lsp_' . l:name . '_virtual_text' call prop_remove({'all': v:true, 'type': l:type, 'bufnr': a:bufnr}, l:line) - call prop_add( + let l:prop_id = prop_add( \ l:line, 0, \ { \ 'type': l:type, 'text': l:text, 'bufnr': a:bufnr, @@ -189,6 +201,11 @@ function! s:place_virtual_text(server, diagnostics_response, bufnr) abort \ 'text_padding_left': g:lsp_diagnostics_virtual_text_padding_left, \ 'text_wrap': g:lsp_diagnostics_virtual_text_wrap, \ }) + + let l:line_props[l:line] = { + \ 'prop_id': l:prop_id, + \ 'severity': l:severity, + \ } endif endif endfor diff --git a/doc/vim-lsp.txt b/doc/vim-lsp.txt index bf5676ea9..40d1077c9 100644 --- a/doc/vim-lsp.txt +++ b/doc/vim-lsp.txt @@ -57,6 +57,8 @@ CONTENTS *vim-lsp-contents* |g:lsp_diagnostics_virtual_text_padding_left| g:lsp_diagnostics_virtual_text_wrap |g:lsp_diagnostics_virtual_text_wrap| + g:lsp_diagnostics_virtual_text_tidy + |g:lsp_diagnostics_virtual_text_tidy| g:lsp_document_code_action_signs_enabled |g:lsp_document_code_action_signs_enabled| g:lsp_document_code_action_signs_delay @@ -785,6 +787,20 @@ g:lsp_diagnostics_virtual_text_wrap *g:lsp_diagnostics_virtual_text_wrap* Example: > let g:lsp_diagnostics_virtual_text_wrap = "truncate" +g:lsp_diagnostics_virtual_text_tidy + *g:lsp_diagnostics_virtual_text_tidy* + Type: |Boolean| + Default: `0` + + Determines whether or not to show only the diagnostic virtual text + with the highest severity per line. Requires + |g:lsp_diagnostics_virtual_text_enabled|. + This prevents unintentional newlines in the view inserted by diagnostics + messages. + + Example: > + let g:lsp_diagnostics_virtual_text_tidy = 0 + g:lsp_document_code_action_signs_enabled *g:lsp_document_code_action_signs_enabled* Type: |Number| diff --git a/plugin/lsp.vim b/plugin/lsp.vim index 11a2b4428..c8460f350 100644 --- a/plugin/lsp.vim +++ b/plugin/lsp.vim @@ -41,6 +41,7 @@ let g:lsp_diagnostics_virtual_text_prefix = get(g:, 'lsp_diagnostics_virtual_tex let g:lsp_diagnostics_virtual_text_align = get(g:, 'lsp_diagnostics_virtual_text_align', 'below') let g:lsp_diagnostics_virtual_text_wrap = get(g:, 'lsp_diagnostics_virtual_text_wrap', 'wrap') let g:lsp_diagnostics_virtual_text_padding_left = get(g:, 'lsp_diagnostics_virtual_text_padding_left', 1) +let g:lsp_diagnostics_virtual_text_tidy = get(g:, 'lsp_diagnostics_virtual_text_tidy', 0) let g:lsp_document_code_action_signs_enabled = get(g:, 'lsp_document_code_action_signs_enabled', 1) let g:lsp_document_code_action_signs_delay = get(g:, 'lsp_document_code_action_signs_delay', 500)