]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
:LspSymbolSeach command doesn't support command modifiers. When only one symbol is...
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sun, 18 Jun 2023 04:39:08 +0000 (21:39 -0700)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Sun, 18 Jun 2023 04:39:08 +0000 (21:39 -0700)
autoload/lsp/lsp.vim
autoload/lsp/lspserver.vim
autoload/lsp/symbol.vim
autoload/lsp/util.vim
doc/lsp.txt
plugin/lsp.vim
test/clangd_offsetencoding.vim
test/clangd_tests.vim

index a2d7bede2fd332cb434d4b52a07722cf93dd7dbe..730527a1bc906ed62ad4494ba6d57408143ea67f 100644 (file)
@@ -952,7 +952,7 @@ enddef
 
 # Perform a workspace wide symbol lookup
 # Uses LSP "workspace/symbol" request
-export def SymbolSearch(queryArg: string)
+export def SymbolSearch(queryArg: string, cmdmods: string)
   var lspserver: dict<any> = buf.CurbufGetServerChecked()
   if lspserver->empty()
     return
@@ -967,7 +967,7 @@ export def SymbolSearch(queryArg: string)
   endif
   :redraw!
 
-  lspserver.workspaceQuery(query)
+  lspserver.workspaceQuery(query, true, cmdmods)
 enddef
 
 # Display the list of workspace folders
index 03d89bd8414953d862576c75b501adfa8752a645..3ef58dce10aa1679dae1368642521eb15cdda0e0 100644 (file)
@@ -1433,7 +1433,7 @@ enddef
 # List project-wide symbols matching query string
 # Request: "workspace/symbol"
 # Param: WorkspaceSymbolParams
-def WorkspaceQuerySymbols(lspserver: dict<any>, query: string)
+def WorkspaceQuerySymbols(lspserver: dict<any>, query: string, firstCall: bool, cmdmods: string = '')
   # Check whether the LSP server supports listing workspace symbols
   if !lspserver.isWorkspaceSymbolProvider
     util.ErrMsg('LSP server does not support listing workspace symbols')
@@ -1449,7 +1449,24 @@ def WorkspaceQuerySymbols(lspserver: dict<any>, query: string)
     return
   endif
 
-  symbol.WorkspaceSymbolPopup(lspserver, query, reply.result)
+  var symInfo: list<dict<any>> = reply.result
+
+  symInfo->map((_, sym) => {
+      if sym->has_key('location')
+       lspserver.decodeLocation(sym.location)
+      endif
+      return sym
+    })
+
+  if firstCall && symInfo->len() == 1
+    # If there is only one symbol, then jump to the symbol location
+    var symLoc: dict<any> = symInfo[0]->get('location', {})
+    if !symLoc->empty()
+      symbol.GotoSymbol(lspserver, symLoc, false, cmdmods)
+    endif
+  else
+    symbol.WorkspaceSymbolPopup(lspserver, query, symInfo, cmdmods)
+  endif
 enddef
 
 # Add a workspace folder to the language server.
index 177c761a35bb26499fb74a00b27fd9c1ef90c86e..ae193877a398248f02c196fe4032716c39c2a9c3 100644 (file)
@@ -54,7 +54,7 @@ def FilterSymbols(lspserver: dict<any>, popupID: number, key: string): bool
     # Update the popup with the new list of symbol names
     popupID->popup_settext('')
     if query != ''
-      lspserver.workspaceQuery(query)
+      lspserver.workspaceQuery(query, false)
     else
       []->setwinvar(popupID, 'LspSymbolTable')
     endif
@@ -72,7 +72,7 @@ def FilterSymbols(lspserver: dict<any>, popupID: number, key: string): bool
 enddef
 
 # Jump to the location of a symbol selected in the popup menu
-def JumpToWorkspaceSymbol(popupID: number, result: number): void
+def JumpToWorkspaceSymbol(cmdmods: string, popupID: number, result: number): void
   # clear the message displayed at the command-line
   :echo ''
 
@@ -91,32 +91,40 @@ def JumpToWorkspaceSymbol(popupID: number, result: number): void
 
     # if the selected file is already present in a window, then jump to it
     var fname: string = symTbl[result - 1].file
-    var bufnum = fname->bufnr()
-    var winList: list<number> = bufnum->win_findbuf()
-    if winList->empty()
-      # Not present in any window
-      if &modified || &buftype != ''
-       # the current buffer is modified or is not a normal buffer, then open
-       # the file in a new window
-       exe $'split {symTbl[result - 1].file}'
+    var bnr = fname->bufnr()
+    if cmdmods->empty()
+      var winList: list<number> = bnr->win_findbuf()
+      if winList->empty()
+       # Not present in any window
+       if &modified || &buftype != ''
+         # the current buffer is modified or is not a normal buffer, then
+         # open the file in a new window
+         exe $'split {symTbl[result - 1].file}'
+       else
+         exe $'confirm edit {symTbl[result - 1].file}'
+       endif
       else
-       exe $'confirm edit {symTbl[result - 1].file}'
-      endif
-    else
-      if bufnr() != bufnum
-       var winID = fname->bufwinid()
-       if winID == -1
-         # not present in the current tab page
-         winID = winList[0]
+       # If the target buffer is opened in the curent window, then don't
+       # change the window.
+       if bufnr() != bnr
+         # If the target buffer is opened in a window in the current tab
+         # page, then use it.
+         var winID = fname->bufwinid()
+         if winID == -1
+           # not present in the current tab page.  Use the first window.
+           winID = winList[0]
+         endif
+         winID->win_gotoid()
        endif
-       winID->win_gotoid()
       endif
+    else
+      exe $'{cmdmods} split {symTbl[result - 1].file}'
     endif
     # Set the previous cursor location mark. Instead of using setpos(), m' is
     # used so that the current location is added to the jump list.
     :normal m'
     setcursorcharpos(symTbl[result - 1].pos.line + 1,
-                    util.GetCharIdxWithoutCompChar(bufnum,
+                    util.GetCharIdxWithoutCompChar(bnr,
                                                    symTbl[result - 1].pos) + 1)
   catch
     # ignore exceptions
@@ -124,7 +132,7 @@ def JumpToWorkspaceSymbol(popupID: number, result: number): void
 enddef
 
 # display a list of symbols from the workspace
-def ShowSymbolMenu(lspserver: dict<any>, query: string)
+def ShowSymbolMenu(lspserver: dict<any>, query: string, cmdmods: string)
   # Create the popup menu
   var lnum = &lines - &cmdheight - 2 - 10
   var popupAttr = {
@@ -141,7 +149,7 @@ def ShowSymbolMenu(lspserver: dict<any>, query: string)
       fixed: 1,
       close: 'button',
       filter: function(FilterSymbols, [lspserver]),
-      callback: JumpToWorkspaceSymbol
+      callback: function('JumpToWorkspaceSymbol', [cmdmods])
   }
   lspserver.workspaceSymbolPopup = popup_menu([], popupAttr)
   lspserver.workspaceSymbolQuery = query
@@ -175,16 +183,15 @@ enddef
 # process the 'workspace/symbol' reply from the LSP server
 # Result: SymbolInformation[] | null
 export def WorkspaceSymbolPopup(lspserver: dict<any>, query: string,
-                               symInfo: list<dict<any>>)
+                               symInfo: list<dict<any>>, cmdmods: string)
   var symbols: list<dict<any>> = []
   var symbolType: string
   var fileName: string
-  var r: dict<dict<number>>
   var symName: string
 
   # Create a symbol popup menu if it is not present
   if lspserver.workspaceSymbolPopup->winbufnr() == -1
-    ShowSymbolMenu(lspserver, query)
+    ShowSymbolMenu(lspserver, query, cmdmods)
   endif
 
   for symbol in symInfo
@@ -195,8 +202,6 @@ export def WorkspaceSymbolPopup(lspserver: dict<any>, query: string,
 
     # interface SymbolInformation
     fileName = util.LspUriToFile(symbol.location.uri)
-    r = symbol.location.range
-    lspserver.decodeRange(fileName->bufnr(), r)
 
     symName = symbol.name
     if symbol->has_key('containerName') && symbol.containerName != ''
@@ -209,7 +214,7 @@ export def WorkspaceSymbolPopup(lspserver: dict<any>, query: string,
 
     symbols->add({name: symName,
                        file: fileName,
-                       pos: r.start})
+                       pos: symbol.location.range.start})
   endfor
   symbols->setwinvar(lspserver.workspaceSymbolPopup, 'LspSymbolTable')
   lspserver.workspaceSymbolPopup->popup_settext(
index a63953c6a3660553f17ea607a7c1d2c918fd2f32..023c83553e85d471bfb8b45048c5c9b92fb613ae 100644 (file)
@@ -261,8 +261,8 @@ export def JumpToLspLocation(location: dict<any>, cmdmods: string)
   var fname = LspUriToFile(uri)
 
   # jump to the file and line containing the symbol
+  var bnr: number = fname->bufnr()
   if cmdmods->empty()
-    var bnr: number = fname->bufnr()
     if bnr == bufnr()
       # Set the previous cursor location mark. Instead of using setpos(), m' is
       # used so that the current location is added to the jump list.
@@ -294,7 +294,12 @@ export def JumpToLspLocation(location: dict<any>, cmdmods: string)
       endif
     endif
   else
-    exe $'{cmdmods} split {fname}'
+    if bnr == -1
+      exe $'{cmdmods} split {fname}'
+    else
+      # Use "sbuffer" so that the 'switchbuf' option settings are used.
+      exe $'{cmdmods} sbuffer {bnr}'
+    endif
   endif
   setcursorcharpos(range.start.line + 1,
                   GetCharIdxWithoutCompChar(bufnr(), range.start) + 1)
index 6c8b47f290c0f1e495934054ae643261b9fb267c..11857564918316fa05f88b8244e991fdfd70876d 100644 (file)
@@ -1047,9 +1047,11 @@ can map these commands to keys and make it easier to invoke them.
 :LspSymbolSearch <sym> Perform a workspace wide search for the symbol <sym>.
                        If <sym> is not supplied, then you will be prompted to
                        enter the symbol name (the keyword under the cursor is
-                       used as the default).  A popup window is opened with
-                       the list of matching symbols.  You can enter a few
-                       characters to narrow down the list of matches. The
+                       used as the default).  If there is only one matching
+                       symbol, then the cursor will be positioned at the
+                       symbol location.  Otherwise a popup window is opened
+                       with the list of matching symbols.  You can enter a
+                       few characters to narrow down the list of matches. The
                        displayed symbol name can be erased by pressing
                        <Backspace> or <C-U> and a new symbol search pattern
                        can be entered.  You can close the popup menu by
@@ -1082,6 +1084,14 @@ can map these commands to keys and make it easier to invoke them.
                        You can enter a new search pattern to do a workspace
                        wide symbol search.
 
+                       This command accepts |:command-modifiers| which can be
+                       used to jump to a symbol in a horizontally or
+                       vertically split window or a new tab page: >
+
+                               :topleft LspSymbolSearch foo
+                               :vert LspSymbolSearch bar
+                               :tab LspSymbolSearch baz
+<
                                                *:LspWorkspaceAddFolder*
 :LspWorkspaceAddFolder {folder}
                        Add a folder to the workspace
index cc9856ed8f08968fa9d4eac7249616f80d469898..f38f97ab029e24d2eefae28160bfc69f9ae92700 100644 (file)
@@ -96,7 +96,7 @@ command! -nargs=0 -bar LspSuperTypeHierarchy lsp.TypeHierarchy(1)
 # Clangd specifc extension to switch from one C/C++ source file to a
 # corresponding header file
 command! -nargs=0 -bar LspSwitchSourceHeader lsp.SwitchSourceHeader()
-command! -nargs=? -bar LspSymbolSearch lsp.SymbolSearch(<q-args>)
+command! -nargs=? -bar LspSymbolSearch lsp.SymbolSearch(<q-args>, <q-mods>)
 command! -nargs=1 -bar -complete=dir LspWorkspaceAddFolder lsp.AddWorkspaceFolder(<q-args>)
 command! -nargs=0 -bar LspWorkspaceListFolders lsp.ListWorkspaceFolders()
 command! -nargs=1 -bar -complete=dir LspWorkspaceRemoveFolder lsp.RemoveWorkspaceFolder(<q-args>)
index c61b37c331fac4562cca7f51bfbfa92d55747951..0918ab91a3dc77ca9749cdc4301667c8256a893d 100644 (file)
@@ -378,13 +378,13 @@ def g:Test_LspSymbolSearch_multibyte()
   g:WaitForServerFileLoad(0)
 
   cursor(1, 1)
-  feedkeys(":LspSymbolSearch Func1\<CR>\<CR>", "xt")
+  feedkeys(":LspSymbolSearch Func1\<CR>", "xt")
   assert_equal([5, 18], [line('.'), col('.')])
   cursor(1, 1)
-  feedkeys(":LspSymbolSearch Func2\<CR>\<CR>", "xt")
+  feedkeys(":LspSymbolSearch Func2\<CR>", "xt")
   assert_equal([9, 14], [line('.'), col('.')])
   cursor(1, 1)
-  feedkeys(":LspSymbolSearch Func3\<CR>\<CR>", "xt")
+  feedkeys(":LspSymbolSearch Func3\<CR>", "xt")
   assert_equal([13, 22], [line('.'), col('.')])
 
   :%bw!
index 3c88ff0a9bf306a13d192a9b9d6af71a5eafbf48..443ff987664667bb4d50df8ef1999ef029e9f361 100644 (file)
@@ -1178,7 +1178,7 @@ def g:Test_LspSymbolSearch()
   g:WaitForServerFileLoad(0)
 
   cursor(1, 1)
-  feedkeys(":LspSymbolSearch lsptest_funcB\<CR>\<CR>", "xt")
+  feedkeys(":LspSymbolSearch lsptest_funcB\<CR>", "xt")
   assert_equal([5, 6], [line('.'), col('.')])
 
   cursor(1, 1)
@@ -1186,7 +1186,7 @@ def g:Test_LspSymbolSearch()
   assert_equal([9, 6], [line('.'), col('.')])
 
   cursor(1, 1)
-  feedkeys(":LspSymbolSearch lsptest_funcA\<CR>\<BS>B\<CR>", "xt")
+  feedkeys(":LspSymbolSearch lsptest_func\<CR>A\<BS>B\<CR>", "xt")
   assert_equal([5, 6], [line('.'), col('.')])
 
   var output = execute(':LspSymbolSearch lsptest_nonexist')->split("\n")