diff options
Diffstat (limited to 'runtime/lua/vim/lsp/buf.lua')
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 17cc698b76..fa0cbab138 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -495,6 +495,90 @@ function M.outgoing_calls() call_hierarchy(ms.callHierarchy_outgoingCalls) end +--- @param method string +local function type_hierarchy(method) + --- Merge results from multiple clients into a single table. Client-ID is preserved. + --- + --- @param results table<integer, {error: lsp.ResponseError, result: lsp.TypeHierarchyItem[]?}> + local function merge_results(results) + local merged_results = {} + for client_id, client_result in pairs(results) do + if client_result.error then + vim.notify(client_result.error.message, vim.log.levels.WARN) + elseif client_result.result then + for _, item in pairs(client_result.result) do + table.insert(merged_results, { client_id, item }) + end + end + end + return merged_results + end + + local bufnr = api.nvim_get_current_buf() + local params = util.make_position_params() + --- @param results table<integer, {error: lsp.ResponseError, result: lsp.TypeHierarchyItem[]?}> + vim.lsp.buf_request_all(bufnr, ms.textDocument_prepareTypeHierarchy, params, function(results) + local merged_results = merge_results(results) + if #merged_results == 0 then + vim.notify('No items resolved', vim.log.levels.INFO) + return + end + + if #merged_results == 1 then + --- @type {integer, lsp.TypeHierarchyItem} + local item = merged_results[1] + local client = vim.lsp.get_client_by_id(item[1]) + if client then + --- @type lsp.TypeHierarchyItem + client.request(method, { item = item[2] }, nil, bufnr) + else + vim.notify( + string.format('Client with id=%d disappeared during call hierarchy request', item[1]), + vim.log.levels.WARN + ) + end + else + local opts = { + prompt = 'Select a type hierarchy item:', + kind = 'typehierarchy', + format_item = function(item) + if not item[2].detail or #item[2].detail == 0 then + return item[2].name + end + return string.format('%s %s', item[2].name, item[2].detail) + end, + } + + vim.ui.select(merged_results, opts, function(item) + local client = vim.lsp.get_client_by_id(item[1]) + if client then + --- @type lsp.TypeHierarchyItem + client.request(method, { item = item[2] }, nil, bufnr) + else + vim.notify( + string.format('Client with id=%d disappeared during call hierarchy request', item[1]), + vim.log.levels.WARN + ) + end + end) + end + end) +end + +--- Lists all the subtypes of the symbol under the +--- cursor in the |quickfix| window. If the symbol can resolve to +--- multiple items, the user can pick one using |vim.ui.select()|. +function M.subtypes() + type_hierarchy(ms.typeHierarchy_subtypes) +end + +--- Lists all the supertypes of the symbol under the +--- cursor in the |quickfix| window. If the symbol can resolve to +--- multiple items, the user can pick one using |vim.ui.select()|. +function M.supertypes() + type_hierarchy(ms.typeHierarchy_supertypes) +end + --- List workspace folders. --- function M.list_workspace_folders() |