From a9d25e94725d5cfc41c2fabff22b2284e109fa0c Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Thu, 12 May 2022 18:48:02 +0200 Subject: fix(lsp): perform client side filtering of code actions (#18392) Implement filtering of actions based on the kind when passing the 'only' parameter to code_action(). Action kinds are hierachical with a '.' as the separator, and the filter thus allows, for example, both 'quickfix' and 'quickfix.foo' when requestiong only 'quickfix'. Fix https://github.com/neovim/neovim/pull/18221#issuecomment-1110179121 --- runtime/lua/vim/lsp/buf.lua | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/lsp/buf.lua') diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 1cfbcd1259..b0bf2c6e5b 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -691,10 +691,38 @@ end --- `codeAction/resolve` local function on_code_action_results(results, ctx, options) local action_tuples = {} - local filter = options and options.filter + + ---@private + local function action_filter(a) + -- filter by specified action kind + if options and options.context and options.context.only then + if not a.kind then + return false + end + local found = false + for _, o in ipairs(options.context.only) do + -- action kinds are hierachical with . as a separator: when requesting only + -- 'quickfix' this filter allows both 'quickfix' and 'quickfix.foo', for example + if a.kind:find('^' .. o .. '$') or a.kind:find('^' .. o .. '%.') then + found = true + break + end + end + if not found then + return false + end + end + -- filter by user function + if options and options.filter and not options.filter(a) then + return false + end + -- no filter removed this action + return true + end + for client_id, result in pairs(results) do for _, action in pairs(result.result or {}) do - if not filter or filter(action) then + if action_filter(action) then table.insert(action_tuples, { client_id, action }) end end -- cgit