From e9597fa4a66cae6747eb0595b21a79d6f34c8733 Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Thu, 13 Jul 2023 19:54:46 -0700 Subject: [PATCH] Diagnostic balloon doesn't work properly --- README.md | 5 ++-- autoload/lsp/diag.vim | 42 ++++++++++++++++++++++++++++++++- autoload/lsp/lsp.vim | 33 +------------------------- autoload/lsp/options.vim | 6 ++--- doc/lsp.txt | 51 ++++++++++++++++++++++------------------ test/clangd_tests.vim | 10 ++++---- 6 files changed, 82 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 106a2b2..d635f2a 100644 --- a/README.md +++ b/README.md @@ -124,16 +124,17 @@ call LspOptionsSet(#{ \ diagVirtualTextAlign: 'above', \ echoSignature: v:false, \ hideDisabledCodeActions: v:false, - \ highlightDiagInline: v:false, + \ highlightDiagInline: v:true, \ hoverInPreview: v:false, \ ignoreMissingServer: v:false, \ keepFocusInReferences: v:false, - \ noDiagHoverOnLine: v:true, \ noNewlineInCompletion: v:false, \ outlineOnRight: v:false, \ outlineWinSize: 20, + \ showDiagInBalloon: v:true, \ showDiagInPopup: v:true, \ showDiagOnStatusLine: v:false, + \ showDiagWithSign: v:true, \ showDiagWithVirtualText: v:false, \ showInlayHints: v:false, \ showSignature: v:true, diff --git a/autoload/lsp/diag.vim b/autoload/lsp/diag.vim index 480d1ec..116c90c 100644 --- a/autoload/lsp/diag.vim +++ b/autoload/lsp/diag.vim @@ -23,7 +23,7 @@ var diagsMap: dict> = {} export def InitOnce() # Signs and their highlight groups used for LSP diagnostics hlset([ - {name: 'LspDiagLine', default: true, linksto: 'DiffAdd'}, + {name: 'LspDiagLine', default: true, linksto: 'NONE'}, {name: 'LspDiagSignErrorText', default: true, linksto: 'ErrorMsg'}, {name: 'LspDiagSignWarningText', default: true, linksto: 'Search'}, {name: 'LspDiagSignInfoText', default: true, linksto: 'Pmenu'}, @@ -119,6 +119,14 @@ export def InitOnce() endif enddef +# Initialize the diagnostics features for the buffer 'bnr' +export def BufferInit(lspserver: dict, bnr: number) + if opt.lspOptions.showDiagInBalloon + :set ballooneval balloonevalterm + setbufvar(bnr, '&balloonexpr', 'g:LspDiagExpr()') + endif +enddef + # Sort diagnostics ascending based on line and character offset def SortDiags(diags: list>): list> return diags->sort((a, b) => { @@ -797,6 +805,38 @@ export def GetDiagsForBuf(bnr: number = bufnr()): list> return diagsMap[bnr].sortedDiagnostics->deepcopy() enddef +# Return the diagnostic text from the LSP server for the current mouse line to +# display in a balloon +def g:LspDiagExpr(): any + if !opt.lspOptions.showDiagInBalloon + return '' + endif + + var diagsInfo: list> = + GetDiagsByLine(v:beval_bufnr, v:beval_lnum) + if diagsInfo->empty() + # No diagnostic for the current cursor location + return '' + endif + var diagFound: dict = {} + for diag in diagsInfo + var r = diag.range + var startcol = util.GetLineByteFromPos(v:beval_bufnr, r.start) + 1 + var endcol = util.GetLineByteFromPos(v:beval_bufnr, r.end) + 1 + if v:beval_col >= startcol && v:beval_col < endcol + diagFound = diag + break + endif + endfor + if diagFound->empty() + # mouse is outside of the diagnostics range + return '' + endif + + # return the found diagnostic + return diagFound.message->split("\n") +enddef + # Track the current diagnostics auto highlight enabled/disabled state. Used # when the "autoHighlightDiags" option value is changed. var save_autoHighlightDiags = opt.lspOptions.autoHighlightDiags diff --git a/autoload/lsp/lsp.vim b/autoload/lsp/lsp.vim index a2e0e83..3b7f6c4 100644 --- a/autoload/lsp/lsp.vim +++ b/autoload/lsp/lsp.vim @@ -49,7 +49,6 @@ def LspInitOnce() signature.InitOnce() symbol.InitOnce() - :set ballooneval balloonevalterm lspInitializedOnce = true enddef @@ -353,35 +352,6 @@ def LspSavedFile() endfor enddef -# Return the diagnostic text from the LSP server for the current mouse line to -# display in a balloon -var lspDiagPopupID: number = 0 -var lspDiagPopupInfo: dict = {} -def g:LspDiagExpr(): any - # Display the diagnostic message only if the mouse is over the gutter for - # the signs. - if opt.lspOptions.noDiagHoverOnLine && v:beval_col >= 2 - return '' - endif - - var diagsInfo: list> = diag.GetDiagsByLine( - v:beval_bufnr, - v:beval_lnum - ) - if diagsInfo->empty() - # No diagnostic for the current cursor location - return '' - endif - - # Include all diagnostics from the current line in the message - var message: list = [] - for diag in diagsInfo - message->extend(diag.message->split("\n")) - endfor - - return message -enddef - # Called after leaving insert mode. Used to process diag messages (if any) def LspLeftInsertMode() if !exists('b:LspDiagsUpdatePending') @@ -445,8 +415,7 @@ def BufferInit(lspserverId: number, bnr: number): void AddBufLocalAutocmds(lspserver, bnr) - setbufvar(bnr, '&balloonexpr', 'g:LspDiagExpr()') - + diag.BufferInit(lspserver, bnr) signature.BufferInit(lspserver) inlayhints.BufferInit(lspserver, bnr) diff --git a/autoload/lsp/options.vim b/autoload/lsp/options.vim index 7e5c8d6..26a4785 100644 --- a/autoload/lsp/options.vim +++ b/autoload/lsp/options.vim @@ -37,7 +37,7 @@ export var lspOptions: dict = { # hide disabled code actions hideDisabledCodeActions: false, # Highlight diagnostics inline - highlightDiagInline: false, + highlightDiagInline: true, # Show the symbol documentation in the preview window instead of in a popup hoverInPreview: false, # Don't print message when a configured language server is missing. @@ -53,14 +53,14 @@ export var lspOptions: dict = { # Alignment of virtual diagnostic text, when showDiagWithVirtualText is true # Allowed values: 'above' | 'below' | 'after' (default is 'above') diagVirtualTextAlign: 'above', - # instead of the signature - noDiagHoverOnLine: true, # Suppress adding a new line on completion selection with noNewlineInCompletion: false, # Open outline window on right side outlineOnRight: false, # Outline window size outlineWinSize: 20, + # Show diagnostic text in a balloon when the mouse is over the diagnostic + showDiagInBalloon: true, # Make diagnostics show in a popup instead of echoing showDiagInPopup: true, # Suppress diagnostic hover from appearing when the mouse is over the line diff --git a/doc/lsp.txt b/doc/lsp.txt index 81be3a5..d63ddea 100644 --- a/doc/lsp.txt +++ b/doc/lsp.txt @@ -526,7 +526,7 @@ hideDisabledCodeActions |Boolean| option. Hide all the disabled code actions. *lsp-opt-highlightDiagInline* highlightDiagInline |Boolean| option. Highlight the diagnostics inline. - By default this is set to false. + By default this is set to true. *lsp-opt-hoverInPreview* hoverInPreview |Boolean| option. Show |:LspHover| in a preview window @@ -545,12 +545,6 @@ keepFocusInDiags |Boolean| option. Focus on the location list window *lsp-opt-keepFocusInReferences* keepFocusInReferences |Boolean| option. Focus on the location list window after LspShowReferences. - By default this is set to true. - - *lsp-opt-noDiagHoverOnLine* -noDiagHoverOnLine |Boolean| option. Suppress diagnostic hover from - appearing when the mouse is over the line instead of - the signature. By default this is set to true. *lsp-opt-noNewlineInCompletion* @@ -566,6 +560,17 @@ outlineOnRight |Boolean| option. Open the outline window on the outlineWinSize |Number| option. The size of the symbol Outline window. By default this is set to 20. + *lsp-opt-showDiagInBalloon* +showDiagInBalloon |Boolean| option. When the mouse is over a range of + text referenced by a diagnostic, display the + diagnostic text in a balloon. By default this is set + to true. In a GUI Vim, this needs the |+balloon_eval| + feature. In a terminal Vim, this needs the + |+balloon_eval_term| feature. In a terminal Vim, + 'mouse' option should be set to enable mouse. + If this option is set to true, then the 'ballooneval' + and 'balloonevalterm' options are set. + *lsp-opt-showDiagInPopup* showDiagInPopup |Boolean| option. When using the ":LspDiag current" command to display the diagnostic message for the @@ -1265,10 +1270,12 @@ current" command to display the entire diagnostic message from the language server for the current line. By default, the lines with a diagnostic message have a sign placed on them and -are highlighted. You can disable the automatic sign placement by setting the -"showDiagWithSign" option to v:false. By default, this option is set to -v:true. The line with the diagnostics is highlighted using the "LspDiagLine" -highlight group. +the range of text with the diagnostic is highlighted. You can disable the +automatic sign placement by setting the "showDiagWithSign" option to v:false. +By default, this option is set to v:true. You can disable the diagnostic text +highlighting by setting the "highlightDiagInline" option to v:false. The line +with the diagnostics is highlighted using the "LspDiagLine" highlight group. +By default this highlight group is not set. You can also display the diagnostic message as a virtual text near the location of the diagnostics by setting the "showDiagWithVirtualText" option to @@ -1279,7 +1286,7 @@ supported values are 'below' and 'after'. The range of text for a diagnostic message can be automatically highlighted by setting the "highlightDiagInline" option to v:true. By default, this option -is set to v:false. The text is highlighted using the "LspDiagInlineError" or +is set to v:true. The text is highlighted using the "LspDiagInlineError" or "LspDiagInlineHint" or "LspDiagInlineInfo" or "LspDiagInlineWarning" highlight group. @@ -1313,13 +1320,11 @@ true.  By default this option is set to false.  When new diagnostics are received for a buffer, if a location list with the diagnostics is already present, then it is refreshed with the new diagnostics. -When using GUI Vim or in a terminal Vim with 'ballooneval' option set, when -the mouse is moved over the diagnostic sign displayed in the sign column, then -the diagnostic message is displayed in a popup. By default, the diagnostic -message popup is not displayed when the mouse is moved over the text in the -line. To display the diagnostic message when hovering the mouse over the text -of the line, you can set the 'noDiagHoverOnLine' option to false. By -default, this option is set to true. +When using GUI Vim or in a terminal Vim with 'balloonevalterm' option set, +when the mouse is moved over the range of text referenced by a diagnostic, +then the diagnostic message is displayed in a popup. If the +"showDiagInBalloon" option is set to false, then the balloon popup will not be +displayed. By default, this option is set to true. To display the diagnostic message for the current line in the status area, you can set the 'showDiagOnStatusLine' option to true. By default, this option @@ -1437,9 +1442,9 @@ override them. By default, linked to the "SpellCap" highlight group. *LspDiagLine* Used to highlight a line with one or more - diagnostics. By default linked to the - "DiffAdd" highlight group. Use "NONE" to - disable. + diagnostics. By default linked to "NONE" + (cleared). You can link this to a highlight + group to highlight the line. *LspDiagSignErrorText* Used to highlight the sign text for error diags. By default linked to 'ErrorMsg'. *LspDiagSignHintText* Used to highlight the sign text for hint @@ -1487,7 +1492,7 @@ can use the following: > < or > - highlight link LspDiagLine NONE + highlight link LspDiagLine DiffAdd highlight link LspDiagVirtualText WarningMsg < ============================================================================== diff --git a/test/clangd_tests.vim b/test/clangd_tests.vim index 54c5ade..f1e585d 100644 --- a/test/clangd_tests.vim +++ b/test/clangd_tests.vim @@ -475,9 +475,9 @@ def g:Test_LspDiag_Multi() :redraw! # TODO: Waiting count doesn't include Warning, Info, and Hint diags if clangdVerMajor > 14 - g:WaitForServerFileLoad(3) + g:WaitForServerFileLoad(3) else - g:WaitForServerFileLoad(2) + g:WaitForServerFileLoad(2) endif :LspDiag show var qfl: list> = getloclist(0) @@ -485,9 +485,9 @@ def g:Test_LspDiag_Multi() assert_equal(bnr, qfl[0].bufnr) assert_equal(3, qfl->len()) if clangdVerMajor > 14 - assert_equal([1, 5, 'E'], [qfl[0].lnum, qfl[0].col, qfl[0].type]) + assert_equal([1, 5, 'E'], [qfl[0].lnum, qfl[0].col, qfl[0].type]) else - assert_equal([1, 5, 'W'], [qfl[0].lnum, qfl[0].col, qfl[0].type]) + assert_equal([1, 5, 'W'], [qfl[0].lnum, qfl[0].col, qfl[0].type]) endif assert_equal([1, 9, 'E'], [qfl[1].lnum, qfl[1].col, qfl[1].type]) assert_equal([2, 9, 'E'], [qfl[2].lnum, qfl[2].col, qfl[2].type]) @@ -1653,6 +1653,7 @@ def g:Test_DiagVirtualText() # Doesn't support virtual text return endif + g:LspOptionsSet({highlightDiagInline: false}) :silent! edit XdiagVirtualText.c sleep 200m var lines: list =<< trim END @@ -1677,6 +1678,7 @@ def g:Test_DiagVirtualText() p = prop_list(1, {end_lnum: line('$')}) assert_equal(0, p->len()) + g:LspOptionsSet({highlightDiagInline: true}) :%bw! enddef -- 2.48.1