]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Populate the location list if there are multiple goto and peek locations
authorAndreas Louv <andreas@louv.dk>
Tue, 21 Mar 2023 20:51:30 +0000 (21:51 +0100)
committerAndreas Louv <andreas@louv.dk>
Tue, 21 Mar 2023 21:31:54 +0000 (22:31 +0100)
autoload/lsp/lspserver.vim
doc/lsp.txt
test/tsserver_tests.vim

index e3cb85ad23a6a959dcb563fba23d4abd339db031..e750c0228b22a11658f1d9eea69a4a591607d733 100644 (file)
@@ -900,8 +900,24 @@ def GotoSymbolLoc(lspserver: dict<any>, msg: string, peekSymbol: bool,
     return
   endif
 
+  var title: string = ''
+  if msg ==# 'textDocument/declaration'
+    title = 'Declarations'
+  elseif msg ==# 'textDocument/typeDefinition'
+    title = 'Type Definitions'
+  elseif msg ==# 'textDocument/implementation'
+    title = 'Implementations'
+  else
+    title = 'Definitions'
+  endif
+
   var location: dict<any>
   if reply.result->type() == v:t_list
+    if reply.result->len() > 1
+      symbol.ShowLocations(lspserver, reply.result, peekSymbol, title)
+      return
+    endif
+
     location = reply.result[0]
   else
     location = reply.result
index b74f0873249b4fed7d395c0400f1621aaa217f45..039eeee5d904e53183246c79366a53d0794a918e 100644 (file)
@@ -403,15 +403,23 @@ can map these commands to keys and make it easier to invoke them.
 
                                                *:LspGotoDefinition*
 :LspGotoDefinition     Jumps to the definition of the symbol under the
-                       cursor.  If the file is already present in a window,
-                       then jumps to that window.  Otherwise, opens the file
-                       in a  new window.  If the current buffer is modified
-                       and 'hidden' is not set or if the current buffer is a
-                       special buffer, then a new window is opened.  If the
-                       jump is successful, then the current cursor location
-                       is pushed onto the tag stack.  The |CTRL-T| command
-                       can be used to go back up the tag stack.  Also the
-                       |``| mark is set to the position before the jump.
+                       cursor.
+
+                       If there are multiple matches, then a location list will
+                       be created with the list of locations.
+
+                       If there is only one location then the following will
+                       apply:
+
+                       If the file is already present in a window, then jumps
+                       to that window.  Otherwise, opens the file in a new
+                       window.  If the current buffer is modified and 'hidden'
+                       is not set or if the current buffer is a special buffer,
+                       then a new window is opened.  If the jump is successful,
+                       then the current cursor location is pushed onto the tag
+                       stack.  The |CTRL-T| command can be used to go back up
+                       the tag stack.  Also the |``| mark is set to the
+                       position before the jump.
 
                        This command supports |:command-modifiers|.  You can
                        use the modifiers to specify whether a new window or
index ad08489d3b32212f0c5d6ebd6f366f2bb40df94e..d0b86959a96535b2092f4327a65fdc28fa089e75 100644 (file)
@@ -71,6 +71,72 @@ def g:Test_LspDiag()
   :%bw!
 enddef
 
+def g:Test_LspGoto()
+  :silent! edit Xtest.ts
+  sleep 200m
+
+  var lines: list<string> = [
+    'function B(val: number): void;'
+    'function B(val: string): void;',
+    'function B(val: string | number) {',
+    '  console.log(val);',
+    '  return void 0;',
+    '}',
+    'typeof B;',
+    'B(1);',
+    'B("1");'
+  ]
+
+  setline(1, lines)
+  :sleep 1
+
+  cursor(8, 1)
+  assert_equal('', execute('LspGotoDefinition'))
+  assert_equal([1, 10], [line('.'), col('.')])
+
+  cursor(9, 1)
+  assert_equal('', execute('LspGotoDefinition'))
+  assert_equal([2, 10], [line('.'), col('.')])
+
+  cursor(9, 1)
+  assert_equal('', execute('LspGotoDefinition'))
+  assert_equal([2, 10], [line('.'), col('.')])
+
+  cursor(7, 8)
+  assert_equal('', execute('LspGotoDefinition'))
+  sleep 200m
+  var qfl: list<dict<any>> = getloclist(0)
+  assert_equal('quickfix', getwinvar(winnr('$'), '&buftype'))
+  assert_equal(bufnr(), qfl[0].bufnr)
+  assert_equal(3, qfl->len())
+  assert_equal([1, 10, ''], [qfl[0].lnum, qfl[0].col, qfl[0].type])
+  assert_equal([2, 10, ''], [qfl[1].lnum, qfl[1].col, qfl[1].type])
+  assert_equal([3, 10, ''], [qfl[2].lnum, qfl[2].col, qfl[2].type])
+  lclose
+
+  # Opening the preview window with an unsaved buffer displays the "E37: No
+  # write since last change" error message.  To disable this message, mark the
+  # buffer as not modified.
+  setlocal nomodified
+  cursor(7, 8)
+  :LspPeekDefinition
+  sleep 10m
+  var ids = popup_list()
+  assert_equal(2, ids->len())
+  var filePopupAttrs = ids[0]->popup_getoptions()
+  var refPopupAttrs = ids[1]->popup_getoptions()
+  assert_match('Xtest', filePopupAttrs.title)
+  assert_match('Definitions', refPopupAttrs.title)
+  assert_equal(1, line('.', ids[0]))
+  assert_equal(3, line('$', ids[1]))
+  feedkeys("jj\<CR>", 'xt')
+  assert_equal(3, line('.'))
+  assert_equal([], popup_list())
+  popup_clear()
+
+  :%bw!
+enddef
+
 # Start the typescript language server.  Returns true on success and false on
 # failure.
 def g:StartLangServer(): bool