diff options
author | Fredrik Ekre <ekrefredrik@gmail.com> | 2022-04-30 10:14:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-30 10:14:31 +0200 |
commit | df09e03cf74337675751c3240069a26aec75fa3b (patch) | |
tree | 063e2a54d2a82835587ea981ac2166bb1cb87212 /runtime/lua/vim/lsp/buf.lua | |
parent | de2232878fb95bdb84f8219c7cf1d7f2c2828086 (diff) | |
download | rneovim-df09e03cf74337675751c3240069a26aec75fa3b.tar.gz rneovim-df09e03cf74337675751c3240069a26aec75fa3b.tar.bz2 rneovim-df09e03cf74337675751c3240069a26aec75fa3b.zip |
feat(lsp): options to filter and auto-apply code actions (#18221)
Implement two new options to vim.lsp.buf.code_action():
- filter (function): predicate taking an Action as input, and returning
a boolean.
- apply (boolean): when set to true, and there is just one remaining
action (after filtering), the action is applied without user query.
These options can, for example, be used to filter out, and automatically
apply, the action indicated by the server to be preferred:
vim.lsp.buf.code_action({
filter = function(action)
return action.isPreferred
end,
apply = true,
})
Fix #17514.
Diffstat (limited to 'runtime/lua/vim/lsp/buf.lua')
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index eb7ec579f1..00919c6b04 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -491,11 +491,14 @@ end --- from multiple clients to have 1 single UI prompt for the user, yet we still --- need to be able to link a `CodeAction|Command` to the right client for --- `codeAction/resolve` -local function on_code_action_results(results, ctx) +local function on_code_action_results(results, ctx, options) local action_tuples = {} + local filter = options and options.filter for client_id, result in pairs(results) do for _, action in pairs(result.result or {}) do - table.insert(action_tuples, { client_id, action }) + if not filter or filter(action) then + table.insert(action_tuples, { client_id, action }) + end end end if #action_tuples == 0 then @@ -557,6 +560,13 @@ local function on_code_action_results(results, ctx) end end + -- If options.apply is given, and there are just one remaining code action, + -- apply it directly without querying the user. + if options and options.apply and #action_tuples == 1 then + on_user_choice(action_tuples[1]) + return + end + vim.ui.select(action_tuples, { prompt = 'Code actions:', kind = 'codeaction', @@ -571,35 +581,49 @@ end --- Requests code actions from all clients and calls the handler exactly once --- with all aggregated results ---@private -local function code_action_request(params) +local function code_action_request(params, options) local bufnr = vim.api.nvim_get_current_buf() local method = 'textDocument/codeAction' vim.lsp.buf_request_all(bufnr, method, params, function(results) - on_code_action_results(results, { bufnr = bufnr, method = method, params = params }) + local ctx = { bufnr = bufnr, method = method, params = params} + on_code_action_results(results, ctx, options) end) end --- Selects a code action available at the current --- cursor position. --- ----@param context table|nil `CodeActionContext` of the LSP specification: ---- - diagnostics: (table|nil) ---- LSP `Diagnostic[]`. Inferred from the current ---- position if not provided. ---- - only: (string|nil) ---- LSP `CodeActionKind` used to filter the code actions. ---- Most language servers support values like `refactor` ---- or `quickfix`. +---@param options table|nil Optional table which holds the following optional fields: +--- - context (table|nil): +--- Corresponds to `CodeActionContext` of the LSP specification: +--- - diagnostics (table|nil): +--- LSP `Diagnostic[]`. Inferred from the current +--- position if not provided. +--- - only (string|nil): +--- LSP `CodeActionKind` used to filter the code actions. +--- Most language servers support values like `refactor` +--- or `quickfix`. +--- - filter (function|nil): +--- Predicate function taking an `CodeAction` and returning a boolean. +--- - apply (boolean|nil): +--- When set to `true`, and there is just one remaining action +--- (after filtering), the action is applied without user query. ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction -function M.code_action(context) - validate { context = { context, 't', true } } - context = context or {} +function M.code_action(options) + validate { options = { options, 't', true } } + options = options or {} + -- Detect old API call code_action(context) which should now be + -- code_action({ context = context} ) + if options.diagnostics or options.only then + options = { options = options } + end + local context = options.context or {} if not context.diagnostics then context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics() end local params = util.make_range_params() params.context = context - code_action_request(params) + code_action_request(params, options) end --- Performs |vim.lsp.buf.code_action()| for a given range. |