mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(vim.region): handle multibyte inclusive selection properly (#26129)
This commit is contained in:
parent
4880385809
commit
fec5e3ab24
@ -1728,7 +1728,7 @@ vim.region({bufnr}, {pos1}, {pos2}, {regtype}, {inclusive})
|
|||||||
• {pos2} integer[]|string End of region as a (line, column) tuple
|
• {pos2} integer[]|string End of region as a (line, column) tuple
|
||||||
or |getpos()|-compatible string
|
or |getpos()|-compatible string
|
||||||
• {regtype} (string) |setreg()|-style selection type
|
• {regtype} (string) |setreg()|-style selection type
|
||||||
• {inclusive} (boolean) Controls whether `pos2` column is inclusive
|
• {inclusive} (boolean) Controls whether the ending column is inclusive
|
||||||
(see also 'selection').
|
(see also 'selection').
|
||||||
|
|
||||||
Return: ~
|
Return: ~
|
||||||
|
@ -492,7 +492,7 @@ end
|
|||||||
---@param pos1 integer[]|string Start of region as a (line, column) tuple or |getpos()|-compatible string
|
---@param pos1 integer[]|string Start of region as a (line, column) tuple or |getpos()|-compatible string
|
||||||
---@param pos2 integer[]|string End of region as a (line, column) tuple or |getpos()|-compatible string
|
---@param pos2 integer[]|string End of region as a (line, column) tuple or |getpos()|-compatible string
|
||||||
---@param regtype string \|setreg()|-style selection type
|
---@param regtype string \|setreg()|-style selection type
|
||||||
---@param inclusive boolean Controls whether `pos2` column is inclusive (see also 'selection').
|
---@param inclusive boolean Controls whether the ending column is inclusive (see also 'selection').
|
||||||
---@return table region Dict of the form `{linenr = {startcol,endcol}}`. `endcol` is exclusive, and
|
---@return table region Dict of the form `{linenr = {startcol,endcol}}`. `endcol` is exclusive, and
|
||||||
---whole lines are returned as `{startcol,endcol} = {0,-1}`.
|
---whole lines are returned as `{startcol,endcol} = {0,-1}`.
|
||||||
function vim.region(bufnr, pos1, pos2, regtype, inclusive)
|
function vim.region(bufnr, pos1, pos2, regtype, inclusive)
|
||||||
@ -502,11 +502,11 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive)
|
|||||||
|
|
||||||
if type(pos1) == 'string' then
|
if type(pos1) == 'string' then
|
||||||
local pos = vim.fn.getpos(pos1)
|
local pos = vim.fn.getpos(pos1)
|
||||||
pos1 = { pos[2] - 1, pos[3] - 1 + pos[4] }
|
pos1 = { pos[2] - 1, pos[3] - 1 }
|
||||||
end
|
end
|
||||||
if type(pos2) == 'string' then
|
if type(pos2) == 'string' then
|
||||||
local pos = vim.fn.getpos(pos2)
|
local pos = vim.fn.getpos(pos2)
|
||||||
pos2 = { pos[2] - 1, pos[3] - 1 + pos[4] }
|
pos2 = { pos[2] - 1, pos[3] - 1 }
|
||||||
end
|
end
|
||||||
|
|
||||||
if pos1[1] > pos2[1] or (pos1[1] == pos2[1] and pos1[2] > pos2[2]) then
|
if pos1[1] > pos2[1] or (pos1[1] == pos2[1] and pos1[2] > pos2[2]) then
|
||||||
@ -525,9 +525,8 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive)
|
|||||||
|
|
||||||
-- in case of block selection, columns need to be adjusted for non-ASCII characters
|
-- in case of block selection, columns need to be adjusted for non-ASCII characters
|
||||||
-- TODO: handle double-width characters
|
-- TODO: handle double-width characters
|
||||||
local bufline
|
|
||||||
if regtype:byte() == 22 then
|
if regtype:byte() == 22 then
|
||||||
bufline = vim.api.nvim_buf_get_lines(bufnr, pos1[1], pos1[1] + 1, true)[1]
|
local bufline = vim.api.nvim_buf_get_lines(bufnr, pos1[1], pos1[1] + 1, true)[1]
|
||||||
pos1[2] = vim.str_utfindex(bufline, pos1[2])
|
pos1[2] = vim.str_utfindex(bufline, pos1[2])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -538,7 +537,7 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive)
|
|||||||
c1 = pos1[2]
|
c1 = pos1[2]
|
||||||
c2 = c1 + regtype:sub(2)
|
c2 = c1 + regtype:sub(2)
|
||||||
-- and adjust for non-ASCII characters
|
-- and adjust for non-ASCII characters
|
||||||
bufline = vim.api.nvim_buf_get_lines(bufnr, l, l + 1, true)[1]
|
local bufline = vim.api.nvim_buf_get_lines(bufnr, l, l + 1, true)[1]
|
||||||
local utflen = vim.str_utfindex(bufline, #bufline)
|
local utflen = vim.str_utfindex(bufline, #bufline)
|
||||||
if c1 <= utflen then
|
if c1 <= utflen then
|
||||||
c1 = vim.str_byteindex(bufline, c1)
|
c1 = vim.str_byteindex(bufline, c1)
|
||||||
@ -555,7 +554,11 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive)
|
|||||||
c2 = -1
|
c2 = -1
|
||||||
else
|
else
|
||||||
c1 = (l == pos1[1]) and pos1[2] or 0
|
c1 = (l == pos1[1]) and pos1[2] or 0
|
||||||
c2 = (l == pos2[1]) and (pos2[2] + (inclusive and 1 or 0)) or -1
|
if inclusive and l == pos2[1] then
|
||||||
|
local bufline = vim.api.nvim_buf_get_lines(bufnr, pos2[1], pos2[1] + 1, true)[1]
|
||||||
|
pos2[2] = vim.fn.byteidx(bufline, vim.fn.charidx(bufline, pos2[2]) + 1)
|
||||||
|
end
|
||||||
|
c2 = (l == pos2[1]) and pos2[2] or -1
|
||||||
end
|
end
|
||||||
table.insert(region, l, { c1, c2 })
|
table.insert(region, l, { c1, c2 })
|
||||||
end
|
end
|
||||||
|
@ -2395,7 +2395,14 @@ describe('lua stdlib', function()
|
|||||||
text tαxt txtα tex
|
text tαxt txtα tex
|
||||||
text tαxt tαxt
|
text tαxt tαxt
|
||||||
]]))
|
]]))
|
||||||
eq({5,15}, exec_lua[[ return vim.region(0,{1,5},{1,14},'v',true)[1] ]])
|
eq({5,13}, exec_lua[[ return vim.region(0,{0,5},{0,13},'v',false)[0] ]])
|
||||||
|
eq({5,15}, exec_lua[[ return vim.region(0,{0,5},{0,13},'v',true)[0] ]])
|
||||||
|
eq({5,15}, exec_lua[[ return vim.region(0,{0,5},{0,14},'v',true)[0] ]])
|
||||||
|
eq({5,15}, exec_lua[[ return vim.region(0,{0,5},{0,15},'v',false)[0] ]])
|
||||||
|
eq({5,17}, exec_lua[[ return vim.region(0,{0,5},{0,15},'v',true)[0] ]])
|
||||||
|
eq({5,17}, exec_lua[[ return vim.region(0,{0,5},{0,16},'v',true)[0] ]])
|
||||||
|
eq({5,17}, exec_lua[[ return vim.region(0,{0,5},{0,17},'v',false)[0] ]])
|
||||||
|
eq({5,18}, exec_lua[[ return vim.region(0,{0,5},{0,17},'v',true)[0] ]])
|
||||||
end)
|
end)
|
||||||
it('blockwise', function()
|
it('blockwise', function()
|
||||||
insert([[αα]])
|
insert([[αα]])
|
||||||
|
Loading…
Reference in New Issue
Block a user