autoload/lsp/diag.vim | 69 +++++++++++++++++++++++++++++++++++------------------ autoload/lsp/options.vim | 9 +++++++++ doc/lsp.txt | 33 +++++++++++++++++++++++++-------- test/clangd_tests.vim | 39 ++++++++++++++++++++++++++++++++++++++- diff --git a/autoload/lsp/diag.vim b/autoload/lsp/diag.vim index 4661ca75a945cae179527d5bf536b16e181f91fc..d3a2b4ab63016e82617cb61992333154205575a9 100644 --- a/autoload/lsp/diag.vim +++ b/autoload/lsp/diag.vim @@ -10,14 +10,32 @@ # Initialize the signs and the text property type used for diagnostics. export def InitOnce() var lineHL: string = opt.lspOptions.diagLineHL # Signs used for LSP diagnostics - sign_define([{name: 'LspDiagError', text: 'E>', texthl: 'ErrorMsg', - linehl: lineHL}, - {name: 'LspDiagWarning', text: 'W>', texthl: 'Search', - linehl: lineHL}, - {name: 'LspDiagInfo', text: 'I>', texthl: 'Pmenu', - linehl: lineHL}, - {name: 'LspDiagHint', text: 'H>', texthl: 'Question', - linehl: lineHL}]) + sign_define([ + { + name: 'LspDiagError', + text: opt.lspOptions.diagSignErrorText, + texthl: opt.lspOptions.diagSignErrorTexthl, + linehl: lineHL + }, + { + name: 'LspDiagWarning', + text: opt.lspOptions.diagSignWarningText, + texthl: opt.lspOptions.diagSignWarningTexthl, + linehl: lineHL + }, + { + name: 'LspDiagInfo', + text: opt.lspOptions.diagSignInfoText, + texthl: opt.lspOptions.diagSignInfoTexthl, + linehl: lineHL + }, + { + name: 'LspDiagHint', + text: opt.lspOptions.diagSignHintText, + texthl: opt.lspOptions.diagSignHintTexthl, + linehl: lineHL + } + ]) if opt.lspOptions.highlightDiagInline if !hlexists('LspDiagInlineError') @@ -111,22 +129,27 @@ signs->add({id: 0, buffer: bnr, group: 'LSPDiag', lnum: lnum, name: DiagSevToSignName(diag.severity)}) - if opt.lspOptions.highlightDiagInline - prop_add(diag.range.start.line + 1, - util.GetLineByteFromPos(bnr, diag.range.start) + 1, - {end_lnum: diag.range.end.line + 1, - end_col: util.GetLineByteFromPos(bnr, diag.range.end) + 1, - bufnr: bnr, - type: DiagSevToInlineHLName(diag.severity)}) - endif + try + if opt.lspOptions.highlightDiagInline + prop_add(diag.range.start.line + 1, + util.GetLineByteFromPos(bnr, diag.range.start) + 1, + {end_lnum: diag.range.end.line + 1, + end_col: util.GetLineByteFromPos(bnr, diag.range.end) + 1, + bufnr: bnr, + type: DiagSevToInlineHLName(diag.severity)}) + endif - if opt.lspOptions.showDiagWithVirtualText - prop_add(lnum, 0, {bufnr: bnr, - type: 'LspDiagVirtualText', - text: $'┌─ {diag.message}', - text_align: 'above', - text_padding_left: diag.range.start.character}) - endif + if opt.lspOptions.showDiagWithVirtualText + prop_add(lnum, 0, {bufnr: bnr, + type: 'LspDiagVirtualText', + text: $'┌─ {diag.message}', + text_align: 'above', + text_padding_left: diag.range.start.character}) + endif + catch /E966\|E964/ # Invalid lnum | Invalid col + # Diagnostics arrive asynchronous and the document changed while they wore + # send. Ignore this as new once will arrive shortly. + endtry endfor signs->sign_placelist() diff --git a/autoload/lsp/options.vim b/autoload/lsp/options.vim index 09a76bef33da6adafa073efdcd965019196b2d68..2a779d0927b8469ea8b4ad631286d8fe4c3601e7 100644 --- a/autoload/lsp/options.vim +++ b/autoload/lsp/options.vim @@ -63,6 +63,15 @@ hideDisabledCodeActions: false, # icase | fuzzy | case match for language servers that replies with a full # list of completion items completionMatcher: 'case', + # diagnostics signs options + diagSignErrorText: 'E>', + diagSignErrorTexthl: 'ErrorMsg', + diagSignWarningText: 'W>', + diagSignWarningTexthl: 'Search', + diagSignInfoText: 'I>', + diagSignInfoTexthl: 'Pmenu', + diagSignHintText: 'H>', + diagSignHintTexthl: 'Question', } # set the LSP plugin options from the user provided option values diff --git a/doc/lsp.txt b/doc/lsp.txt index 09b19f66c2fbd211694b7659e950417064dec63e..433df4f98e76a6a58a969ad272acaeba9f653a6f 100644 --- a/doc/lsp.txt +++ b/doc/lsp.txt @@ -287,12 +287,6 @@ server. By default this is set to true. autoPopulateDiags |Boolean| option. Automatically populate the location list with diagnostics from the language server. By default this is set to false. -diagLineHL |String| option. The highlight group used for a line - with one or more diagnostics. By default uses - "DiffAdd". Use "NONE" to disable. -echoSignature |Boolean| option. In insert mode, echo the current - symbol signature instead of showing it in a popup. - By default this is set to false. completionMatcher |String| option. Enable fuzzy or case insensitive completion for language servers that replies with a full list of completion items. Some language servers @@ -306,6 +300,30 @@ This option accepts one of the following values: case - case sensitive matching (default). fuzzy - fuzzy match completion items. icase - ignore case when matching items. +diagLineHL |String| option. The highlight group used for a line + with one or more diagnostics. By default uses + "DiffAdd". Use "NONE" to disable. +diagSignErrorText |String| option. Change diag sign text for errors + By default 'E>' +diagSignErrorTexthl |String| option. Change diag sign highlight for errors + By default 'ErrorMsg', +diagSignWarningText |String| option. Change diag sign text for warnings + By default 'W>', +diagSignWarningTexthl |String| option. Change diag sign highlight for warnings + By default 'Search', +diagSignInfoText |String| option. Change diag sign text for info + By default 'I>', +diagSignInfoTexthl |String| option. Change diag sign text highlight info + By default 'Pmenu', +diagSignHintText |String| option. Change diag sign text for hints + By default 'H>', +diagSignHintTexthl |String| option. Change diag sign highlight for hints + By default 'Question', +diagVirtualTextHL |String| option. The highlight group used for a + diagnostics virtual text. By default uses "LineNr". +echoSignature |Boolean| option. In insert mode, echo the current + symbol signature instead of showing it in a popup. + By default this is set to false. hideDisabledCodeActions |Boolean| option. Hide all the disabled code actions. By default this is set to false. ignoreMissingServer |Boolean| option. Do not print a missing language @@ -339,8 +357,6 @@ the language server with virtual text. By default this is set to false. The "autoHighlightDiags" option should be set to true. Needs Vim version 9.0.1157 or later. -diagVirtualTextHL |String| option. The highlight group used for a - diagnostics virtual text. By default uses "LineNr". showSignature |Boolean| option. In insert mode, automatically show the current symbol signature in a popup. By default this is set to true. @@ -361,6 +377,7 @@ diagInlineInfoHL |String| option. The highlight group used for inline info highlight. By default uses "SpellRare" diagInlineHintHL |String| option. The highlight group used for inline hint highlight. By default uses "SpellLocal" + For example, to disable the automatic placement of signs for the LSP diagnostic messages, you can add the following line to your .vimrc file: > diff --git a/test/clangd_tests.vim b/test/clangd_tests.vim index d669f5c66d663ee99cf02ddf842bd2cdaa6a6ad7..5800158bbc72fb75bf44cb42b61bf410883c5c48 100644 --- a/test/clangd_tests.vim +++ b/test/clangd_tests.vim @@ -3,7 +3,7 @@ # Unit tests for Vim Language Server Protocol (LSP) clangd client source common.vim -var lspOpts = {autoComplete: false} +var lspOpts = {autoComplete: false, highlightDiagInline: true} g:LspOptionsSet(lspOpts) var lspServers = [{ @@ -348,6 +348,43 @@ output = execute('LspDiagCurrent')->split('\n') assert_match('Initializer element is not ', output[0]) endfor g:LspOptionsSet({showDiagInPopup: true}) + + bw! +enddef + +# Test for highlight diag inline +def g:Test_LspHighlightDiagInline() + :silent! edit Xtest.c + sleep 200m + setline(1, [ + 'int main()', + '{', + ' struct obj obj', + '', + ' return 1;', + '}', + ]) + + # TODO: Waiting count doesn't include Warning, Info, and Hint diags + g:WaitForDiags(2) + + var props = prop_list(1) + assert_equal(0, props->len()) + props = prop_list(2) + assert_equal(0, props->len()) + props = prop_list(3) + assert_equal(2, props->len()) + assert_equal([ + {'id': 0, 'col': 12, 'type_bufnr': 0, 'end': 1, 'type': 'LspDiagInlineInfo', 'length': 3, 'start': 1}, + {'id': 0, 'col': 16, 'type_bufnr': 0, 'end': 1, 'type': 'LspDiagInlineError', 'length': 3, 'start': 1} + ], props) + props = prop_list(4) + assert_equal(0, props->len()) + props = prop_list(5) + assert_equal(1, props->len()) + assert_equal([{'id': 0, 'col': 5, 'type_bufnr': 0, 'end': 1, 'type': 'LspDiagInlineError', 'length': 6, 'start': 1}], props) + props = prop_list(6) + assert_equal(0, props->len()) bw! enddef