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/builtin/lsp.lua | |
| parent | ffcc2221d63aa89665e468be1dd8cd8e40e5f581 (diff) | |
feat(builtin.lsp): implement builtin handlers for lsp.(incoming|outgoing)_calls (#1484)
Fixes #863
Diffstat (limited to 'lua/telescope/builtin/lsp.lua')
| -rw-r--r-- | lua/telescope/builtin/lsp.lua | 90 |
1 files changed, 88 insertions, 2 deletions
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) |
