aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/buf.lua
diff options
context:
space:
mode:
authorMathias Fußenegger <mfussenegger@users.noreply.github.com>2022-07-28 19:19:07 +0200
committerGitHub <noreply@github.com>2022-07-28 19:19:07 +0200
commit98915f88b2d4b0e7f2ca643cd4648316ec9cddb8 (patch)
tree4df0fc59aa18fc22addb63b0199e15cebe35b360 /runtime/lua/vim/lsp/buf.lua
parent468b1a689a40e7eb8ee78c0d1926d149148ed951 (diff)
downloadrneovim-98915f88b2d4b0e7f2ca643cd4648316ec9cddb8.tar.gz
rneovim-98915f88b2d4b0e7f2ca643cd4648316ec9cddb8.tar.bz2
rneovim-98915f88b2d4b0e7f2ca643cd4648316ec9cddb8.zip
feat(lsp): add range option to code_action; deprecate range_code_action (#19551)
`code_action` gained extra functions (`filter` and `apply`) which `range_code_action` didn't have. To close this gap, this adds a `range` option to `code_action` and deprecates `range_code_action`. The option defaults to the current selection if in visual mode. This allows users to setup a mapping like `vim.keymap.set({'v', 'n'}, '<a-CR>', vim.lsp.buf.code_action)` `range_code_action` used to use the `<` and `>` markers to get the _last_ selection which required using a `<Esc><Cmd>lua vim.lsp.buf.range_code_action()<CR>` (note the `<ESC>`) mapping.
Diffstat (limited to 'runtime/lua/vim/lsp/buf.lua')
-rw-r--r--runtime/lua/vim/lsp/buf.lua69
1 files changed, 52 insertions, 17 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index 34ca96d1ff..7f19618e0f 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -11,8 +11,8 @@ local M = {}
--- buffer.
---
---@param method (string) LSP method name
----@param params (optional, table) Parameters to send to the server
----@param handler (optional, functionnil) See |lsp-handler|. Follows |lsp-handler-resolution|
+---@param params (table|nil) Parameters to send to the server
+---@param handler (function|nil) See |lsp-handler|. Follows |lsp-handler-resolution|
--
---@returns 2-tuple:
--- - Map of client-id:request-id pairs for all successful requests.
@@ -842,20 +842,27 @@ end
--- cursor position.
---
---@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 (table|nil):
---- List of LSP `CodeActionKind`s 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.
+--- - context: (table|nil)
+--- Corresponds to `CodeActionContext` of the LSP specification:
+--- - diagnostics (table|nil):
+--- LSP `Diagnostic[]`. Inferred from the current
+--- position if not provided.
+--- - only (table|nil):
+--- List of LSP `CodeActionKind`s used to filter the code actions.
+--- Most language servers support values like `refactor`
+--- or `quickfix`.
+--- - filter: (function|nil)
+--- Predicate 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.
+---
+--- - range: (table|nil)
+--- Range for which code actions should be requested.
+--- If in visual mode this defaults to the active selection.
+--- Table must contain `start` and `end` keys with {row, col} tuples
+--- using mark-like indexing. See |api-indexing|
+---
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
function M.code_action(options)
validate({ options = { options, 't', true } })
@@ -870,7 +877,34 @@ function M.code_action(options)
local bufnr = api.nvim_get_current_buf()
context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics(bufnr)
end
- local params = util.make_range_params()
+ local params
+ local mode = api.nvim_get_mode().mode
+ if options.range then
+ assert(type(options.range) == 'table', 'code_action range must be a table')
+ local start = assert(options.range.start, 'range must have a `start` property')
+ local end_ = assert(options.range['end'], 'range must have a `end` property')
+ params = util.make_given_range_params(start, end_)
+ elseif mode == 'v' or mode == 'V' then
+ -- [bufnum, lnum, col, off]; both row and column 1-indexed
+ local start = vim.fn.getpos('v')
+ local end_ = vim.fn.getpos('.')
+ local start_row = start[2]
+ local start_col = start[3]
+ local end_row = end_[2]
+ local end_col = end_[3]
+
+ -- A user can start visual selection at the end and move backwards
+ -- Normalize the range to start < end
+ if start_row == end_row and end_col < start_col then
+ end_col, start_col = start_col, end_col
+ elseif end_row < start_row then
+ start_row, end_row = end_row, start_row
+ start_col, end_col = end_col, start_col
+ end
+ params = util.make_given_range_params({ start_row, start_col - 1 }, { end_row, end_col - 1 })
+ else
+ params = util.make_range_params()
+ end
params.context = context
code_action_request(params, options)
end
@@ -891,6 +925,7 @@ end
---@param end_pos ({number, number}, optional) mark-indexed position.
---Defaults to the end of the last visual selection.
function M.range_code_action(context, start_pos, end_pos)
+ vim.deprecate('vim.lsp.buf.range_code_action', 'vim.lsp.buf.code_action', '0.9.0')
validate({ context = { context, 't', true } })
context = context or {}
if not context.diagnostics then