fix(lsp.reference): single reference direct jump (#3137)
* fix(lsp.reference): single reference direct jump * [docgen] Update doc/telescope.txt skip-checks: true --------- Co-authored-by: Github Actions <actions@github>
This commit is contained in:
@@ -1607,6 +1607,8 @@ builtin.lsp_references({opts}) *telescope.builtin.lsp_references()*
|
|||||||
"vsplit", "never"
|
"vsplit", "never"
|
||||||
{show_line} (boolean) show results text (default: true)
|
{show_line} (boolean) show results text (default: true)
|
||||||
{trim_text} (boolean) trim results text (default: false)
|
{trim_text} (boolean) trim results text (default: false)
|
||||||
|
{reuse_win} (boolean) jump to existing window if buffer is
|
||||||
|
already opened (default: false)
|
||||||
{file_encoding} (string) file encoding for the previewer
|
{file_encoding} (string) file encoding for the previewer
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -97,51 +97,59 @@ lsp.outgoing_calls = function(opts)
|
|||||||
calls(opts, "to")
|
calls(opts, "to")
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type { [string]: fun(results: table, items: table, opts: table): table, table }
|
--- convert `item` type back to something we can pass to `vim.lsp.util.jump_to_location`
|
||||||
local action_handlers = {
|
--- stopgap for pre-nvim 0.10 - after which we can simply use the `user_data`
|
||||||
["textDocument/references"] = function(results, items, opts)
|
--- field on the items in `vim.lsp.util.locations_to_items`
|
||||||
if not opts.include_current_line then
|
---@param item vim.lsp.util.locations_to_items.ret
|
||||||
local retresults = {}
|
---@param offset_encoding string|nil utf-8|utf-16|utf-32
|
||||||
local retitems = {}
|
---@return lsp.Location
|
||||||
|
local function item_to_location(item, offset_encoding)
|
||||||
for i, item in pairs(items) do
|
local line = item.lnum - 1
|
||||||
if
|
local character = vim.lsp.util._str_utfindex_enc(item.text, item.col, offset_encoding) - 1
|
||||||
not (
|
return {
|
||||||
item.filename == vim.api.nvim_buf_get_name(opts.bufnr)
|
uri = vim.uri_from_fname(item.filename),
|
||||||
and item.lnum == vim.api.nvim_win_get_cursor(opts.winnr)[1]
|
range = {
|
||||||
)
|
start = {
|
||||||
then
|
line = line,
|
||||||
table.insert(retresults, results[i])
|
character = character,
|
||||||
table.insert(retitems, items[i])
|
},
|
||||||
end
|
["end"] = {
|
||||||
end
|
line = line,
|
||||||
|
character = character,
|
||||||
return retresults, retitems
|
},
|
||||||
end
|
},
|
||||||
|
|
||||||
return results, items
|
|
||||||
end,
|
|
||||||
}
|
}
|
||||||
|
end
|
||||||
|
|
||||||
---@param action string
|
---@alias telescope.lsp.list_or_jump_action
|
||||||
---@param locations table
|
---| "textDocument/references"
|
||||||
---@param items table
|
---| "textDocument/definition"
|
||||||
|
---| "textDocument/typeDefinition"
|
||||||
|
---| "textDocument/implementation"
|
||||||
|
|
||||||
|
---@param action telescope.lsp.list_or_jump_action
|
||||||
|
---@param items vim.lsp.util.locations_to_items.ret[]
|
||||||
---@param opts table
|
---@param opts table
|
||||||
---@return table results, table items
|
---@return vim.lsp.util.locations_to_items.ret[]
|
||||||
local apply_action_handler = function(action, locations, items, opts)
|
local apply_action_handler = function(action, items, opts)
|
||||||
local handler = action_handlers[action]
|
if action == "textDocument/references" and not opts.include_current_line then
|
||||||
if handler then
|
local lnum = vim.api.nvim_win_get_cursor(opts.winnr)[1]
|
||||||
return handler(locations, items, opts)
|
items = vim.tbl_filter(function(v)
|
||||||
|
return not (v.filename and v.lnum == lnum)
|
||||||
|
end, items)
|
||||||
end
|
end
|
||||||
|
|
||||||
return locations, items
|
return items
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param action string
|
---@param action telescope.lsp.list_or_jump_action
|
||||||
---@param title string prompt title
|
---@param title string prompt title
|
||||||
---@param params lsp.TextDocumentPositionParams
|
---@param params lsp.TextDocumentPositionParams
|
||||||
---@param opts table
|
---@param opts table
|
||||||
local function list_or_jump(action, title, params, opts)
|
local function list_or_jump(action, title, params, opts)
|
||||||
|
opts.reuse_win = vim.F.if_nil(opts.reuse_win, false)
|
||||||
|
|
||||||
|
local curr_filepath = vim.api.nvim_buf_get_name(opts.bufnr)
|
||||||
vim.lsp.buf_request(opts.bufnr, action, params, function(err, result, ctx, _)
|
vim.lsp.buf_request(opts.bufnr, action, params, function(err, result, ctx, _)
|
||||||
if err then
|
if err then
|
||||||
vim.api.nvim_err_writeln("Error when executing " .. action .. " : " .. err.message)
|
vim.api.nvim_err_writeln("Error when executing " .. action .. " : " .. err.message)
|
||||||
@@ -160,19 +168,16 @@ local function list_or_jump(action, title, params, opts)
|
|||||||
|
|
||||||
local offset_encoding = vim.lsp.get_client_by_id(ctx.client_id).offset_encoding
|
local offset_encoding = vim.lsp.get_client_by_id(ctx.client_id).offset_encoding
|
||||||
local items = vim.lsp.util.locations_to_items(locations, offset_encoding)
|
local items = vim.lsp.util.locations_to_items(locations, offset_encoding)
|
||||||
|
items = apply_action_handler(action, items, opts)
|
||||||
|
|
||||||
locations, items = apply_action_handler(action, locations, items, opts)
|
if vim.tbl_isempty(items) then
|
||||||
|
|
||||||
if vim.tbl_isempty(locations) then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if #locations == 1 and opts.jump_type ~= "never" then
|
if #items == 1 and opts.jump_type ~= "never" then
|
||||||
local current_uri = params.textDocument.uri
|
local item = items[1]
|
||||||
local target_uri = locations[1].uri or locations[1].targetUri
|
if curr_filepath ~= item.filename then
|
||||||
if current_uri ~= target_uri then
|
|
||||||
local cmd
|
local cmd
|
||||||
local file_path = vim.uri_to_fname(target_uri)
|
|
||||||
if opts.jump_type == "tab" then
|
if opts.jump_type == "tab" then
|
||||||
cmd = "tabedit"
|
cmd = "tabedit"
|
||||||
elseif opts.jump_type == "split" then
|
elseif opts.jump_type == "split" then
|
||||||
@@ -184,11 +189,12 @@ local function list_or_jump(action, title, params, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if cmd then
|
if cmd then
|
||||||
vim.cmd(string.format("%s %s", cmd, file_path))
|
vim.cmd(string.format("%s %s", cmd, item.filename))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.lsp.util.jump_to_location(locations[1], offset_encoding, opts.reuse_win)
|
local location = item_to_location(item, offset_encoding)
|
||||||
|
vim.lsp.util.jump_to_location(location, offset_encoding, opts.reuse_win)
|
||||||
else
|
else
|
||||||
pickers
|
pickers
|
||||||
.new(opts, {
|
.new(opts, {
|
||||||
@@ -208,6 +214,7 @@ local function list_or_jump(action, title, params, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
lsp.references = function(opts)
|
lsp.references = function(opts)
|
||||||
|
opts.include_current_line = vim.F.if_nil(opts.include_current_line, false)
|
||||||
local params = vim.lsp.util.make_position_params(opts.winnr)
|
local params = vim.lsp.util.make_position_params(opts.winnr)
|
||||||
params.context = { includeDeclaration = vim.F.if_nil(opts.include_declaration, true) }
|
params.context = { includeDeclaration = vim.F.if_nil(opts.include_declaration, true) }
|
||||||
return list_or_jump("textDocument/references", "LSP References", params, opts)
|
return list_or_jump("textDocument/references", "LSP References", params, opts)
|
||||||
|
|||||||
@@ -421,6 +421,7 @@ builtin.jumplist = require_on_exported_call("telescope.builtin.__internal").jump
|
|||||||
---@field jump_type string: how to goto reference if there is only one and the definition file is different from the current file, values: "tab", "tab drop", "split", "vsplit", "never"
|
---@field jump_type string: how to goto reference if there is only one and the definition file is different from the current file, values: "tab", "tab drop", "split", "vsplit", "never"
|
||||||
---@field show_line boolean: show results text (default: true)
|
---@field show_line boolean: show results text (default: true)
|
||||||
---@field trim_text boolean: trim results text (default: false)
|
---@field trim_text boolean: trim results text (default: false)
|
||||||
|
---@field reuse_win boolean: jump to existing window if buffer is already opened (default: false)
|
||||||
---@field file_encoding string: file encoding for the previewer
|
---@field file_encoding string: file encoding for the previewer
|
||||||
builtin.lsp_references = require_on_exported_call("telescope.builtin.__lsp").references
|
builtin.lsp_references = require_on_exported_call("telescope.builtin.__lsp").references
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user