]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Use sync rpc to the LSP server and simplify jumping to a symbol location
authorYegappan Lakshmanan <yegappan@yahoo.com>
Fri, 7 Oct 2022 16:00:47 +0000 (09:00 -0700)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Fri, 7 Oct 2022 16:00:47 +0000 (09:00 -0700)
autoload/lsp/handlers.vim
autoload/lsp/lspserver.vim
autoload/lsp/symbol.vim

index b6df9038b41ddaa80e7762e2fdc789e4d6fe1b6d..85f41eec452b4cf279759d3518d1e65c2d286819 100644 (file)
@@ -61,24 +61,6 @@ def ProcessShutdownReply(lspserver: dict<any>, req: dict<any>, reply: dict<any>)
   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<any>, req: dict<any>, reply: dict<any>): void
-  var location: dict<any>
-  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<any>, req: dict<any>, reply: dict<any>):
     {
       '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,
index 9b4b416b32d59b26b53c0df3a167ec5478b42f87..aa5545900c9ce2dc1e0121914290b15913f0633c 100644 (file)
@@ -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<any>, chan: channel, msg: any): void
@@ -424,38 +425,68 @@ def GetCompletion(lspserver: dict<any>, 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<any>, 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<any>
+  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<any>, 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<any>)
-  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<any>, 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<any>, 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<any>, 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<any>)
+  var req = lspserver.createRequest('textDocument/switchSourceHeader')
+  req.params->extend({uri: util.LspFileToUri(@%)})
   lspserver.sendMessage(req)
 
   lspserver.waitForResponse(req)
index 765714a25602e637d1894d7e544b0bd46a92482e..8e46d27da461acc520408f0fadecbc7d06f279de 100644 (file)
@@ -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<any>, location: dict<any>, 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<any> = gettagstack()
-      if tagstack.length > 0
-        settagstack(winnr(), {curidx: tagstack.length}, 't')
-      endif
-    endif
-    lspserver.peekSymbol = false
-    return
-  endif
-
+export def GotoSymbol(lspserver: dict<any>, location: dict<any>, 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<any>, location: dict<any>, type: string)
                        location.range.start.character + 1)
   endif
   redraw!
-  lspserver.peekSymbol = false
 enddef
 
 # vim: shiftwidth=2 softtabstop=2