From b2be23b2e8fa4549c0ae0e99a744db3ecad4dafb Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Tue, 4 Jul 2023 09:58:56 -0700 Subject: [PATCH] Dict key access optimizations --- autoload/lsp/completion.vim | 88 +++++++++++++++------------ autoload/lsp/diag.vim | 63 ++++++++++++-------- autoload/lsp/handlers.vim | 17 +++--- autoload/lsp/lspserver.vim | 115 +++++++++++++++++++++--------------- autoload/lsp/options.vim | 13 ++++ 5 files changed, 177 insertions(+), 119 deletions(-) diff --git a/autoload/lsp/completion.vim b/autoload/lsp/completion.vim index 6a2bdda..5e38296 100644 --- a/autoload/lsp/completion.vim +++ b/autoload/lsp/completion.vim @@ -90,9 +90,10 @@ def LspCompleteItemKindChar(kind: number): string var kindName = kindMap[kind] var kindValue = defaultKinds[kindName] - if opt.lspOptions.customCompletionKinds - && opt.lspOptions.completionKinds->has_key(kindName) - kindValue = opt.lspOptions.completionKinds[kindName] + var lspOpts = opt.lspOptions + if lspOpts.customCompletionKinds && + lspOpts.completionKinds->has_key(kindName) + kindValue = lspOpts.completionKinds[kindName] endif return kindValue @@ -134,7 +135,8 @@ def CompletionFromBuffer(items: list>) endif endfor # Check every 200 lines if timeout is exceeded - if timeout > 0 && linenr % 200 == 0 && start->reltime()->reltimefloat() * 1000 > timeout + if timeout > 0 && linenr % 200 == 0 && + start->reltime()->reltimefloat() * 1000 > timeout break endif linenr += 1 @@ -162,23 +164,25 @@ export def CompletionReply(lspserver: dict, cItems: any) lspserver.completeItemsIsIncomplete = cItems->get('isIncomplete', false) endif + var lspOpts = opt.lspOptions + # Get the keyword prefix before the current cursor column. var chcol = charcol('.') var starttext = chcol == 1 ? '' : getline('.')[ : chcol - 2] var [prefix, start_idx, end_idx] = starttext->matchstrpos('\k*$') - if opt.lspOptions.completionMatcher == 'icase' + if lspOpts.completionMatcherValue == opt.COMPLETIONMATCHER_ICASE prefix = prefix->tolower() endif var start_col = start_idx + 1 - if opt.lspOptions.ultisnipsSupport + if lspOpts.ultisnipsSupport snippet.CompletionUltiSnips(prefix, items) - elseif opt.lspOptions.vsnipSupport + elseif lspOpts.vsnipSupport snippet.CompletionVsnip(items) endif - if opt.lspOptions.useBufferCompletion + if lspOpts.useBufferCompletion CompletionFromBuffer(items) endif @@ -186,12 +190,13 @@ export def CompletionReply(lspserver: dict, cItems: any) for item in items var d: dict = {} - # TODO: Add proper support for item.textEdit.newText and item.textEdit.range - # Keep in mind that item.textEdit.range can start be way before the typed - # keyword. - if item->has_key('textEdit') && opt.lspOptions.completionMatcher != 'fuzzy' + # TODO: Add proper support for item.textEdit.newText and + # item.textEdit.range Keep in mind that item.textEdit.range can start be + # way before the typed keyword. + if item->has_key('textEdit') && + lspOpts.completionMatcherValue != opt.COMPLETIONMATCHER_FUZZY var start_charcol: number - if prefix != '' + if !prefix->empty() start_charcol = charidx(starttext, start_idx) + 1 else start_charcol = chcol @@ -215,22 +220,22 @@ export def CompletionReply(lspserver: dict, cItems: any) # snippet completion. Needs a snippet plugin to expand the snippet. # Remove all the snippet placeholders d.word = MakeValidWord(d.word) - elseif !lspserver.completeItemsIsIncomplete || opt.lspOptions.useBufferCompletion + elseif !lspserver.completeItemsIsIncomplete || lspOpts.useBufferCompletion # Filter items only when "isIncomplete" is set (otherwise server would # have done the filtering) or when buffer completion is enabled # plain text completion - if prefix != '' + if !prefix->empty() # If the completion item text doesn't start with the current (case # ignored) keyword prefix, skip it. var filterText: string = item->get('filterText', d.word) - if opt.lspOptions.completionMatcher == 'icase' + if lspOpts.completionMatcherValue == opt.COMPLETIONMATCHER_ICASE if filterText->tolower()->stridx(prefix) != 0 continue endif # If the completion item text doesn't fuzzy match with the current # keyword prefix, skip it. - elseif opt.lspOptions.completionMatcher == 'fuzzy' + elseif lspOpts.completionMatcherValue == opt.COMPLETIONMATCHER_FUZZY if matchfuzzy([filterText], prefix)->empty() continue endif @@ -247,7 +252,7 @@ export def CompletionReply(lspserver: dict, cItems: any) d.abbr = item.label d.dup = 1 - if opt.lspOptions.completionMatcher == 'icase' + if lspOpts.completionMatcherValue == opt.COMPLETIONMATCHER_ICASE d.icase = 1 endif @@ -260,18 +265,19 @@ export def CompletionReply(lspserver: dict, cItems: any) if lspserver.completionLazyDoc d.info = 'Lazy doc' else - if item->has_key('detail') && item.detail != '' + if item->has_key('detail') && !item.detail->empty() # Solve a issue where if a server send a detail field # with a "\n", on the menu will be everything joined with # a "^@" separating it. (example: clangd) d.menu = item.detail->split("\n")[0] endif if item->has_key('documentation') - if item.documentation->type() == v:t_string && item.documentation != '' - d.info = item.documentation - elseif item.documentation->type() == v:t_dict - && item.documentation.value->type() == v:t_string - d.info = item.documentation.value + var itemDoc = item.documentation + if itemDoc->type() == v:t_string && !itemDoc->empty() + d.info = itemDoc + elseif itemDoc->type() == v:t_dict + && itemDoc.value->type() == v:t_string + d.info = itemDoc.value endif endif endif @@ -286,13 +292,13 @@ export def CompletionReply(lspserver: dict, cItems: any) completeItems->add(d) endfor - if opt.lspOptions.completionMatcher != 'fuzzy' + if lspOpts.completionMatcherValue != opt.COMPLETIONMATCHER_FUZZY # Lexographical sort (case-insensitive). completeItems->sort((a, b) => a.score == b.score ? 0 : a.score >? b.score ? 1 : -1) endif - if opt.lspOptions.autoComplete && !lspserver.omniCompletePending + if lspOpts.autoComplete && !lspserver.omniCompletePending if completeItems->empty() # no matches return @@ -348,22 +354,23 @@ def ShowCompletionDocumentation(cItem: any) if !infoText->empty() infoText->extend(['- - -']) endif - if cItem.documentation->type() == v:t_dict + var cItemDoc = cItem.documentation + if cItemDoc->type() == v:t_dict # MarkupContent - if cItem.documentation.kind == 'plaintext' - infoText->extend(cItem.documentation.value->split("\n")) + if cItemDoc.kind == 'plaintext' + infoText->extend(cItemDoc.value->split("\n")) infoKind = 'text' - elseif cItem.documentation.kind == 'markdown' - infoText->extend(cItem.documentation.value->split("\n")) + elseif cItemDoc.kind == 'markdown' + infoText->extend(cItemDoc.value->split("\n")) infoKind = 'lspgfm' else - util.ErrMsg($'Unsupported documentation type ({cItem.documentation.kind})') + util.ErrMsg($'Unsupported documentation type ({cItemDoc.kind})') return endif - elseif cItem.documentation->type() == v:t_string - infoText->extend(cItem.documentation->split("\n")) + elseif cItemDoc->type() == v:t_string + infoText->extend(cItemDoc->split("\n")) else - util.ErrMsg($'Unsupported documentation ({cItem.documentation->string()})') + util.ErrMsg($'Unsupported documentation ({cItemDoc->string()})') return endif endif @@ -461,12 +468,14 @@ def g:LspOmniFunc(findstart: number, base: string): any return res endif - if opt.lspOptions.completionMatcher == 'fuzzy' + var lspOpts = opt.lspOptions + if lspOpts.completionMatcherValue == opt.COMPLETIONMATCHER_FUZZY return res->matchfuzzy(prefix, { key: 'word' }) endif - if opt.lspOptions.completionMatcher == 'icase' - return res->filter((i, v) => v.word->tolower()->stridx(prefix->tolower()) == 0) + if lspOpts.completionMatcherValue == opt.COMPLETIONMATCHER_ICASE + return res->filter((i, v) => + v.word->tolower()->stridx(prefix->tolower()) == 0) endif return res->filter((i, v) => v.word->stridx(prefix) == 0) @@ -595,7 +604,8 @@ export def BufferInit(lspserver: dict, bnr: number, ftype: string) else setbufvar(bnr, '&completeopt', 'menuone,popup,noinsert,noselect') endif - setbufvar(bnr, '&completepopup', 'width:80,highlight:Pmenu,align:item,border:off') + setbufvar(bnr, '&completepopup', + 'width:80,highlight:Pmenu,align:item,border:off') # in insert mode stops completion and inserts a if !opt.lspOptions.noNewlineInCompletion :inoremap pumvisible() ? "\\" : "\" diff --git a/autoload/lsp/diag.vim b/autoload/lsp/diag.vim index a892b74..81e9936 100644 --- a/autoload/lsp/diag.vim +++ b/autoload/lsp/diag.vim @@ -101,7 +101,14 @@ export def InitOnce() {highlight: 'LspDiagVirtualTextHint', override: true}) if opt.lspOptions.aleSupport - autocmd_add([{group: 'LspAleCmds', event: 'User', pattern: 'ALEWantResults', cmd: 'AleHook(g:ale_want_results_buffer)'}]) + autocmd_add([ + { + group: 'LspAleCmds', + event: 'User', + pattern: 'ALEWantResults', + cmd: 'AleHook(g:ale_want_results_buffer)' + } + ]) endif enddef @@ -161,26 +168,28 @@ def DiagSevToVirtualTextHLName(severity: number): string enddef def DiagSevToSymbolText(severity: number): string + var lspOpts = opt.lspOptions var typeMap: list = [ - opt.lspOptions.diagSignErrorText, - opt.lspOptions.diagSignWarningText, - opt.lspOptions.diagSignInfoText, - opt.lspOptions.diagSignHintText + lspOpts.diagSignErrorText, + lspOpts.diagSignWarningText, + lspOpts.diagSignInfoText, + lspOpts.diagSignHintText ] if severity > 4 - return opt.lspOptions.diagSignHintText + return lspOpts.diagSignHintText endif return typeMap[severity - 1] enddef # Remove signs and text properties for diagnostics in buffer def RemoveDiagVisualsForBuffer(bnr: number) - if opt.lspOptions.showDiagWithSign + var lspOpts = opt.lspOptions + if lspOpts.showDiagWithSign # Remove all the existing diagnostic signs sign_unplace('LSPDiag', {buffer: bnr}) endif - if opt.lspOptions.showDiagWithVirtualText + if lspOpts.showDiagWithVirtualText # Remove all the existing virtual text prop_remove({type: 'LspDiagVirtualTextError', bufnr: bnr, all: true}) prop_remove({type: 'LspDiagVirtualTextWarning', bufnr: bnr, all: true}) @@ -188,7 +197,7 @@ def RemoveDiagVisualsForBuffer(bnr: number) prop_remove({type: 'LspDiagVirtualTextHint', bufnr: bnr, all: true}) endif - if opt.lspOptions.highlightDiagInline + if lspOpts.highlightDiagInline # Remove all the existing virtual text prop_remove({type: 'LspDiagInlineError', bufnr: bnr, all: true}) prop_remove({type: 'LspDiagInlineWarning', bufnr: bnr, all: true}) @@ -213,12 +222,13 @@ def DiagsRefresh(bnr: number) var diag_align: string = 'above' var diag_wrap: string = 'truncate' var diag_symbol: string = '┌─' + var lspOpts = opt.lspOptions - if opt.lspOptions.diagVirtualTextAlign == 'below' + if lspOpts.diagVirtualTextAlign == 'below' diag_align = 'below' diag_wrap = 'truncate' diag_symbol = '└─' - elseif opt.lspOptions.diagVirtualTextAlign == 'after' + elseif lspOpts.diagVirtualTextAlign == 'after' diag_align = 'after' diag_wrap = 'wrap' diag_symbol = 'E>' @@ -227,19 +237,20 @@ def DiagsRefresh(bnr: number) var signs: list> = [] var diags: list> = diagsMap[bnr].sortedDiagnostics for diag in diags - # TODO: prioritize most important severity if there are multiple diagnostics - # from the same line - var d_start = diag.range.start - var d_end = diag.range.end + # TODO: prioritize most important severity if there are multiple + # diagnostics from the same line + var d_range = diag.range + var d_start = d_range.start + var d_end = d_range.end var lnum = d_start.line + 1 - if opt.lspOptions.showDiagWithSign + if lspOpts.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 + if lspOpts.highlightDiagInline prop_add(lnum, util.GetLineByteFromPos(bnr, d_start) + 1, {end_lnum: d_end.line + 1, end_col: util.GetLineByteFromPos(bnr, d_end) + 1, @@ -247,7 +258,7 @@ def DiagsRefresh(bnr: number) type: DiagSevToInlineHLName(diag.severity)}) endif - if opt.lspOptions.showDiagWithVirtualText + if lspOpts.showDiagWithVirtualText var padding: number var symbol: string = diag_symbol @@ -271,12 +282,12 @@ def DiagsRefresh(bnr: number) text_padding_left: padding}) 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. + # Diagnostics arrive asynchronous and the document changed while they + # wore send. Ignore this as new once will arrive shortly. endtry endfor - if opt.lspOptions.showDiagWithSign + if lspOpts.showDiagWithSign signs->sign_placelist() endif enddef @@ -311,10 +322,11 @@ enddef export def ProcessNewDiags(bnr: number) DiagsUpdateLocList(bnr) - if opt.lspOptions.aleSupport + var lspOpts = opt.lspOptions + if lspOpts.aleSupport SendAleDiags(bnr, -1) return - elseif !opt.lspOptions.autoHighlightDiags + elseif !lspOpts.autoHighlightDiags return endif @@ -492,8 +504,9 @@ def DiagsUpdateLocList(bnr: number, calledByCmd: bool = false): bool var diags = diagsMap[bnr].sortedDiagnostics for diag in diags - var d_start = diag.range.start - var d_end = diag.range.end + var d_range = diag.range + var d_start = d_range.start + var d_end = d_range.end text = diag.message->substitute("\n\\+", "\n", 'g') qflist->add({filename: fname, lnum: d_start.line + 1, diff --git a/autoload/lsp/handlers.vim b/autoload/lsp/handlers.vim index 428fdd4..d0dbfff 100644 --- a/autoload/lsp/handlers.vim +++ b/autoload/lsp/handlers.vim @@ -17,7 +17,8 @@ enddef # Notification: textDocument/publishDiagnostics # Param: PublishDiagnosticsParams def ProcessDiagNotif(lspserver: dict, reply: dict): void - diag.DiagNotification(lspserver, reply.params.uri, reply.params.diagnostics) + var params = reply.params + diag.DiagNotification(lspserver, params.uri, params.diagnostics) enddef # Convert LSP message type to a string @@ -34,18 +35,19 @@ enddef # Notification: window/showMessage # Param: ShowMessageParams def ProcessShowMsgNotif(lspserver: dict, reply: dict) - if reply.params.type >= 4 + var msgType = reply.params.type + if msgType >= 4 # ignore log messages from the LSP server (too chatty) # TODO: Add a configuration to control the message level that will be # displayed. Also store these messages and provide a command to display # them. return endif - if reply.params.type == 1 + if msgType == 1 util.ErrMsg($'Lsp({lspserver.name}) {reply.params.message}') - elseif reply.params.type == 2 + elseif msgType == 2 util.WarnMsg($'Lsp({lspserver.name}) {reply.params.message}') - elseif reply.params.type == 3 + elseif msgType == 3 util.InfoMsg($'Lsp({lspserver.name}) {reply.params.message}') endif enddef @@ -54,8 +56,9 @@ enddef # Notification: window/logMessage # Param: LogMessageParams def ProcessLogMsgNotif(lspserver: dict, reply: dict) - var mtype = LspMsgTypeToString(reply.params.type) - lspserver.addMessage(mtype, reply.params.message) + var params = reply.params + var mtype = LspMsgTypeToString(params.type) + lspserver.addMessage(mtype, params.message) enddef # process the log trace notification messages diff --git a/autoload/lsp/lspserver.vim b/autoload/lsp/lspserver.vim index 9d888c8..7097674 100644 --- a/autoload/lsp/lspserver.vim +++ b/autoload/lsp/lspserver.vim @@ -292,11 +292,12 @@ enddef # create a LSP server request message def CreateRequest(lspserver: dict, method: string): dict - var req = {} - req.jsonrpc = '2.0' - req.id = lspserver.nextReqID() - req.method = method - req.params = {} + var req = { + jsonrpc: '2.0', + id: lspserver.nextReqID(), + method: method, + params: {} + } # Save the request, so that the corresponding response can be processed lspserver.requests->extend({[req.id->string()]: req}) @@ -306,19 +307,20 @@ enddef # create a LSP server response message def CreateResponse(lspserver: dict, req_id: number): dict - var resp = {} - resp.jsonrpc = '2.0' - resp.id = req_id - + var resp = { + jsonrpc: '2.0', + id: req_id + } return resp enddef # create a LSP server notification message def CreateNotification(lspserver: dict, notif: string): dict - var req = {} - req.jsonrpc = '2.0' - req.method = notif - req.params = {} + var req = { + jsonrpc: '2.0', + method: notif, + params: {} + } return req enddef @@ -537,12 +539,14 @@ enddef def TextdocDidOpen(lspserver: dict, bnr: number, ftype: string): void # Notification: 'textDocument/didOpen' # Params: DidOpenTextDocumentParams - var tdi = {} - tdi.uri = util.LspBufnrToUri(bnr) - tdi.languageId = ftype - tdi.version = 1 - tdi.text = bnr->getbufline(1, '$')->join("\n") .. "\n" - var params = {textDocument: tdi} + var params = { + textDocument: { + uri: util.LspBufnrToUri(bnr), + languageId: ftype, + version: 1, + text: bnr->getbufline(1, '$')->join("\n") .. "\n" + } + } lspserver.sendNotification('textDocument/didOpen', params) enddef @@ -550,9 +554,11 @@ enddef def TextdocDidClose(lspserver: dict, bnr: number): void # Notification: 'textDocument/didClose' # Params: DidCloseTextDocumentParams - var tdid = {} - tdid.uri = util.LspBufnrToUri(bnr) - var params = {textDocument: tdid} + var params = { + textDocument: { + uri: util.LspBufnrToUri(bnr) + } + } lspserver.sendNotification('textDocument/didClose', params) enddef @@ -563,10 +569,6 @@ def TextdocDidChange(lspserver: dict, bnr: number, start: number, changes: list>): void # Notification: 'textDocument/didChange' # Params: DidChangeTextDocumentParams - var vtdid: dict = {} - vtdid.uri = util.LspBufnrToUri(bnr) - # Use Vim 'changedtick' as the LSP document version number - vtdid.version = bnr->getbufvar('changedtick') var changeset: list> @@ -607,7 +609,14 @@ def TextdocDidChange(lspserver: dict, bnr: number, start: number, # endfor changeset->add({text: bnr->getbufline(1, '$')->join("\n") .. "\n"}) - var params = {textDocument: vtdid, contentChanges: changeset} + var params = { + textDocument: { + uri: util.LspBufnrToUri(bnr), + # Use Vim 'changedtick' as the LSP document version number + version: bnr->getbufvar('changedtick') + }, + contentChanges: changeset + } lspserver.sendNotification('textDocument/didChange', params) enddef @@ -833,8 +842,9 @@ enddef # Param: TextDocumentIdentifier # Clangd specific extension def SwitchSourceHeader(lspserver: dict) - var param = {} - param.uri = util.LspFileToUri(@%) + var param = { + uri: util.LspFileToUri(@%) + } var reply = lspserver.rpc('textDocument/switchSourceHeader', param) if reply->empty() || reply.result->empty() util.WarnMsg('Source/Header file is not found') @@ -964,8 +974,9 @@ def DocHighlightReply(lspserver: dict, docHighlightReply: any, propName = 'LspTextRef' endif try - var docHL_start = docHL.range.start - var docHL_end = docHL.range.end + var docHL_range = docHL.range + var docHL_start = docHL_range.start + var docHL_end = docHL_range.end prop_add(docHL_start.line + 1, util.GetLineByteFromPos(bnr, docHL_start) + 1, {end_lnum: docHL_end.line + 1, @@ -1041,13 +1052,16 @@ def TextDocFormat(lspserver: dict, fname: string, rangeFormat: bool, # interface DocumentFormattingParams # interface TextDocumentIdentifier # interface FormattingOptions - var param = {} - param.textDocument = {uri: util.LspFileToUri(fname)} var fmtopts: dict = { tabSize: shiftwidth(), insertSpaces: &expandtab ? true : false, } - param.options = fmtopts + var param = { + textDocument: { + uri: util.LspFileToUri(fname) + }, + options: fmtopts + } if rangeFormat var r: dict> = { @@ -1124,11 +1138,12 @@ def IncomingCalls(lspserver: dict, fname: string) callhier.IncomingCalls(lspserver) enddef -def GetIncomingCalls(lspserver: dict, item: dict): any +def GetIncomingCalls(lspserver: dict, item_arg: dict): any # Request: "callHierarchy/incomingCalls" # Param: CallHierarchyIncomingCallsParams - var param = {} - param.item = item + var param = { + item: item_arg + } var reply = lspserver.rpc('callHierarchy/incomingCalls', param) if reply->empty() return null @@ -1136,7 +1151,7 @@ def GetIncomingCalls(lspserver: dict, item: dict): any if lspserver.needOffsetEncoding # Decode the position encoding in all the incoming call locations - var bnr = util.LspUriToBufnr(item.uri) + var bnr = util.LspUriToBufnr(item_arg.uri) reply.result->map((_, hierItem) => { lspserver.decodeRange(bnr, hierItem.from.range) return hierItem @@ -1157,11 +1172,12 @@ def OutgoingCalls(lspserver: dict, fname: string) callhier.OutgoingCalls(lspserver) enddef -def GetOutgoingCalls(lspserver: dict, item: dict): any +def GetOutgoingCalls(lspserver: dict, item_arg: dict): any # Request: "callHierarchy/outgoingCalls" # Param: CallHierarchyOutgoingCallsParams - var param = {} - param.item = item + var param = { + item: item_arg + } var reply = lspserver.rpc('callHierarchy/outgoingCalls', param) if reply->empty() return null @@ -1169,7 +1185,7 @@ def GetOutgoingCalls(lspserver: dict, item: dict): any if lspserver.needOffsetEncoding # Decode the position encoding in all the outgoing call locations - var bnr = util.LspUriToBufnr(item.uri) + var bnr = util.LspUriToBufnr(item_arg.uri) reply.result->map((_, hierItem) => { lspserver.decodeRange(bnr, hierItem.to.range) return hierItem @@ -1460,8 +1476,9 @@ def WorkspaceQuerySymbols(lspserver: dict, query: string, firstCall: bool, endif # Param: WorkspaceSymbolParams - var param = {} - param.query = query + var param = { + query: query + } var reply = lspserver.rpc('workspace/symbol', param) if reply->empty() || reply.result->empty() util.WarnMsg($'Symbol "{query}" is not found') @@ -1560,10 +1577,12 @@ def SelectionRange(lspserver: dict, fname: string) # interface SelectionRangeParams # interface TextDocumentIdentifier - var param = {} - param.textDocument = {} - param.textDocument.uri = util.LspFileToUri(fname) - param.positions = [lspserver.getPosition(false)] + var param = { + textDocument: { + uri: util.LspFileToUri(fname) + }, + positions: [lspserver.getPosition(false)] + } var reply = lspserver.rpc('textDocument/selectionRange', param) if reply->empty() || reply.result->empty() diff --git a/autoload/lsp/options.vim b/autoload/lsp/options.vim index f372053..b8fbb95 100644 --- a/autoload/lsp/options.vim +++ b/autoload/lsp/options.vim @@ -87,6 +87,10 @@ export var lspOptions: dict = { completionKinds: {} } +export const COMPLETIONMATCHER_CASE = 1 +export const COMPLETIONMATCHER_ICASE = 2 +export const COMPLETIONMATCHER_FUZZY = 3 + # set the LSP plugin options from the user provided option values export def OptionsSet(opts: dict) lspOptions->extend(opts) @@ -96,6 +100,15 @@ export def OptionsSet(opts: dict) if !has('patch-9.0.1157') lspOptions.showDiagWithVirtualText = false endif + + # For faster comparison, convert the 'completionMatcher' option value from a + # string to a number. + lspOptions.completionMatcherValue = COMPLETIONMATCHER_CASE + if lspOptions.completionMatcher == 'icase' + lspOptions.completionMatcherValue = COMPLETIONMATCHER_ICASE + elseif lspOptions.completionMatcher == 'fuzzy' + lspOptions.completionMatcherValue = COMPLETIONMATCHER_FUZZY + endif enddef # return a copy of the LSP plugin options -- 2.48.1