feat(lsp): add vim.lsp.buf.subtypes(), vim.lsp.buf.supertypes() (#28388)

Co-authored-by: Mathias Fußenegger <mfussenegger@users.noreply.github.com>
Co-authored-by: Maria José Solano <majosolano99@gmail.com>
This commit is contained in:
Yinzuo Jiang
2024-04-20 21:40:01 +08:00
committed by GitHub
parent fd085d9082
commit f190f758ac
6 changed files with 577 additions and 0 deletions

View File

@@ -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()