From 226cd713e7079f41baa0a07a63d672a2f6f5cad8 Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Wed, 28 Jun 2023 21:44:00 -0700 Subject: [PATCH] Add an option (showDiagWithSign) to enable/disable placing signs on lines with diagnostics. Add separate virtual text highlight groups for each type of diagnostic --- autoload/lsp/buffer.vim | 10 +++- autoload/lsp/diag.vim | 108 +++++++++++++++++++++++++------------ autoload/lsp/lspserver.vim | 3 +- autoload/lsp/options.vim | 2 + doc/lsp.txt | 53 ++++++++++++++++++ 5 files changed, 138 insertions(+), 38 deletions(-) diff --git a/autoload/lsp/buffer.vim b/autoload/lsp/buffer.vim index 4c22547..7c1b6c1 100644 --- a/autoload/lsp/buffer.vim +++ b/autoload/lsp/buffer.vim @@ -4,9 +4,13 @@ vim9script import './util.vim' -# Buffer number to LSP server map +# A buffer can have one or more attached language servers.  The +# "bufnrToServers" Dict contains the list of language servers attached to a +# buffer. The buffer number is the key for the "bufnrToServers" Dict.  The +# value is the List of attached language servers. var bufnrToServers: dict>> = {} +# Add "lspserver" to "bufnrToServers" map for buffer "bnr". export def BufLspServerSet(bnr: number, lspserver: dict) if !bufnrToServers->has_key(bnr) bufnrToServers[bnr] = [] @@ -15,6 +19,7 @@ export def BufLspServerSet(bnr: number, lspserver: dict) bufnrToServers[bnr]->add(lspserver) enddef +# Remove "lspserver" from "bufnrToServers" map for buffer "bnr". export def BufLspServerRemove(bnr: number, lspserver: dict) if !bufnrToServers->has_key(bnr) return @@ -70,7 +75,8 @@ export def BufLspServerGet(bnr: number, feature: string = null_string): dicthas_key(feature) - # If this happns it is a programming error, and should be fixed in the source code + # If this happns it is a programming error, and should be fixed in the + # source code :throw $'Error: ''{feature}'' is not a valid feature' endif diff --git a/autoload/lsp/diag.vim b/autoload/lsp/diag.vim index 05dd44e..3238d74 100644 --- a/autoload/lsp/diag.vim +++ b/autoload/lsp/diag.vim @@ -21,12 +21,14 @@ var diagsMap: dict> = {} # Initialize the signs and the text property type used for diagnostics. export def InitOnce() - # Signs used for LSP diagnostics - hlset([{name: 'LspDiagLine', default: true, linksto: 'DiffAdd'}]) - hlset([{name: 'LspDiagSignErrorText', default: true, linksto: 'ErrorMsg'}]) - hlset([{name: 'LspDiagSignWarningText', default: true, linksto: 'Search'}]) - hlset([{name: 'LspDiagSignInfoText', default: true, linksto: 'Pmenu'}]) - hlset([{name: 'LspDiagSignHintText', default: true, linksto: 'Question'}]) + # Signs and their highlight groups used for LSP diagnostics + hlset([ + {name: 'LspDiagLine', default: true, linksto: 'DiffAdd'}, + {name: 'LspDiagSignErrorText', default: true, linksto: 'ErrorMsg'}, + {name: 'LspDiagSignWarningText', default: true, linksto: 'Search'}, + {name: 'LspDiagSignInfoText', default: true, linksto: 'Pmenu'}, + {name: 'LspDiagSignHintText', default: true, linksto: 'Question'} + ]) sign_define([ { name: 'LspDiagError', @@ -54,34 +56,49 @@ export def InitOnce() } ]) - hlset([{name: 'LspDiagInlineError', default: true, linksto: 'SpellBad'}]) - hlset([{name: 'LspDiagInlineWarning', default: true, linksto: 'SpellCap'}]) - hlset([{name: 'LspDiagInlineInfo', default: true, linksto: 'SpellRare'}]) - hlset([{name: 'LspDiagInlineHint', default: true, linksto: 'SpellLocal'}]) + # Diag inline highlight groups and text property types + hlset([ + {name: 'LspDiagInlineError', default: true, linksto: 'SpellBad'}, + {name: 'LspDiagInlineWarning', default: true, linksto: 'SpellCap'}, + {name: 'LspDiagInlineInfo', default: true, linksto: 'SpellRare'}, + {name: 'LspDiagInlineHint', default: true, linksto: 'SpellLocal'} + ]) var override = &cursorline && &cursorlineopt =~ '\\|\\|\' prop_type_add('LspDiagInlineError', - { highlight: 'LspDiagInlineError', - priority: 10, - override: override }) + {highlight: 'LspDiagInlineError', + priority: 10, + override: override}) prop_type_add('LspDiagInlineWarning', - { highlight: 'LspDiagInlineWarning', - priority: 9, - override: override }) + {highlight: 'LspDiagInlineWarning', + priority: 9, + override: override}) prop_type_add('LspDiagInlineInfo', - { highlight: 'LspDiagInlineInfo', - priority: 8, - override: override }) + {highlight: 'LspDiagInlineInfo', + priority: 8, + override: override}) prop_type_add('LspDiagInlineHint', - { highlight: 'LspDiagInlineHint', - priority: 7, - override: override }) - - hlset([{name: 'LspDiagVirtualText', default: true, linksto: 'LineNr'}]) - prop_type_add('LspDiagVirtualText', {highlight: 'LspDiagVirtualText', - override: true}) + {highlight: 'LspDiagInlineHint', + priority: 7, + override: override}) + + # Diag virtual text highlight groups and text property types + hlset([ + {name: 'LspDiagVirtualTextError', default: true, linksto: 'SpellBad'}, + {name: 'LspDiagVirtualTextWarning', default: true, linksto: 'SpellCap'}, + {name: 'LspDiagVirtualTextInfo', default: true, linksto: 'SpellRare'}, + {name: 'LspDiagVirtualTextHint', default: true, linksto: 'SpellLocal'}, + ]) + prop_type_add('LspDiagVirtualTextError', + {highlight: 'LspDiagVirtualTextError', override: true}) + prop_type_add('LspDiagVirtualTextWarning', + {highlight: 'LspDiagVirtualTextWarning', override: true}) + prop_type_add('LspDiagVirtualTextInfo', + {highlight: 'LspDiagVirtualTextInfo', override: true}) + prop_type_add('LspDiagVirtualTextHint', + {highlight: 'LspDiagVirtualTextHint', override: true}) if opt.lspOptions.aleSupport autocmd_add([{group: 'LspAleCmds', event: 'User', pattern: 'ALEWantResults', cmd: 'AleHook(g:ale_want_results_buffer)'}]) @@ -128,6 +145,19 @@ def DiagSevToInlineHLName(severity: number): string return typeMap[severity - 1] enddef +def DiagSevToVirtualTextHLName(severity: number): string + var typeMap: list = [ + 'LspDiagVirtualTextError', + 'LspDiagVirtualTextWarning', + 'LspDiagVirtualTextInfo', + 'LspDiagVirtualTextHint' + ] + if severity > 4 + return 'LspDiagVirtualTextHint' + endif + return typeMap[severity - 1] +enddef + def DiagSevToSymbolText(severity: number): string var typeMap: list = [ opt.lspOptions.diagSignErrorText, @@ -143,12 +173,17 @@ enddef # Remove signs and text properties for diagnostics in buffer def RemoveDiagVisualsForBuffer(bnr: number) - # Remove all the existing diagnostic signs - sign_unplace('LSPDiag', {buffer: bnr}) + if opt.lspOptions.showDiagWithSign + # Remove all the existing diagnostic signs + sign_unplace('LSPDiag', {buffer: bnr}) + endif if opt.lspOptions.showDiagWithVirtualText # Remove all the existing virtual text - prop_remove({type: 'LspDiagVirtualText', bufnr: bnr, all: true}) + prop_remove({type: 'LspDiagVirtualTextError', bufnr: bnr, all: true}) + prop_remove({type: 'LspDiagVirtualTextWarning', bufnr: bnr, all: true}) + prop_remove({type: 'LspDiagVirtualTextInfo', bufnr: bnr, all: true}) + prop_remove({type: 'LspDiagVirtualTextHint', bufnr: bnr, all: true}) endif if opt.lspOptions.highlightDiagInline @@ -193,10 +228,11 @@ def DiagsRefresh(bnr: number) # TODO: prioritize most important severity if there are multiple diagnostics # from the same line var lnum = diag.range.start.line + 1 - signs->add({id: 0, buffer: bnr, group: 'LSPDiag', - lnum: lnum, - name: DiagSevToSignName(diag.severity), - priority: 10 - diag.severity}) + if opt.lspOptions.showDiagWithSign + signs->add({id: 0, buffer: bnr, group: 'LSPDiag', + lnum: lnum, name: DiagSevToSignName(diag.severity), + priority: 10 - diag.severity}) + endif try if opt.lspOptions.highlightDiagInline @@ -225,7 +261,7 @@ def DiagsRefresh(bnr: number) endif prop_add(lnum, 0, {bufnr: bnr, - type: 'LspDiagVirtualText', + type: DiagSevToVirtualTextHLName(diag.severity), text: $'{symbol} {diag.message}', text_align: diag_align, text_wrap: diag_wrap, @@ -237,7 +273,9 @@ def DiagsRefresh(bnr: number) endtry endfor - signs->sign_placelist() + if opt.lspOptions.showDiagWithSign + signs->sign_placelist() + endif enddef # Sends diagnostics to Ale diff --git a/autoload/lsp/lspserver.vim b/autoload/lsp/lspserver.vim index 1dc4a36..e5cb731 100644 --- a/autoload/lsp/lspserver.vim +++ b/autoload/lsp/lspserver.vim @@ -837,13 +837,14 @@ def SwitchSourceHeader(lspserver: dict) param.uri = util.LspFileToUri(@%) var reply = lspserver.rpc('textDocument/switchSourceHeader', param) if reply->empty() || reply.result->empty() - util.WarnMsg('No alternate file found') + util.WarnMsg('Source/Header file is not found') return endif # process the 'textDocument/switchSourceHeader' reply from the LSP server # Result: URI | null var fname = util.LspUriToFile(reply.result) + # TODO: Add support for cmd modifiers if (&modified && !&hidden) || &buftype != '' # if the current buffer has unsaved changes and 'hidden' is not set, # or if the current buffer is a special buffer, then ask to save changes diff --git a/autoload/lsp/options.vim b/autoload/lsp/options.vim index be55f05..f372053 100644 --- a/autoload/lsp/options.vim +++ b/autoload/lsp/options.vim @@ -59,6 +59,8 @@ export var lspOptions: dict = { # Suppress diagnostic hover from appearing when the mouse is over the line # Show a diagnostic message on a status line showDiagOnStatusLine: false, + # Show a diagnostic messages using signs + showDiagWithSign: true, # Show a diagnostic messages with virtual text showDiagWithVirtualText: false, # enable inlay hints diff --git a/doc/lsp.txt b/doc/lsp.txt index 944204e..a75277d 100644 --- a/doc/lsp.txt +++ b/doc/lsp.txt @@ -439,22 +439,27 @@ aleSupport |Boolean| option. If true, diagnostics will be sent to Ale, instead of being displayed by this plugin. This is useful to combine all LSP and linter diagnostics. By default this is set to false. + *lsp-opt-autoComplete* autoComplete |Boolean| option. In insert mode, automatically complete the current symbol. Otherwise use omni-completion. By default this is set to true. + *lsp-opt-autoHighlight* autoHighlight |Boolean| option. In normal mode, automatically highlight all the occurrences of the symbol under the cursor. By default this is set to false. + *lsp-opt-autoHighlightDiags* autoHighlightDiags |Boolean| option. Automatically place signs on the lines with a diagnostic message from the language server. By default this is set to true. + *lsp-opt-autoPopulateDiags* autoPopulateDiags |Boolean| option. Automatically populate the location list with diagnostics from the language server. By default this is set to false. + *lsp-opt-completionMatcher* completionMatcher |String| option. Enable fuzzy or case insensitive completion for language servers that replies with a @@ -469,127 +474,163 @@ completionMatcher |String| option. Enable fuzzy or case insensitive case - case sensitive matching (default). fuzzy - fuzzy match completion items. icase - ignore case when matching items. + *lsp-opt-completionTextEdit* completionTextEdit |Boolean| option. If true, apply the LSP server supplied text edits after a completion. If a snippet plugin is going to apply the text edits, then set this to false to avoid applying the text edits twice. By default this is set to true. + *lsp-opt-completionKinds* completionKinds |Dictionary| option. See |lsp-custom-kinds| for all completion kind names. + *lsp-opt-customCompletionKinds* customCompletionKinds |Boolean| option. If you set this to true, you can set custom completion kinds using the option completionKinds. + *lsp-opt-diagSignErrorText* diagSignErrorText |String| option. Change diag sign text for errors By default 'E>' + *lsp-opt-diagSignHintText* diagSignHintText |String| option. Change diag sign text for hints By default 'H>', + *lsp-opt-diagSignInfoText* diagSignInfoText |String| option. Change diag sign text for info By default 'I>', + *lsp-opt-diagSignWarningText* diagSignWarningText |String| option. Change diag sign text for warnings By default 'W>', + *lsp-opt-diagVirtualTextAlign* diagVirtualTextAlign |String| option. Alignment of diagnostics messages if |lsp-opt-showDiagWithVirtualText| is set to true. Allowed values are 'above', 'below' or 'after' By default this is set to 'above', + *lsp-opt-echoSignature* 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. + *lsp-opt-hideDisabledCodeActions* hideDisabledCodeActions |Boolean| option. Hide all the disabled code actions. By default this is set to false. + *lsp-opt-highlightDiagInline* highlightDiagInline |Boolean| option. Highlight the diagnostics inline By default this is set to false. + *lsp-opt-hoverInPreview* hoverInPreview |Boolean| option. Show |:LspHover| in a preview window instead of a popup. By default this is set to false. + *lsp-opt-ignoreMissingServer* ignoreMissingServer |Boolean| option. Do not print a missing language server executable. By default this is set to false. + *lsp-opt-keepFocusInDiags* keepFocusInDiags |Boolean| option. Focus on the location list window after LspDiagShow. By default this is set to true. + *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* noNewlineInCompletion |Boolean| option. Suppress adding a new line on completion selection with . By default this is set to false. + *lsp-opt-outlineOnRight* outlineOnRight |Boolean| option. Open the outline window on the right side, by default this is false. + *lsp-opt-outlineWinSize* outlineWinSize |Number| option. The size of the symbol Outline window. By default this is set to 20. + *lsp-opt-showDiagInPopup* showDiagInPopup |Boolean| option. When using the |:LspDiagCurrent| command to display the diagnostic message for the current line, use a popup window to display the message instead of echoing in the status area. By default this is set to true. + *lsp-opt-showDiagOnStatusLine* showDiagOnStatusLine |Boolean| option. Show a diagnostic message on a status line. By default this is set to false. + + *lsp-opt-showDiagWithSign* +showDiagWithSign |Boolean| option. Place a sign on lines with + diagnostics. By default this is set to true. The + "autoHighlightDiags" option should be set to true. + *lsp-opt-showDiagWithVirtualText* showDiagWithVirtualText |Boolean| option. Show diagnostic message text from 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. + *lsp-opt-showInlayHints* showInlayHints |Boolean| option. Show inlay hints from the language server. By default this is set to false. The inlay hint text is displayed as a virtual text. Needs Vim version 9.0.0178 or later. + *lsp-opt-showSignature* showSignature |Boolean| option. In insert mode, automatically show the current symbol signature in a popup. By default this is set to true. + *lsp-opt-snippetSupport* snippetSupport |Boolean| option. Enable snippet completion support. Need a snippet completion plugin like vim-vsnip. By default this is set to false. + *lsp-opt-ultisnipsSupport* ultisnipsSupport |Boolean| option. Enable SirVer/ultisnips support. Need a snippet completion plugin SirVer/ultisnips. By default this is set to false. + *lsp-opt-vssnipSupport* vsnipSupport |Boolean| option. Enable hrsh7th/vim-vsnip support. Need snippet completion plugins hrsh7th/vim-vsnip and hrsh7th/vim-vsnip-integ. Make sure ultisnipsSupport is set to false before enabling this. By default this option is set to false. + *lsp-opt-usePopupInCodeAction* usePopupInCodeAction |Boolean| option. When using the |:LspCodeAction| command to display the code action for the current line, use a popup menu instead of echoing. By default this is set to false. + *lsp-opt-useQuickfixForLocations* useQuickfixForLocations |Boolean| option. Show |:LspShowReferences| in a quickfix list instead of a location list. By default this is set to false. + *lsp-opt-useBufferCompletion* useBufferCompletion |Boolean| option. If enabled, the words from the current buffer are added to the auto completion list. By default this is set to false. + *lsp-opt-bufferCompletionTimeout* bufferCompletionTimeout |Number| option. Specifies how long (in milliseconds) to wait while processing current buffer for @@ -1383,6 +1424,18 @@ override them. *LspDiagVirtualText* Used to highlight diagnostic virtual text. By default, linked to the "LineNr" highlight group. +*LspDiagVirtualTextError* Used to highlight virtual text for error diags. + By default, linked to the "SpellBad" highlight + group. +*LspDiagVirtualTextHint* Used to highlight virtual text for hint + diags. By default, linked to the "SpellLocal" + highlight group. +*LspDiagVirtualTextInfo* Used to highlight virtual text for info + diags. By default, linked to the "SpellRare" + highlight group. +*LspDiagVirtualTextWarning* Used to highlight virtual text for warning + diags. By default, linked to the "SpellCap" + highlight group. *LspInlayHintsParam* Used to highlight inlay hints of kind "parameter". By default, linked to the "Label" highlight group. -- 2.48.1