autoload/lsp/lspserver.vim | 19 ++++++++++++++++++- autoload/lsp/symbol.vim | 20 +++++++++++--------- autoload/lsp/util.vim | 17 ++++++++++++++--- diff --git a/autoload/lsp/lspserver.vim b/autoload/lsp/lspserver.vim index fd78974088a37fc5a0bb76a38a6ef45186a63b6f..16d98380013aea065742b806e47983cba9abb75e 100644 --- a/autoload/lsp/lspserver.vim +++ b/autoload/lsp/lspserver.vim @@ -425,7 +425,11 @@ foldingRange: {lineFoldingOnly: true}, inlayHint: {dynamicRegistration: false}, synchronization: { didSave: true - } + }, + declaration: {linkSupport: true}, + definition: {linkSupport: true}, + typeDefinition: {linkSupport: true}, + implementation: {linkSupport: true} }, window: {}, general: {} @@ -884,6 +888,11 @@ if reply.result->type() == v:t_list location = reply.result[0] else location = reply.result + endif + + # Convert to 'LocationLink' + if !location->has_key('targetUri') + location = util.LspLocationToLocationLink(location) endif symbol.GotoSymbol(lspserver, location, peekSymbol, cmdmods) @@ -1585,6 +1594,14 @@ taglocations = reply.result else taglocations = [reply.result] endif + + taglocations = taglocations->map((key, location) => { + # Already a 'LocationLink' + if location->has_key('targetUri') + return location + endif + return util.LspLocationToLocationLink(location) + }) return symbol.TagFunc(lspserver, taglocations, pat) enddef diff --git a/autoload/lsp/symbol.vim b/autoload/lsp/symbol.vim index ab167e4b9c116384031f3b028616d5c920234bee..6bddbff4c313d4c707be73c9587b731017e08cca 100644 --- a/autoload/lsp/symbol.vim +++ b/autoload/lsp/symbol.vim @@ -394,10 +394,10 @@ return false enddef -# Display the file specified by LSP 'location' in a popup window and highlight -# the range in 'location'. +# Display the file specified by LSP 'LocationLink' in a popup window and +# highlight the range in 'location'. def PeekSymbolLocation(lspserver: dict, location: dict) - var fname = util.LspUriToFile(location.uri) + var fname = util.LspUriToFile(location.targetUri) var bnum = fname->bufadd() if bnum == 0 # Failed to create or find a buffer @@ -431,13 +431,13 @@ var pwbuf = pwid->winbufnr() var pos: list = [] var start_col: number var end_col: number - start_col = util.GetLineByteFromPos(pwbuf, location.range.start) + 1 - end_col = util.GetLineByteFromPos(pwbuf, location.range.end) + 1 - pos->add(location.range.start.line + 1) + start_col = util.GetLineByteFromPos(pwbuf, location.targetSelectionRange.start) + 1 + end_col = util.GetLineByteFromPos(pwbuf, location.targetSelectionRange.end) + 1 + pos->add(location.targetSelectionRange.start.line + 1) pos->extend([start_col, end_col - start_col]) matchaddpos('Search', [pos], 10, 101, {window: pwid}) var cmds =<< trim eval END - [{location.range.start.line + 1}, 1]->cursor() + [{location.targetSelectionRange.start.line + 1}, 1]->cursor() normal! z. END win_execute(pwid, cmds, 'silent!') @@ -467,8 +467,10 @@ for tagloc in taglocations var tagitem = {} tagitem.name = pat - tagitem.filename = util.LspUriToFile(tagloc.uri) - tagitem.cmd = $"/\\%{tagloc.range.start.line + 1}l\\%{tagloc.range.start.character + 1}c" + + tagitem.filename = util.LspUriToFile(tagloc.targetUri) + tagitem.cmd = $"/\\%{tagloc.targetSelectionRange.start.line + 1}l\\%{tagloc.targetSelectionRange.start.character + 1}c" + retval->add(tagitem) endfor diff --git a/autoload/lsp/util.vim b/autoload/lsp/util.vim index 556430f6ba16c9c6bdb5668c2ff0ef8b5579170d..11b160655c7344e7f40b2f675b0256f1ef06835c 100644 --- a/autoload/lsp/util.vim +++ b/autoload/lsp/util.vim @@ -50,6 +50,17 @@ writefile([], $'{lsp_log_dir}lsp-server.out') writefile([], $'{lsp_log_dir}lsp-server.err') enddef +# Convert a 'Location' to a dict that looks a lot like a 'LocationLink' but with +# the caveat that 'targetRange' is null. +export def LspLocationToLocationLink(location: dict): dict + return { + targetUri: location.uri, + targetSelectionRange: location.range, + targetRange: null, + originSelectionRange: null + } +enddef + # Convert a LSP file URI (file://) to a Vim file name export def LspUriToFile(uri: string): string # Replace all the %xx numbers (e.g. %20 for space) in the URI to character @@ -154,7 +165,7 @@ # Jump to the LSP 'location'. The 'location' contains the file name, line # number and character number. The user specified window command modifiers # (e.g. topleft) are in 'cmdmods'. export def JumpToLspLocation(location: dict, cmdmods: string) - var fname = LspUriToFile(location.uri) + var fname = LspUriToFile(location.targetUri) # jump to the file and line containing the symbol if cmdmods == '' @@ -191,8 +202,8 @@ 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(location.range.start.line + 1, - location.range.start.character + 1) + setcursorcharpos(location.targetSelectionRange.start.line + 1, + location.targetSelectionRange.start.character + 1) enddef # vim: tabstop=8 shiftwidth=2 softtabstop=2