mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(lsp): use line start/end for visual line selection (#22632)
Fixes https://github.com/neovim/neovim/issues/22629
This commit is contained in:
parent
314f20a44f
commit
d15abd1be4
@ -118,8 +118,10 @@ function M.completion(context)
|
|||||||
end
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
|
---@param bufnr integer
|
||||||
|
---@param mode "v"|"V"
|
||||||
---@return table {start={row, col}, end={row, col}} using (1, 0) indexing
|
---@return table {start={row, col}, end={row, col}} using (1, 0) indexing
|
||||||
local function range_from_selection()
|
local function range_from_selection(bufnr, mode)
|
||||||
-- TODO: Use `vim.region()` instead https://github.com/neovim/neovim/pull/13896
|
-- TODO: Use `vim.region()` instead https://github.com/neovim/neovim/pull/13896
|
||||||
|
|
||||||
-- [bufnum, lnum, col, off]; both row and column 1-indexed
|
-- [bufnum, lnum, col, off]; both row and column 1-indexed
|
||||||
@ -138,6 +140,11 @@ local function range_from_selection()
|
|||||||
start_row, end_row = end_row, start_row
|
start_row, end_row = end_row, start_row
|
||||||
start_col, end_col = end_col, start_col
|
start_col, end_col = end_col, start_col
|
||||||
end
|
end
|
||||||
|
if mode == 'V' then
|
||||||
|
start_col = 1
|
||||||
|
local lines = api.nvim_buf_get_lines(bufnr, end_row - 1, end_row, true)
|
||||||
|
end_col = #lines[1]
|
||||||
|
end
|
||||||
return {
|
return {
|
||||||
['start'] = { start_row, start_col - 1 },
|
['start'] = { start_row, start_col - 1 },
|
||||||
['end'] = { end_row, end_col - 1 },
|
['end'] = { end_row, end_col - 1 },
|
||||||
@ -200,7 +207,7 @@ function M.format(options)
|
|||||||
local mode = api.nvim_get_mode().mode
|
local mode = api.nvim_get_mode().mode
|
||||||
local range = options.range
|
local range = options.range
|
||||||
if not range and mode == 'v' or mode == 'V' then
|
if not range and mode == 'v' or mode == 'V' then
|
||||||
range = range_from_selection()
|
range = range_from_selection(bufnr, mode)
|
||||||
end
|
end
|
||||||
local method = range and 'textDocument/rangeFormatting' or 'textDocument/formatting'
|
local method = range and 'textDocument/rangeFormatting' or 'textDocument/formatting'
|
||||||
|
|
||||||
@ -772,7 +779,7 @@ function M.code_action(options)
|
|||||||
local end_ = assert(options.range['end'], 'range must have a `end` property')
|
local end_ = assert(options.range['end'], 'range must have a `end` property')
|
||||||
params = util.make_given_range_params(start, end_)
|
params = util.make_given_range_params(start, end_)
|
||||||
elseif mode == 'v' or mode == 'V' then
|
elseif mode == 'v' or mode == 'V' then
|
||||||
local range = range_from_selection()
|
local range = range_from_selection(0, mode)
|
||||||
params = util.make_given_range_params(range.start, range['end'])
|
params = util.make_given_range_params(range.start, range['end'])
|
||||||
else
|
else
|
||||||
params = util.make_range_params()
|
params = util.make_range_params()
|
||||||
|
@ -3554,6 +3554,7 @@ describe('LSP', function()
|
|||||||
vim.cmd.normal('v')
|
vim.cmd.normal('v')
|
||||||
vim.api.nvim_win_set_cursor(0, { 2, 3 })
|
vim.api.nvim_win_set_cursor(0, { 2, 3 })
|
||||||
vim.lsp.buf.format({ bufnr = bufnr, false })
|
vim.lsp.buf.format({ bufnr = bufnr, false })
|
||||||
|
vim.lsp.stop_client(client_id)
|
||||||
return server.messages
|
return server.messages
|
||||||
]])
|
]])
|
||||||
eq("textDocument/rangeFormatting", result[3].method)
|
eq("textDocument/rangeFormatting", result[3].method)
|
||||||
@ -3563,6 +3564,52 @@ describe('LSP', function()
|
|||||||
}
|
}
|
||||||
eq(expected_range, result[3].params.range)
|
eq(expected_range, result[3].params.range)
|
||||||
end)
|
end)
|
||||||
|
it('format formats range in visual line mode', function()
|
||||||
|
exec_lua(create_server_definition)
|
||||||
|
local result = exec_lua([[
|
||||||
|
local server = _create_server({ capabilities = {
|
||||||
|
documentFormattingProvider = true,
|
||||||
|
documentRangeFormattingProvider = true,
|
||||||
|
}})
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
|
||||||
|
vim.api.nvim_win_set_buf(0, bufnr)
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, {'foo', 'bar baz'})
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 1, 2 })
|
||||||
|
vim.cmd.normal('V')
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 2, 1 })
|
||||||
|
vim.lsp.buf.format({ bufnr = bufnr, false })
|
||||||
|
|
||||||
|
-- Format again with visual lines going from bottom to top
|
||||||
|
-- Must result in same formatting
|
||||||
|
vim.cmd.normal("<ESC>")
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 2, 1 })
|
||||||
|
vim.cmd.normal('V')
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 1, 2 })
|
||||||
|
vim.lsp.buf.format({ bufnr = bufnr, false })
|
||||||
|
|
||||||
|
vim.lsp.stop_client(client_id)
|
||||||
|
return server.messages
|
||||||
|
]])
|
||||||
|
local expected_methods = {
|
||||||
|
"initialize",
|
||||||
|
"initialized",
|
||||||
|
"textDocument/rangeFormatting",
|
||||||
|
"$/cancelRequest",
|
||||||
|
"textDocument/rangeFormatting",
|
||||||
|
"$/cancelRequest",
|
||||||
|
"shutdown",
|
||||||
|
"exit",
|
||||||
|
}
|
||||||
|
eq(expected_methods, vim.tbl_map(function(x) return x.method end, result))
|
||||||
|
-- uses first column of start line and last column of end line
|
||||||
|
local expected_range = {
|
||||||
|
start = { line = 0, character = 0 },
|
||||||
|
['end'] = { line = 1, character = 7 },
|
||||||
|
}
|
||||||
|
eq(expected_range, result[3].params.range)
|
||||||
|
eq(expected_range, result[5].params.range)
|
||||||
|
end)
|
||||||
it('Aborts with notify if no clients support requested method', function()
|
it('Aborts with notify if no clients support requested method', function()
|
||||||
exec_lua(create_server_definition)
|
exec_lua(create_server_definition)
|
||||||
exec_lua([[
|
exec_lua([[
|
||||||
|
Loading…
Reference in New Issue
Block a user