aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/_editor.lua
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 /runtime/lua/vim/_editor.lua
parent488038580934f301c1528a14548ec0cabd16c2cd (diff)
downloadrneovim-fec5e3ab247bcc1ced67f1d0aa7fa10f694f933b.tar.gz
rneovim-fec5e3ab247bcc1ced67f1d0aa7fa10f694f933b.tar.bz2
rneovim-fec5e3ab247bcc1ced67f1d0aa7fa10f694f933b.zip
fix(vim.region): handle multibyte inclusive selection properly (#26129)
Diffstat (limited to 'runtime/lua/vim/_editor.lua')
-rw-r--r--runtime/lua/vim/_editor.lua17
1 files changed, 10 insertions, 7 deletions
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