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 | |
| parent | ffcc2221d63aa89665e468be1dd8cd8e40e5f581 (diff) | |
feat(builtin.lsp): implement builtin handlers for lsp.(incoming|outgoing)_calls (#1484)
Fixes #863
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | doc/telescope.txt | 26 | ||||
| -rw-r--r-- | lua/telescope/builtin/init.lua | 12 | ||||
| -rw-r--r-- | lua/telescope/builtin/lsp.lua | 90 |
4 files changed, 128 insertions, 2 deletions
@@ -299,6 +299,8 @@ Built-in functions. Ready to be bound to any key you like. | Functions | Description | |---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------| | `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_workspace_symbols` | Lists LSP document symbols in the current workspace | | `builtin.lsp_dynamic_workspace_symbols` | Dynamically Lists LSP for all workspace symbols | diff --git a/doc/telescope.txt b/doc/telescope.txt index ce171f1..78cc7e4 100644 --- a/doc/telescope.txt +++ b/doc/telescope.txt @@ -1464,6 +1464,32 @@ builtin.lsp_references({opts}) *telescope.builtin.lsp_references()* 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()* Goto the definition of the word under the cursor, if there's only one, otherwise show all options in Telescope 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) |
