Skip to content

Commit ec3fe3d

Browse files
committed
fix(lsp): prep methods with multiple clients
closes #2547
1 parent 6971762 commit ec3fe3d

1 file changed

Lines changed: 23 additions & 6 deletions

File tree

lua/fzf-lua/providers/lsp.lua

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,9 +484,17 @@ local function gen_lsp_contents(opts)
484484
if response.result then
485485
local context = { client_id = client_id }
486486
lsp_handler.handler(opts, cb, lsp_handler.method, response.result, context, nil)
487-
elseif response.error then
488-
local name = assert(vim.lsp.get_client_by_id(client_id)).name
489-
utils.warn("%s[%s]: %s", tostring(name), lsp_handler.method, response.error.message)
487+
elseif response.error and opts.silent ~= true then
488+
-- HACK: since `client:supports_method()` always returns true for off-spec methods
489+
-- we need to test for the "prep" method to validate the error, for example stylua
490+
-- will return `true` for the first and `false` for the second call (see #2547):
491+
-- :=(vim.lsp.get_clients({bufnr=0,name="stylua"})[1]):supports_method("callHierarchy/incomingCalls")
492+
-- :=(vim.lsp.get_clients({bufnr=0,name="stylua"})[1]):supports_method("textDocument/prepareCallHierarchy")
493+
local client = assert(vim.lsp.get_client_by_id(client_id))
494+
if not lsp_handler.prep or client:supports_method(lsp_handler.prep) then
495+
utils.warn("%s[%s]: %s",
496+
tostring(client.name), lsp_handler.method, response.error.message)
497+
end
490498
end
491499
end
492500
if utils.tbl_isempty(results) then
@@ -536,7 +544,12 @@ local function gen_lsp_contents(opts)
536544
-- so we can determine if all callbacks were completed (#468)
537545
local async_opts = {
538546
num_callbacks = 0,
539-
num_clients = check_capabilities(lsp_handler, opts.silent),
547+
-- NOTE: since off-spec handlers (e.g. incomingCalls) always returns true it also always
548+
-- gets called (and errs) on async mode so even though the prepare method returns `false`
549+
-- we should take into account multiple callbacks, some of which will err (#2547)
550+
num_clients = lsp_handler.prep
551+
and #utils.lsp_get_clients({ bufnr = utils.CTX().bufnr })
552+
or check_capabilities(lsp_handler, opts.silent),
540553
-- signals the handler to not print a warning when empty result set
541554
-- is returned, important for `live_workspace_symbols` when the user
542555
-- inputs a query that returns no results
@@ -559,8 +572,12 @@ local function gen_lsp_contents(opts)
559572
async_opts.num_callbacks = async_opts.num_callbacks + 1
560573
-- did all clients send back their responses?
561574
local done = async_opts.num_callbacks == async_opts.num_clients
562-
if err and not async_opts.silent then
563-
utils.error("Error executing '%s': %s", lsp_handler.method, err)
575+
if err and async_opts.silent ~= true then
576+
-- NOTE: detailed notes in the "HACK" notes in "sync" error handling
577+
local client = assert(vim.lsp.get_client_by_id(context.client_id))
578+
if not lsp_handler.prep or client:supports_method(lsp_handler.prep) then
579+
utils.warn("%s[%s]: %s", tostring(client.name), lsp_handler.method, err)
580+
end
564581
end
565582
coroutine.resume(co, done, err, result, context, lspcfg)
566583
end)

0 commit comments

Comments
 (0)