aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-11-21 14:25:45 +0800
committerGitHub <noreply@github.com>2023-11-21 14:25:45 +0800
commitfec5e3ab247bcc1ced67f1d0aa7fa10f694f933b (patch)
treea869106aa7bd8fd6fae1d0315e9a1e46bfae10d8
parent488038580934f301c1528a14548ec0cabd16c2cd (diff)
downloadrneovim-fec5e3ab247bcc1ced67f1d0aa7fa10f694f933b.tar.gz
rneovim-fec5e3ab247bcc1ced67f1d0aa7fa10f694f933b.tar.bz2
rneovim-fec5e3ab247bcc1ced67f1d0aa7fa10f694f933b.zip
fix(vim.region): handle multibyte inclusive selection properly (#26129)
-rw-r--r--runtime/doc/lua.txt2
-rw-r--r--runtime/lua/vim/_editor.lua17
-rw-r--r--test/functional/lua/vim_spec.lua9
3 files changed, 19 insertions, 9 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 596b58d4ff..b155e646ab 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -1728,7 +1728,7 @@ vim.region({bufnr}, {pos1}, {pos2}, {regtype}, {inclusive})
• {pos2} integer[]|string End of region as a (line, column) tuple
or |getpos()|-compatible string
• {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').
Return: ~
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index 98a1ce79ed..12b632075d 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -492,7 +492,7 @@ end
---@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 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
---whole lines are returned as `{startcol,endcol} = {0,-1}`.
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
local pos = vim.fn.getpos(pos1)
- pos1 = { pos[2] - 1, pos[3] - 1 + pos[4] }
+ pos1 = { pos[2] - 1, pos[3] - 1 }
end
if type(pos2) == 'string' then
local pos = vim.fn.getpos(pos2)
- pos2 = { pos[2] - 1, pos[3] - 1 + pos[4] }
+ pos2 = { pos[2] - 1, pos[3] - 1 }
end
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
-- TODO: handle double-width characters
- local bufline
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])
end
@@ -538,7 +537,7 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive)
c1 = pos1[2]
c2 = c1 + regtype:sub(2)
-- 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)
if c1 <= utflen then
c1 = vim.str_byteindex(bufline, c1)
@@ -555,7 +554,11 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive)
c2 = -1
else
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
table.insert(region, l, { c1, c2 })
end
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index a8a72f20c9..1533a1823f 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -2395,7 +2395,14 @@ describe('lua stdlib', function()
text tαxt txtα tex
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)
it('blockwise', function()
insert([[αα]])