From: Yegappan Lakshmanan Date: Fri, 7 Oct 2022 16:00:47 +0000 (-0700) Subject: Use sync rpc to the LSP server and simplify jumping to a symbol location X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=3411739b066548f5785627a7861ae5bfc324a68a;p=vim-lsp.git Use sync rpc to the LSP server and simplify jumping to a symbol location --- diff --git a/autoload/lsp/handlers.vim b/autoload/lsp/handlers.vim index b6df903..85f41ee 100644 --- a/autoload/lsp/handlers.vim +++ b/autoload/lsp/handlers.vim @@ -61,24 +61,6 @@ def ProcessShutdownReply(lspserver: dict, req: dict, reply: dict) return enddef -# process the 'textDocument/definition' / 'textDocument/declaration' / -# 'textDocument/typeDefinition' and 'textDocument/implementation' replies from -# the LSP server -# Result: Location | Location[] | LocationLink[] | null -def ProcessDefDeclReply(lspserver: dict, req: dict, reply: dict): void - var location: dict - if reply.result->empty() - return - endif - if reply.result->type() == v:t_list - location = reply.result[0] - else - location = reply.result - endif - - symbol.GotoSymbol(lspserver, location, req.method) -enddef - # process the 'textDocument/switchSourceHeader' reply from the LSP server # Clangd specific extension # Result: URI | null @@ -657,11 +639,7 @@ export def ProcessReply(lspserver: dict, req: dict, reply: dict): { 'initialize': ProcessInitializeReply, 'shutdown': ProcessShutdownReply, - 'textDocument/definition': ProcessDefDeclReply, - 'textDocument/declaration': ProcessDefDeclReply, - 'textDocument/typeDefinition': ProcessDefDeclReply, 'textDocument/switchSourceHeader': ProcessSwitchHeaderReply, - 'textDocument/implementation': ProcessDefDeclReply, 'textDocument/signatureHelp': ProcessSignaturehelpReply, 'textDocument/completion': ProcessCompletionReply, 'textDocument/hover': ProcessHoverReply, diff --git a/autoload/lsp/lspserver.vim b/autoload/lsp/lspserver.vim index 9b4b416..aa55459 100644 --- a/autoload/lsp/lspserver.vim +++ b/autoload/lsp/lspserver.vim @@ -8,6 +8,7 @@ import './handlers.vim' import './util.vim' import './diag.vim' import './selection.vim' +import './symbol.vim' # LSP server standard output handler def Output_cb(lspserver: dict, chan: channel, msg: any): void @@ -424,38 +425,68 @@ def GetCompletion(lspserver: dict, triggerKind_arg: number): void endif enddef +# Jump to or peek a symbol location. +# +# Send 'msg' to a LSP server and process the reply. 'msg' is one of the +# following: +# textDocument/definition +# textDocument/declaration +# textDocument/typeDefinition +# textDocument/implementation +# +# Process the LSP server reply and jump to the symbol location. Before +# jumping to the symbol location, save the current cursor position in the tag +# stack. +# +# If 'peekSymbol' is true, then display the symbol location in the preview +# window but don't jump to the symbol location. +# +# Result: Location | Location[] | LocationLink[] | null +def GotoSymbolLoc(lspserver: dict, msg: string, peekSymbol: bool) + var resp = lspserver.rpc(msg, GetLspTextDocPosition()) + if resp->empty() || resp.result->empty() + var emsg: string + if msg ==# 'textDocument/declaration' + emsg = 'Error: symbol declaration is not found' + elseif msg ==# 'textDocument/typeDefinition' + emsg = 'Error: symbol type definition is not found' + elseif msg ==# 'textDocument/implementation' + emsg = 'Error: symbol implementation is not found' + else + emsg = 'Error: symbol definition is not found' + endif + + util.WarnMsg(emsg) + return + endif + + if !peekSymbol + util.PushCursorToTagStack() + endif + + var location: dict + if resp.result->type() == v:t_list + location = resp.result[0] + else + location = resp.result + endif + + symbol.GotoSymbol(lspserver, location, peekSymbol) +enddef + # Request: "textDocument/definition" # Param: DefinitionParams def GotoDefinition(lspserver: dict, peek: bool) # Check whether LSP server supports jumping to a definition if !lspserver.caps->has_key('definitionProvider') || !lspserver.caps.definitionProvider - util.ErrMsg("Error: LSP server does not support jumping to a definition") + util.ErrMsg("Error: Jumping to a symbol definition is not supported") return endif - if !peek - util.PushCursorToTagStack() - endif - lspserver.peekSymbol = peek - var req = lspserver.createRequest('textDocument/definition') # interface DefinitionParams # interface TextDocumentPositionParams - req.params->extend(GetLspTextDocPosition()) - lspserver.sendMessage(req) - - lspserver.waitForResponse(req) -enddef - -# Request: "textDocument/switchSourceHeader" -# Param: TextDocumentIdentifier -# Clangd specific extension -def SwitchSourceHeader(lspserver: dict) - var req = lspserver.createRequest('textDocument/switchSourceHeader') - req.params->extend({uri: util.LspFileToUri(@%)}) - lspserver.sendMessage(req) - - lspserver.waitForResponse(req) + GotoSymbolLoc(lspserver, 'textDocument/definition', peek) enddef # Request: "textDocument/declaration" @@ -464,23 +495,13 @@ def GotoDeclaration(lspserver: dict, peek: bool): void # Check whether LSP server supports jumping to a declaration if !lspserver.caps->has_key('declarationProvider') || !lspserver.caps.declarationProvider - util.ErrMsg("Error: LSP server does not support jumping to a declaration") + util.ErrMsg("Error: Jumping to a symbol declaration is not supported") return endif - if !peek - util.PushCursorToTagStack() - endif - lspserver.peekSymbol = peek - var req = lspserver.createRequest('textDocument/declaration') - # interface DeclarationParams # interface TextDocumentPositionParams - req.params->extend(GetLspTextDocPosition()) - - lspserver.sendMessage(req) - - lspserver.waitForResponse(req) + GotoSymbolLoc(lspserver, 'textDocument/declaration', peek) enddef # Request: "textDocument/typeDefinition" @@ -489,23 +510,13 @@ def GotoTypeDef(lspserver: dict, peek: bool): void # Check whether LSP server supports jumping to a type definition if !lspserver.caps->has_key('typeDefinitionProvider') || !lspserver.caps.typeDefinitionProvider - util.ErrMsg("Error: LSP server does not support jumping to a type definition") + util.ErrMsg("Error: Jumping to a symbol type definition is not supported") return endif - if !peek - util.PushCursorToTagStack() - endif - lspserver.peekSymbol = peek - var req = lspserver.createRequest('textDocument/typeDefinition') - # interface TypeDefinitionParams # interface TextDocumentPositionParams - req.params->extend(GetLspTextDocPosition()) - - lspserver.sendMessage(req) - - lspserver.waitForResponse(req) + GotoSymbolLoc(lspserver, 'textDocument/typeDefinition', peek) enddef # Request: "textDocument/implementation" @@ -514,20 +525,21 @@ def GotoImplementation(lspserver: dict, peek: bool): void # Check whether LSP server supports jumping to a implementation if !lspserver.caps->has_key('implementationProvider') || !lspserver.caps.implementationProvider - util.ErrMsg("Error: LSP server does not support jumping to an implementation") + util.ErrMsg("Error: Jumping to a symbol implementation is not supported") return endif - if !peek - util.PushCursorToTagStack() - endif - lspserver.peekSymbol = peek - var req = lspserver.createRequest('textDocument/implementation') - # interface ImplementationParams # interface TextDocumentPositionParams - req.params->extend(GetLspTextDocPosition()) + GotoSymbolLoc(lspserver, 'textDocument/implementation', peek) +enddef +# Request: "textDocument/switchSourceHeader" +# Param: TextDocumentIdentifier +# Clangd specific extension +def SwitchSourceHeader(lspserver: dict) + var req = lspserver.createRequest('textDocument/switchSourceHeader') + req.params->extend({uri: util.LspFileToUri(@%)}) lspserver.sendMessage(req) lspserver.waitForResponse(req) diff --git a/autoload/lsp/symbol.vim b/autoload/lsp/symbol.vim index 765714a..8e46d27 100644 --- a/autoload/lsp/symbol.vim +++ b/autoload/lsp/symbol.vim @@ -188,33 +188,9 @@ enddef # Jump to the definition, declaration or implementation of a symbol. # Also, used to peek at the definition, declaration or implementation of a # symbol. -export def GotoSymbol(lspserver: dict, location: dict, type: string) - if location->empty() - var msg: string - if type ==# 'textDocument/declaration' - msg = 'Error: declaration is not found' - elseif type ==# 'textDocument/typeDefinition' - msg = 'Error: type definition is not found' - elseif type ==# 'textDocument/implementation' - msg = 'Error: implementation is not found' - else - msg = 'Error: definition is not found' - endif - - util.WarnMsg(msg) - if !lspserver.peekSymbol - # pop the tag stack - var tagstack: dict = gettagstack() - if tagstack.length > 0 - settagstack(winnr(), {curidx: tagstack.length}, 't') - endif - endif - lspserver.peekSymbol = false - return - endif - +export def GotoSymbol(lspserver: dict, location: dict, peekSymbol: bool) var fname = util.LspUriToFile(location.uri) - if lspserver.peekSymbol + if peekSymbol # open the definition/declaration in the preview window and highlight the # matching symbol exe $'pedit {fname}' @@ -267,7 +243,6 @@ export def GotoSymbol(lspserver: dict, location: dict, type: string) location.range.start.character + 1) endif redraw! - lspserver.peekSymbol = false enddef # vim: shiftwidth=2 softtabstop=2