feat(builtin.lsp): implement builtin handlers for lsp.(incoming|outgoing)_calls (#1484)

Fixes #863
This commit is contained in:
Manuel
2022-06-12 16:06:20 +02:00
committed by Simon Hauser
parent ffcc2221d6
commit 3a72cc8902
4 changed files with 128 additions and 2 deletions

View File

@@ -299,6 +299,8 @@ Built-in functions. Ready to be bound to any key you like.
| Functions | Description | | Functions | Description |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------| |---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `builtin.lsp_references` | Lists LSP references for word under the cursor | | `builtin.lsp_references` | Lists LSP references for word under the cursor |
| `builtin.lsp_incoming_calls` | Lists LSP incoming calls for word under the cursor |
| `builtin.lsp_outgoing_calls` | Lists LSP outgoing calls for word under the cursor |
| `builtin.lsp_document_symbols` | Lists LSP document symbols in the current buffer | | `builtin.lsp_document_symbols` | Lists LSP document symbols in the current buffer |
| `builtin.lsp_workspace_symbols` | Lists LSP document symbols in the current workspace | | `builtin.lsp_workspace_symbols` | Lists LSP document symbols in the current workspace |
| `builtin.lsp_dynamic_workspace_symbols` | Dynamically Lists LSP for all workspace symbols | | `builtin.lsp_dynamic_workspace_symbols` | Dynamically Lists LSP for all workspace symbols |

View File

@@ -1464,6 +1464,32 @@ builtin.lsp_references({opts}) *telescope.builtin.lsp_references()*
section (default: 30) section (default: 30)
builtin.lsp_incoming_calls({opts}) *telescope.builtin.lsp_incoming_calls()*
Lists LSP incoming calls for word under the cursor, jumps to reference on
`<cr>`
Parameters: ~
{opts} (table) options to pass to the picker
Options: ~
{show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false)
builtin.lsp_outgoing_calls({opts}) *telescope.builtin.lsp_outgoing_calls()*
Lists LSP outgoing calls for word under the cursor, jumps to reference on
`<cr>`
Parameters: ~
{opts} (table) options to pass to the picker
Options: ~
{show_line} (boolean) show results text (default: true)
{trim_text} (boolean) trim results text (default: false)
builtin.lsp_definitions({opts}) *telescope.builtin.lsp_definitions()* builtin.lsp_definitions({opts}) *telescope.builtin.lsp_definitions()*
Goto the definition of the word under the cursor, if there's only one, Goto the definition of the word under the cursor, if there's only one,
otherwise show all options in Telescope otherwise show all options in Telescope

View File

@@ -378,6 +378,18 @@ builtin.jumplist = require_on_exported_call("telescope.builtin.internal").jumpli
---@field fname_width number: defines the width of the filename section (default: 30) ---@field fname_width number: defines the width of the filename section (default: 30)
builtin.lsp_references = require_on_exported_call("telescope.builtin.lsp").references builtin.lsp_references = require_on_exported_call("telescope.builtin.lsp").references
--- Lists LSP incoming calls for word under the cursor, jumps to reference on `<cr>`
---@param opts table: options to pass to the picker
---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false)
builtin.lsp_incoming_calls = require_on_exported_call("telescope.builtin.lsp").incoming_calls
--- Lists LSP outgoing calls for word under the cursor, jumps to reference on `<cr>`
---@param opts table: options to pass to the picker
---@field show_line boolean: show results text (default: true)
---@field trim_text boolean: trim results text (default: false)
builtin.lsp_outgoing_calls = require_on_exported_call("telescope.builtin.lsp").outgoing_calls
--- Goto the definition of the word under the cursor, if there's only one, otherwise show all options in Telescope --- Goto the definition of the word under the cursor, if there's only one, otherwise show all options in Telescope
---@param opts table: options to pass to the picker ---@param opts table: options to pass to the picker
---@field jump_type string: how to goto definition if there is only one, values: "tab", "split", "vsplit", "never" ---@field jump_type string: how to goto definition if there is only one, values: "tab", "split", "vsplit", "never"

View File

@@ -52,9 +52,93 @@ lsp.references = function(opts)
end) end)
end end
local function list_or_jump(action, title, opts) local function call_hierarchy(opts, method, title, direction, item)
opts = opts or {} vim.lsp.buf_request(opts.bufnr, method, { item = item }, function(err, result)
if err then
vim.api.nvim_err_writeln("Error handling " .. title .. ": " .. err)
return
end
if not result or vim.tbl_isempty(result) then
return
end
local locations = {}
for _, ch_call in pairs(result) do
local ch_item = ch_call[direction]
for _, range in pairs(ch_call.fromRanges) do
table.insert(locations, {
filename = vim.uri_to_fname(ch_item.uri),
text = ch_item.name,
lnum = range.start.line + 1,
col = range.start.character + 1,
})
end
end
pickers.new(opts, {
prompt_title = title,
finder = finders.new_table {
results = locations,
entry_maker = opts.entry_maker or make_entry.gen_from_quickfix(opts),
},
previewer = conf.qflist_previewer(opts),
sorter = conf.generic_sorter(opts),
push_cursor_on_edit = true,
push_tagstack_on_edit = true,
}):find()
end)
end
local function pick_call_hierarchy_item(call_hierarchy_items)
if not call_hierarchy_items then
return
end
if #call_hierarchy_items == 1 then
return call_hierarchy_items[1]
end
local items = {}
for i, item in pairs(call_hierarchy_items) do
local entry = item.detail or item.name
table.insert(items, string.format("%d. %s", i, entry))
end
local choice = vim.fn.inputlist(items)
if choice < 1 or choice > #items then
return
end
return choice
end
local function calls(opts, direction)
local params = vim.lsp.util.make_position_params()
vim.lsp.buf_request(opts.bufnr, "textDocument/prepareCallHierarchy", params, function(err, result)
if err then
vim.api.nvim_err_writeln("Error when preparing call hierarchy: " .. err)
return
end
local call_hierarchy_item = pick_call_hierarchy_item(result)
if not call_hierarchy_item then
return
end
if direction == "from" then
call_hierarchy(opts, "callHierarchy/incomingCalls", "LSP Incoming Calls", direction, call_hierarchy_item)
else
call_hierarchy(opts, "callHierarchy/outgoingCalls", "LSP Outgoing Calls", direction, call_hierarchy_item)
end
end)
end
lsp.incoming_calls = function(opts)
calls(opts, "from")
end
lsp.outgoing_calls = function(opts)
calls(opts, "to")
end
local function list_or_jump(action, title, opts)
local params = vim.lsp.util.make_position_params(opts.winnr) local params = vim.lsp.util.make_position_params(opts.winnr)
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
@@ -271,6 +355,8 @@ local feature_map = {
["type_definitions"] = "typeDefinitionProvider", ["type_definitions"] = "typeDefinitionProvider",
["implementations"] = "implementationProvider", ["implementations"] = "implementationProvider",
["workspace_symbols"] = "workspaceSymbolProvider", ["workspace_symbols"] = "workspaceSymbolProvider",
["incoming_calls"] = "callHierarchyProvider",
["outgoing_calls"] = "callHierarchyProvider",
} }
local function apply_checks(mod) local function apply_checks(mod)