diff options
| author | Manuel <dev+git@manuelsbrain.de> | 2022-06-12 16:06:20 +0200 |
|---|---|---|
| committer | Simon Hauser <simon.hauser@helsinki-systems.de> | 2022-06-30 14:01:51 +0200 |
| commit | 3a72cc89024120d09f32d70689cc9cbe367fc2b4 (patch) | |
| tree | 8b51ae0442809616df1f26a16b4247d8771ef02d /lua/telescope | |
| parent | ffcc2221d63aa89665e468be1dd8cd8e40e5f581 (diff) | |
feat(builtin.lsp): implement builtin handlers for lsp.(incoming|outgoing)_calls (#1484)
Fixes #863
Diffstat (limited to 'lua/telescope')
| -rw-r--r-- | lua/telescope/builtin/init.lua | 12 | ||||
| -rw-r--r-- | lua/telescope/builtin/lsp.lua | 90 |
2 files changed, 100 insertions, 2 deletions
diff --git a/lua/telescope/builtin/init.lua b/lua/telescope/builtin/init.lua index 7a3fb14..20d9812 100644 --- a/lua/telescope/builtin/init.lua +++ b/lua/telescope/builtin/init.lua @@ -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) 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 ---@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" diff --git a/lua/telescope/builtin/lsp.lua b/lua/telescope/builtin/lsp.lua index 410a068..85fabb0 100644 --- a/lua/telescope/builtin/lsp.lua +++ b/lua/telescope/builtin/lsp.lua @@ -52,9 +52,93 @@ lsp.references = function(opts) end) end -local function list_or_jump(action, title, opts) - opts = opts or {} +local function call_hierarchy(opts, method, title, direction, item) + 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) vim.lsp.buf_request(opts.bufnr, action, params, function(err, result, ctx, _) if err then @@ -271,6 +355,8 @@ local feature_map = { ["type_definitions"] = "typeDefinitionProvider", ["implementations"] = "implementationProvider", ["workspace_symbols"] = "workspaceSymbolProvider", + ["incoming_calls"] = "callHierarchyProvider", + ["outgoing_calls"] = "callHierarchyProvider", } local function apply_checks(mod) |
