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([[αα]])