diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-11-21 14:25:45 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-21 14:25:45 +0800 |
commit | fec5e3ab247bcc1ced67f1d0aa7fa10f694f933b (patch) | |
tree | a869106aa7bd8fd6fae1d0315e9a1e46bfae10d8 /runtime/lua/vim/_editor.lua | |
parent | 488038580934f301c1528a14548ec0cabd16c2cd (diff) | |
download | rneovim-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.lua | 17 |
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 |