aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/lua/vim/lsp/buf.lua32
-rw-r--r--test/functional/fixtures/fake-lsp-server.lua15
-rw-r--r--test/functional/plugin/lsp_spec.lua21
3 files changed, 65 insertions, 3 deletions
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
diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua
index f589f5955f..86cdf4ef56 100644
--- a/test/functional/fixtures/fake-lsp-server.lua
+++ b/test/functional/fixtures/fake-lsp-server.lua
@@ -766,8 +766,21 @@ function tests.code_action_filter()
isPreferred = true,
command = 'preferred_command',
}
+ local quickfix_action = {
+ title = 'Action 3',
+ kind = 'quickfix',
+ command = 'quickfix_command',
+ }
+ local quickfix_foo_action = {
+ title = 'Action 4',
+ kind = 'quickfix.foo',
+ command = 'quickfix_foo_command',
+ }
+ expect_request('textDocument/codeAction', function()
+ return nil, { action, preferred_action, quickfix_action, quickfix_foo_action, }
+ end)
expect_request('textDocument/codeAction', function()
- return nil, { action, preferred_action, }
+ return nil, { action, preferred_action, quickfix_action, quickfix_foo_action, }
end)
notify('shutdown')
end;
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 33a8976b79..4cb7636825 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -2753,12 +2753,33 @@ describe('LSP', function()
vim.lsp.commands['executed_preferred'] = function()
end
end
+ vim.lsp.commands['quickfix_command'] = function(cmd)
+ vim.lsp.commands['executed_quickfix'] = function()
+ end
+ end
local bufnr = vim.api.nvim_get_current_buf()
vim.lsp.buf_attach_client(bufnr, TEST_RPC_CLIENT_ID)
vim.lsp.buf.code_action({ filter = function(a) return a.isPreferred end, apply = true, })
+ vim.lsp.buf.code_action({
+ -- expect to be returned actions 'quickfix' and 'quickfix.foo'
+ context = { only = {'quickfix'}, },
+ apply = true,
+ filter = function(a)
+ if a.kind == 'quickfix.foo' then
+ vim.lsp.commands['filtered_quickfix_foo'] = function() end
+ return false
+ elseif a.kind == 'quickfix' then
+ return true
+ else
+ assert(nil, 'unreachable')
+ end
+ end,
+ })
]])
elseif ctx.method == 'shutdown' then
eq('function', exec_lua[[return type(vim.lsp.commands['executed_preferred'])]])
+ eq('function', exec_lua[[return type(vim.lsp.commands['filtered_quickfix_foo'])]])
+ eq('function', exec_lua[[return type(vim.lsp.commands['executed_quickfix'])]])
client.stop()
end
end