From 729e0acd269fad50bceb0381afffacc1468c2a61 Mon Sep 17 00:00:00 2001 From: Maria Solano Date: Sun, 5 Oct 2025 15:02:00 -0700 Subject: [PATCH] feat(lsp): pass client ID in code action filter (#36046) --- runtime/doc/lsp.txt | 6 ++++-- runtime/doc/news.txt | 1 + runtime/lua/vim/lsp/buf.lua | 12 +++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index be6712ea62..eedc5ef567 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1365,8 +1365,10 @@ code_action({opts}) *vim.lsp.buf.code_action()* values like `refactor` or `quickfix`. • {triggerKind}? (`integer`) The reason why code actions were requested. - • {filter}? (`fun(x: lsp.CodeAction|lsp.Command):boolean`) - Predicate taking an `CodeAction` and returning a boolean. + • {filter}? + (`fun(x: lsp.CodeAction|lsp.Command, client_id: integer):boolean`) + Predicate taking a code action or command and the provider's + ID. If it returns false, the action is filtered out. • {apply}? (`boolean`) When set to `true`, and there is just one remaining action (after filtering), the action is applied without user query. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 234884b95c..e21ceaa949 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -252,6 +252,7 @@ LSP See |lsp-inline_completion| for quickstart instructions. • Support for `textDocument/onTypeFormatting`: |lsp-on_type_formatting| https://microsoft.github.io/language-server-protocol/specification/#textDocument_onTypeFormatting +• The filter option of |vim.lsp.buf.code_action()| now receives the client ID as an argument. LUA diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index e520b7d7c1..61bbc99ccc 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -1117,8 +1117,9 @@ end --- - {triggerKind}? (`integer`) The reason why code actions were requested. --- @field context? lsp.CodeActionContext --- ---- Predicate taking an `CodeAction` and returning a boolean. ---- @field filter? fun(x: lsp.CodeAction|lsp.Command):boolean +--- Predicate taking a code action or command and the provider's ID. +--- If it returns false, the action is filtered out. +--- @field filter? fun(x: lsp.CodeAction|lsp.Command, client_id: integer):boolean --- --- When set to `true`, and there is just one remaining action --- (after filtering), the action is applied without user query. @@ -1142,7 +1143,8 @@ end ---@param opts? vim.lsp.buf.code_action.Opts local function on_code_action_results(results, opts) ---@param a lsp.Command|lsp.CodeAction - local function action_filter(a) + ---@param client_id integer + local function action_filter(a, client_id) -- filter by specified action kind if opts and opts.context then if opts.context.only then @@ -1168,7 +1170,7 @@ local function on_code_action_results(results, opts) end end -- filter by user function - if opts and opts.filter and not opts.filter(a) then + if opts and opts.filter and not opts.filter(a, client_id) then return false end -- no filter removed this action @@ -1179,7 +1181,7 @@ local function on_code_action_results(results, opts) local actions = {} for _, result in pairs(results) do for _, action in pairs(result.result or {}) do - if action_filter(action) then + if action_filter(action, result.context.client_id) then table.insert(actions, { action = action, ctx = result.context }) end end