refactor(lsp): use vim.lsp.buf_request_all internally (#34604)

This commit is contained in:
Maria José Solano
2025-06-23 10:15:25 -07:00
committed by GitHub
parent 6942dec9b2
commit 40c61bf205
3 changed files with 129 additions and 162 deletions

View File

@@ -23,10 +23,6 @@ end
---@return table[] ---@return table[]
local function query_definition(pattern) local function query_definition(pattern)
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local clients = vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_definition })
if not next(clients) then
return {}
end
local win = api.nvim_get_current_win() local win = api.nvim_get_current_win()
local results = {} local results = {}
@@ -37,10 +33,18 @@ local function query_definition(pattern)
table.insert(results, mk_tag_item(pattern, range, uri, position_encoding)) table.insert(results, mk_tag_item(pattern, range, uri, position_encoding))
end end
local remaining = #clients local request_results, _ = lsp.buf_request_sync(
for _, client in ipairs(clients) do bufnr,
---@param result nil|lsp.Location|lsp.Location[]|lsp.LocationLink[] ms.textDocument_definition,
local function on_response(_, result) function(client)
return util.make_position_params(win, client.offset_encoding)
end
)
for client_id, res in pairs(request_results or {}) do
local client = assert(lsp.get_client_by_id(client_id))
local result = res.result ---@type lsp.Location|lsp.Location[]|lsp.LocationLink[]|nil
if result then if result then
local encoding = client.offset_encoding local encoding = client.offset_encoding
-- single Location -- single Location
@@ -56,14 +60,8 @@ local function query_definition(pattern)
end end
end end
end end
remaining = remaining - 1
end end
local params = util.make_position_params(win, client.offset_encoding)
client:request(ms.textDocument_definition, params, on_response, bufnr)
end
vim.wait(1000, function()
return remaining == 0
end)
return results return results
end end

View File

@@ -165,31 +165,34 @@ end
local function get_locations(method, opts) local function get_locations(method, opts)
opts = opts or {} opts = opts or {}
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local win = api.nvim_get_current_win()
local clients = lsp.get_clients({ method = method, bufnr = bufnr }) local clients = lsp.get_clients({ method = method, bufnr = bufnr })
if not next(clients) then if not next(clients) then
vim.notify(lsp._unsupported_method(method), vim.log.levels.WARN) vim.notify(lsp._unsupported_method(method), vim.log.levels.WARN)
return return
end end
local win = api.nvim_get_current_win()
local from = vim.fn.getpos('.') local from = vim.fn.getpos('.')
from[1] = bufnr from[1] = bufnr
local tagname = vim.fn.expand('<cword>') local tagname = vim.fn.expand('<cword>')
local remaining = #clients
lsp.buf_request_all(bufnr, method, function(client)
return util.make_position_params(win, client.offset_encoding)
end, function(results)
---@type vim.quickfix.entry[] ---@type vim.quickfix.entry[]
local all_items = {} local all_items = {}
---@param result nil|lsp.Location|lsp.Location[] for client_id, res in pairs(results) do
---@param client vim.lsp.Client local client = assert(lsp.get_client_by_id(client_id))
local function on_response(_, result, client)
local locations = {} local locations = {}
if result then if res then
locations = vim.islist(result) and result or { result } locations = vim.islist(res.result) and res.result or { res.result }
end end
local items = util.locations_to_items(locations, client.offset_encoding) local items = util.locations_to_items(locations, client.offset_encoding)
vim.list_extend(all_items, items) vim.list_extend(all_items, items)
remaining = remaining - 1 end
if remaining == 0 then
if vim.tbl_isempty(all_items) then if vim.tbl_isempty(all_items) then
vim.notify('No locations found', vim.log.levels.INFO) vim.notify('No locations found', vim.log.levels.INFO)
return return
@@ -239,15 +242,8 @@ local function get_locations(method, opts)
vim.fn.setqflist({}, ' ', { title = title, items = all_items }) vim.fn.setqflist({}, ' ', { title = title, items = all_items })
vim.cmd('botright copen') vim.cmd('botright copen')
end end
end
end
for _, client in ipairs(clients) do
local params = util.make_position_params(win, client.offset_encoding)
client:request(method, params, function(_, result)
on_response(_, result, client)
end) end)
end end
end
--- @class vim.lsp.ListOpts --- @class vim.lsp.ListOpts
--- ---
@@ -795,17 +791,24 @@ function M.references(context, opts)
validate('opts', opts, 'table', true) validate('opts', opts, 'table', true)
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local clients = lsp.get_clients({ method = ms.textDocument_references, bufnr = bufnr })
if not next(clients) then
return
end
local win = api.nvim_get_current_win() local win = api.nvim_get_current_win()
opts = opts or {} opts = opts or {}
lsp.buf_request_all(bufnr, ms.textDocument_references, function(client)
local params = util.make_position_params(win, client.offset_encoding)
---@diagnostic disable-next-line: inject-field
params.context = context or { includeDeclaration = true }
return params
end, function(results)
local all_items = {} local all_items = {}
local title = 'References' local title = 'References'
local function on_done() for client_id, res in pairs(results) do
local client = assert(lsp.get_client_by_id(client_id))
local items = util.locations_to_items(res.result, client.offset_encoding)
vim.list_extend(all_items, items)
end
if not next(all_items) then if not next(all_items) then
vim.notify('No references found') vim.notify('No references found')
else else
@@ -828,26 +831,8 @@ function M.references(context, opts)
vim.cmd('botright copen') vim.cmd('botright copen')
end end
end end
end
local remaining = #clients
for _, client in ipairs(clients) do
local params = util.make_position_params(win, client.offset_encoding)
---@diagnostic disable-next-line: inject-field
params.context = context or {
includeDeclaration = true,
}
client:request(ms.textDocument_references, params, function(_, result)
local items = util.locations_to_items(result or {}, client.offset_encoding)
vim.list_extend(all_items, items)
remaining = remaining - 1
if remaining == 0 then
on_done()
end
end) end)
end end
end
--- Lists all symbols in the current buffer in the |location-list|. --- Lists all symbols in the current buffer in the |location-list|.
--- @param opts? vim.lsp.ListOpts --- @param opts? vim.lsp.ListOpts
@@ -909,8 +894,21 @@ local function hierarchy(method)
local win = api.nvim_get_current_win() local win = api.nvim_get_current_win()
--- @param results [integer, lsp.TypeHierarchyItem|lsp.CallHierarchyItem][] lsp.buf_request_all(bufnr, prepare_method, function(client)
local function on_response(results) return util.make_position_params(win, client.offset_encoding)
end, function(req_results)
local results = {} --- @type [integer, lsp.TypeHierarchyItem|lsp.CallHierarchyItem][]
for client_id, res in pairs(req_results) do
if res.err then
vim.notify(res.err.message, vim.log.levels.WARN)
elseif res.result then
local result = res.result --- @type lsp.TypeHierarchyItem[]|lsp.CallHierarchyItem[]
for _, item in ipairs(result) do
results[#results + 1] = { client_id, item }
end
end
end
if #results == 0 then if #results == 0 then
vim.notify('No item resolved', vim.log.levels.WARN) vim.notify('No item resolved', vim.log.levels.WARN)
elseif #results == 1 then elseif #results == 1 then
@@ -930,30 +928,7 @@ local function hierarchy(method)
end end
end) end)
end end
end end)
local results = {} --- @type [integer, lsp.TypeHierarchyItem|lsp.CallHierarchyItem][]
local remaining = #clients
for _, client in ipairs(clients) do
local params = util.make_position_params(win, client.offset_encoding)
--- @param result lsp.CallHierarchyItem[]|lsp.TypeHierarchyItem[]?
client:request(prepare_method, params, function(err, result, ctx)
if err then
vim.notify(err.message, vim.log.levels.WARN)
elseif result then
for _, item in ipairs(result) do
results[#results + 1] = { ctx.client_id, item }
end
end
remaining = remaining - 1
if remaining == 0 then
on_response(results)
end
end, bufnr)
end
end end
--- Lists all the call sites of the symbol under the cursor in the --- Lists all the call sites of the symbol under the cursor in the
@@ -1098,7 +1073,7 @@ end
---@nodoc ---@nodoc
---@class vim.lsp.CodeActionResultEntry ---@class vim.lsp.CodeActionResultEntry
---@field error? lsp.ResponseError ---@field err? lsp.ResponseError
---@field result? (lsp.Command|lsp.CodeAction)[] ---@field result? (lsp.Command|lsp.CodeAction)[]
---@field ctx lsp.HandlerContext ---@field ctx lsp.HandlerContext
@@ -1306,29 +1281,14 @@ function M.code_action(opts)
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local win = api.nvim_get_current_win() local win = api.nvim_get_current_win()
local clients = lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_codeAction }) local clients = lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_codeAction })
local remaining = #clients if not next(clients) then
if remaining == 0 then
if next(lsp.get_clients({ bufnr = bufnr })) then if next(lsp.get_clients({ bufnr = bufnr })) then
vim.notify(lsp._unsupported_method(ms.textDocument_codeAction), vim.log.levels.WARN) vim.notify(lsp._unsupported_method(ms.textDocument_codeAction), vim.log.levels.WARN)
end end
return return
end end
---@type table<integer, vim.lsp.CodeActionResultEntry> lsp.buf_request_all(bufnr, ms.textDocument_codeAction, function(client)
local results = {}
---@param err? lsp.ResponseError
---@param result? (lsp.Command|lsp.CodeAction)[]
---@param ctx lsp.HandlerContext
local function on_result(err, result, ctx)
results[ctx.client_id] = { error = err, result = result, ctx = ctx }
remaining = remaining - 1
if remaining == 0 then
on_code_action_results(results, opts)
end
end
for _, client in ipairs(clients) do
---@type lsp.CodeActionParams ---@type lsp.CodeActionParams
local params local params
@@ -1364,8 +1324,15 @@ function M.code_action(opts)
}) })
end end
client:request(ms.textDocument_codeAction, params, on_result, bufnr) return params
end, function(results, ctx)
for _, result in pairs(results) do
---@cast result vim.lsp.CodeActionResultEntry
result.ctx = ctx
end end
on_code_action_results(results, opts)
end)
end end
--- @deprecated --- @deprecated

View File

@@ -430,6 +430,8 @@ function M._convert_results(
return matches, server_start_boundary return matches, server_start_boundary
end end
-- NOTE: The reason we don't use `lsp.buf_request_all` here is because we want to filter the clients
-- that received the request based on the trigger characters.
--- @param clients table<integer, vim.lsp.Client> # keys != client_id --- @param clients table<integer, vim.lsp.Client> # keys != client_id
--- @param bufnr integer --- @param bufnr integer
--- @param win integer --- @param win integer