mirror of
https://github.com/neovim/neovim.git
synced 2026-08-14 03:04:54 +00:00
Merge #41106 from altermo/selection-refactor-fix
This commit is contained in:
@@ -7,6 +7,7 @@ local lsp = vim.lsp
|
||||
local validate = vim.validate
|
||||
local util = require('vim.lsp.util')
|
||||
local npcall = vim.npcall
|
||||
local Range = require('vim.treesitter._range')
|
||||
|
||||
local M = {}
|
||||
|
||||
@@ -1432,22 +1433,13 @@ local selection_ranges = nil
|
||||
|
||||
---@param range lsp.Range
|
||||
local function select_range(range)
|
||||
local start_line = range.start.line + 1
|
||||
local end_line = range['end'].line + 1
|
||||
local start_line = range.start.line
|
||||
local end_line = range['end'].line
|
||||
|
||||
local start_col = range.start.character
|
||||
local end_col = range['end'].character
|
||||
|
||||
-- If the selection ends at column 0, adjust the position to the end of the previous line.
|
||||
if end_col == 0 then
|
||||
end_line = end_line - 1
|
||||
local end_line_text = api.nvim_buf_get_lines(0, end_line - 1, end_line, true)[1]
|
||||
end_col = #end_line_text
|
||||
end
|
||||
|
||||
vim.fn.setpos("'<", { 0, start_line, start_col + 1, 0 })
|
||||
vim.fn.setpos("'>", { 0, end_line, end_col, 0 })
|
||||
vim.cmd.normal({ 'gv', bang = true })
|
||||
Range.visual_select({ start_line, start_col, end_line, end_col })
|
||||
end
|
||||
|
||||
---@param range lsp.Range
|
||||
|
||||
@@ -172,4 +172,40 @@ function M.add_bytes(source, range)
|
||||
return { start_row, start_col, start_byte, end_row, end_col, end_byte }
|
||||
end
|
||||
|
||||
---@param range Range
|
||||
function M.visual_select(range)
|
||||
local start_row, start_col, end_row, end_col = M.unpack4(range)
|
||||
|
||||
-- If the selection ends at column 0, adjust the position to the end of the previous line.
|
||||
if end_col == 0 then
|
||||
end_row = end_row - 1
|
||||
end_col = #vim.fn.getline(end_row + 1) + 1
|
||||
end
|
||||
|
||||
if vim.fn.visualmode() ~= 'v' then
|
||||
-- Reset visualmode() to 'v'
|
||||
vim.cmd.normal({ 'v\27', bang = true })
|
||||
end
|
||||
|
||||
local cursor_other_end_of_selection = false
|
||||
local visual_col, visual_row = vim.fn.col('v'), vim.fn.line('v')
|
||||
local cursor_col, cursor_row = vim.fn.col('.'), vim.fn.line('.')
|
||||
if M.cmp_pos.gt(visual_row, visual_col, cursor_row, cursor_col) then
|
||||
cursor_other_end_of_selection = true
|
||||
end
|
||||
|
||||
if vim.o.selection == 'exclusive' then
|
||||
end_col = end_col + 1
|
||||
end
|
||||
|
||||
vim.fn.setpos("'<", { 0, start_row + 1, start_col + 1, 0 })
|
||||
vim.fn.setpos("'>", { 0, end_row + 1, end_col, 0 })
|
||||
|
||||
if cursor_other_end_of_selection then
|
||||
vim.cmd.normal({ 'gvo', bang = true })
|
||||
else
|
||||
vim.cmd.normal({ 'gv', bang = true })
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -348,36 +348,6 @@ local function node_normalize_down(node)
|
||||
return node
|
||||
end
|
||||
|
||||
local function visual_select(range)
|
||||
assert(type(range) == 'table')
|
||||
local srow, scol, erow, ecol = Range.unpack4(range)
|
||||
local cursor_other_end_of_visual = false
|
||||
|
||||
local vcol, vrow = vim.fn.col('v'), vim.fn.line('v')
|
||||
local ccol, cline = vim.fn.col('.'), vim.fn.line('.')
|
||||
if vrow > cline or (vrow == cline and vcol > ccol) then
|
||||
cursor_other_end_of_visual = true
|
||||
end
|
||||
|
||||
if ecol == 0 then
|
||||
erow = erow - 1
|
||||
ecol = #vim.fn.getline(erow + 1) + 1
|
||||
end
|
||||
|
||||
if vim.fn.visualmode() ~= 'v' then
|
||||
-- reset visualmode() to 'v'
|
||||
vim.cmd.normal({ 'v\27', bang = true })
|
||||
end
|
||||
|
||||
vim.fn.setpos("'<", { 0, srow + 1, scol + 1, 0 })
|
||||
vim.fn.setpos("'>", { 0, erow + 1, ecol, 0 })
|
||||
if cursor_other_end_of_visual then
|
||||
vim.cmd.normal({ 'gvo', bang = true })
|
||||
else
|
||||
vim.cmd.normal({ 'gv', bang = true })
|
||||
end
|
||||
end
|
||||
|
||||
--- @return Range4
|
||||
local function get_selection()
|
||||
local pos1 = vim.fn.getpos('v')
|
||||
@@ -387,6 +357,10 @@ local function get_selection()
|
||||
pos1, pos2 = pos2, pos1
|
||||
end
|
||||
|
||||
if vim.o.selection == 'exclusive' then
|
||||
pos2[3] = pos2[3] - 1
|
||||
end
|
||||
|
||||
if pos2[3] == #vim.fn.getline(pos2[2]) + 1 then
|
||||
pos2[2] = pos2[2] + 1
|
||||
pos2[3] = 0
|
||||
@@ -596,7 +570,7 @@ local function repeate_apply_range(count, fn)
|
||||
end
|
||||
|
||||
if range and count ~= 0 then
|
||||
visual_select(range)
|
||||
Range.visual_select(range)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ describe('vim.lsp.selection_range', function()
|
||||
parent = {
|
||||
range = {
|
||||
start = { line = 0, character = 0 },
|
||||
['end'] = { line = 5, character = 5 },
|
||||
['end'] = { line = 4, character = 5 },
|
||||
},
|
||||
parent = nil,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user