diff options
-rw-r--r-- | runtime/doc/builtin.txt | 36 | ||||
-rw-r--r-- | runtime/lua/vim/_defaults.lua | 3 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/vimfn.lua | 42 | ||||
-rw-r--r-- | src/nvim/eval.lua | 40 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 49 | ||||
-rw-r--r-- | test/old/testdir/test_visual.vim | 206 |
6 files changed, 251 insertions, 125 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index aa9bc4836f..290fba5281 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -2918,14 +2918,25 @@ getreginfo([{regname}]) *getreginfo()* If {regname} is not specified, |v:register| is used. The returned Dictionary can be passed to |setreg()|. -getregion({pos1}, {pos2}, {type}) *getregion()* - Returns the list of strings from {pos1} to {pos2} as if it's - selected in visual mode of {type}. - For possible values of {pos1} and {pos2} see |line()|. - {type} is the selection type: - "v" for |charwise| mode - "V" for |linewise| mode - "<CTRL-V>" for |blockwise-visual| mode +getregion({pos1}, {pos2} [, {opts}]) *getregion()* + Returns the list of strings from {pos1} to {pos2} in current + buffer. + + {pos1} and {pos2} must both be |List|s with four numbers. + See |getpos()| for the format of the list. + + The optional argument {opts} is a Dict and supports the + following items: + + type Specify the selection type + (default: "v"): + "v" for |charwise| mode + "V" for |linewise| mode + "<CTRL-V>" for |blockwise-visual| mode + + exclusive If |TRUE|, use exclusive selection + for the end position 'selection'. + You can get the last selection type by |visualmode()|. If Visual mode is active, use |mode()| to get the Visual mode (e.g., in a |:vmap|). @@ -2943,16 +2954,13 @@ getregion({pos1}, {pos2}, {type}) *getregion()* - If the selection starts or ends in the middle of a multibyte character, it is not included but its selected part is substituted with spaces. - - If {pos1} or {pos2} equals "v" (see |line()|) and it is not in - |visual-mode|, an empty list is returned. - - If {pos1}, {pos2} or {type} is an invalid string, an empty - list is returned. - - If {pos1} or {pos2} is a mark in different buffer, an empty + - If {pos1} or {pos2} is not current in the buffer, an empty list is returned. Examples: > :xnoremap <CR> - \ <Cmd>echom getregion('v', '.', mode())<CR> + \ <Cmd>echom getregion( + \ getpos('v'), getpos('.'), #{ type: mode() })<CR> < getregtype([{regname}]) *getregtype()* diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua index 7cece41ed3..c8131f8eb4 100644 --- a/runtime/lua/vim/_defaults.lua +++ b/runtime/lua/vim/_defaults.lua @@ -6,7 +6,8 @@ do do local function _visual_search(cmd) assert(cmd == '/' or cmd == '?') - local chunks = vim.fn.getregion('.', 'v', vim.fn.mode()) + local chunks = + vim.fn.getregion(vim.fn.getpos('.'), vim.fn.getpos('v'), { type = vim.fn.mode() }) local esc_chunks = vim .iter(chunks) :map(function(v) diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index 779016f2d1..be89c7dd01 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -3525,13 +3525,24 @@ function vim.fn.getreg(regname, list) end --- @return table function vim.fn.getreginfo(regname) end ---- Returns the list of strings from {pos1} to {pos2} as if it's ---- selected in visual mode of {type}. ---- For possible values of {pos1} and {pos2} see |line()|. ---- {type} is the selection type: ---- "v" for |charwise| mode ---- "V" for |linewise| mode ---- "<CTRL-V>" for |blockwise-visual| mode +--- Returns the list of strings from {pos1} to {pos2} in current +--- buffer. +--- +--- {pos1} and {pos2} must both be |List|s with four numbers. +--- See |getpos()| for the format of the list. +--- +--- The optional argument {opts} is a Dict and supports the +--- following items: +--- +--- type Specify the selection type +--- (default: "v"): +--- "v" for |charwise| mode +--- "V" for |linewise| mode +--- "<CTRL-V>" for |blockwise-visual| mode +--- +--- exclusive If |TRUE|, use exclusive selection +--- for the end position 'selection'. +--- --- You can get the last selection type by |visualmode()|. --- If Visual mode is active, use |mode()| to get the Visual mode --- (e.g., in a |:vmap|). @@ -3549,23 +3560,20 @@ function vim.fn.getreginfo(regname) end --- - If the selection starts or ends in the middle of a multibyte --- character, it is not included but its selected part is --- substituted with spaces. ---- - If {pos1} or {pos2} equals "v" (see |line()|) and it is not in ---- |visual-mode|, an empty list is returned. ---- - If {pos1}, {pos2} or {type} is an invalid string, an empty ---- list is returned. ---- - If {pos1} or {pos2} is a mark in different buffer, an empty +--- - If {pos1} or {pos2} is not current in the buffer, an empty --- list is returned. --- --- Examples: > --- :xnoremap <CR> ---- \ <Cmd>echom getregion('v', '.', mode())<CR> +--- \ <Cmd>echom getregion( +--- \ getpos('v'), getpos('.'), #{ type: mode() })<CR> --- < --- ---- @param pos1 string ---- @param pos2 string ---- @param type string +--- @param pos1 table +--- @param pos2 table +--- @param opts? table --- @return string[] -function vim.fn.getregion(pos1, pos2, type) end +function vim.fn.getregion(pos1, pos2, opts) end --- The result is a String, which is type of register {regname}. --- The value will be one of: diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index e03ee77141..8dc282cd43 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -4356,16 +4356,27 @@ M.funcs = { signature = 'getreginfo([{regname}])', }, getregion = { - args = 3, + args = { 2, 3 }, base = 1, desc = [=[ - Returns the list of strings from {pos1} to {pos2} as if it's - selected in visual mode of {type}. - For possible values of {pos1} and {pos2} see |line()|. - {type} is the selection type: - "v" for |charwise| mode - "V" for |linewise| mode - "<CTRL-V>" for |blockwise-visual| mode + Returns the list of strings from {pos1} to {pos2} in current + buffer. + + {pos1} and {pos2} must both be |List|s with four numbers. + See |getpos()| for the format of the list. + + The optional argument {opts} is a Dict and supports the + following items: + + type Specify the selection type + (default: "v"): + "v" for |charwise| mode + "V" for |linewise| mode + "<CTRL-V>" for |blockwise-visual| mode + + exclusive If |TRUE|, use exclusive selection + for the end position 'selection'. + You can get the last selection type by |visualmode()|. If Visual mode is active, use |mode()| to get the Visual mode (e.g., in a |:vmap|). @@ -4383,22 +4394,19 @@ M.funcs = { - If the selection starts or ends in the middle of a multibyte character, it is not included but its selected part is substituted with spaces. - - If {pos1} or {pos2} equals "v" (see |line()|) and it is not in - |visual-mode|, an empty list is returned. - - If {pos1}, {pos2} or {type} is an invalid string, an empty - list is returned. - - If {pos1} or {pos2} is a mark in different buffer, an empty + - If {pos1} or {pos2} is not current in the buffer, an empty list is returned. Examples: > :xnoremap <CR> - \ <Cmd>echom getregion('v', '.', mode())<CR> + \ <Cmd>echom getregion( + \ getpos('v'), getpos('.'), #{ type: mode() })<CR> < ]=], name = 'getregion', - params = { { 'pos1', 'string' }, { 'pos2', 'string' }, { 'type', 'string' } }, + params = { { 'pos1', 'table' }, { 'pos2', 'table' }, { 'opts', 'table' } }, returns = 'string[]', - signature = 'getregion({pos1}, {pos2}, {type})', + signature = 'getregion({pos1}, {pos2} [, {opts}])', }, getregtype = { args = { 0, 1 }, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index c16fc1d708..3b387e3fd6 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2821,35 +2821,38 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, kListLenMayKnow); - if (tv_check_for_string_arg(argvars, 0) == FAIL - || tv_check_for_string_arg(argvars, 1) == FAIL - || tv_check_for_string_arg(argvars, 2) == FAIL) { + if (tv_check_for_list_arg(argvars, 0) == FAIL + || tv_check_for_list_arg(argvars, 1) == FAIL + || tv_check_for_opt_dict_arg(argvars, 2) == FAIL) { return; } int fnum = -1; - // NOTE: var2fpos() returns static pointer. - pos_T *fp = var2fpos(&argvars[0], true, &fnum, false); - if (fp == NULL || (fnum >= 0 && fnum != curbuf->b_fnum)) { + pos_T p1; + if (list2fpos(&argvars[0], &p1, &fnum, NULL, false) != OK + || (fnum >= 0 && fnum != curbuf->b_fnum)) { return; } - pos_T p1 = *fp; - fp = var2fpos(&argvars[1], true, &fnum, false); - if (fp == NULL || (fnum >= 0 && fnum != curbuf->b_fnum)) { + pos_T p2; + if (list2fpos(&argvars[1], &p2, &fnum, NULL, false) != OK + || (fnum >= 0 && fnum != curbuf->b_fnum)) { return; } - pos_T p2 = *fp; - - const char *pos1 = tv_get_string(&argvars[0]); - const char *pos2 = tv_get_string(&argvars[1]); - const char *type = tv_get_string(&argvars[2]); - - const bool is_visual - = (pos1[0] == 'v' && pos1[1] == NUL) || (pos2[0] == 'v' && pos2[1] == NUL); - if (is_visual && !VIsual_active) { - return; + bool is_select_exclusive; + char *type; + char default_type[] = "v"; + if (argvars[2].v_type == VAR_DICT) { + is_select_exclusive = tv_dict_get_bool(argvars[2].vval.v_dict, "exclusive", + *p_sel == 'e'); + type = tv_dict_get_string(argvars[2].vval.v_dict, "type", false); + if (type == NULL) { + type = default_type; + } + } else { + is_select_exclusive = *p_sel == 'e'; + type = default_type; } MotionType region_type = kMTUnknown; @@ -2866,6 +2869,10 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) const TriState save_virtual = virtual_op; virtual_op = virtual_active(); + // NOTE: Adjust is needed. + p1.col--; + p2.col--; + if (!lt(p1, p2)) { // swap position pos_T p = p1; @@ -2878,7 +2885,7 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (region_type == kMTCharWise) { // handle 'selection' == "exclusive" - if (*p_sel == 'e' && !equalpos(p1, p2)) { + if (is_select_exclusive && !equalpos(p1, p2)) { if (p2.coladd > 0) { p2.coladd--; } else if (p2.col > 0) { @@ -2907,7 +2914,7 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) oa.start = p1; oa.end = p2; oa.start_vcol = MIN(sc1, sc2); - if (*p_sel == 'e' && ec1 < sc2 && 0 < sc2 && ec2 > ec1) { + if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1) { oa.end_vcol = sc2 - 1; } else { oa.end_vcol = MAX(ec1, ec2); diff --git a/test/old/testdir/test_visual.vim b/test/old/testdir/test_visual.vim index 88f587a83a..2b8645d242 100644 --- a/test/old/testdir/test_visual.vim +++ b/test/old/testdir/test_visual.vim @@ -1642,80 +1642,113 @@ func Test_visual_getregion() " Visual mode call cursor(1, 1) call feedkeys("\<ESC>vjl", 'tx') - call assert_equal(['one', 'tw'], 'v'->getregion('.', 'v')) - call assert_equal(['one', 'tw'], '.'->getregion('v', 'v')) - call assert_equal(['o'], 'v'->getregion('v', 'v')) - call assert_equal(['w'], '.'->getregion('.', 'v')) - call assert_equal(['one', 'two'], '.'->getregion('v', 'V')) - call assert_equal(['on', 'tw'], '.'->getregion('v', "\<C-v>")) + call assert_equal(['one', 'tw'], + \ 'v'->getpos()->getregion(getpos('.'))) + call assert_equal(['one', 'tw'], + \ '.'->getpos()->getregion(getpos('v'))) + call assert_equal(['o'], + \ 'v'->getpos()->getregion(getpos('v'))) + call assert_equal(['w'], + \ '.'->getpos()->getregion(getpos('.'), #{ type: 'v' })) + call assert_equal(['one', 'two'], + \ getpos('.')->getregion(getpos('v'), #{ type: 'V' })) + call assert_equal(['on', 'tw'], + \ getpos('.')->getregion(getpos('v'), #{ type: "\<C-v>" })) " Line visual mode call cursor(1, 1) call feedkeys("\<ESC>Vl", 'tx') - call assert_equal(['one'], getregion('v', '.', 'V')) - call assert_equal(['one'], getregion('.', 'v', 'V')) - call assert_equal(['one'], getregion('v', 'v', 'V')) - call assert_equal(['one'], getregion('.', '.', 'V')) - call assert_equal(['on'], '.'->getregion('v', 'v')) - call assert_equal(['on'], '.'->getregion('v', "\<C-v>")) + call assert_equal(['one'], + \ getregion(getpos('v'), getpos('.'), #{ type: 'V' })) + call assert_equal(['one'], + \ getregion(getpos('.'), getpos('v'), #{ type: 'V' })) + call assert_equal(['one'], + \ getregion(getpos('v'), getpos('v'), #{ type: 'V' })) + call assert_equal(['one'], + \ getregion(getpos('.'), getpos('.'), #{ type: 'V' })) + call assert_equal(['on'], + \ getpos('.')->getregion(getpos('v'), #{ type: 'v' })) + call assert_equal(['on'], + \ getpos('.')->getregion(getpos('v'), #{ type: "\<C-v>" })) " Block visual mode call cursor(1, 1) call feedkeys("\<ESC>\<C-v>ll", 'tx') - call assert_equal(['one'], getregion('v', '.', "\<C-v>")) - call assert_equal(['one'], getregion('.', 'v', "\<C-v>")) - call assert_equal(['o'], getregion('v', 'v', "\<C-v>")) - call assert_equal(['e'], getregion('.', '.', "\<C-v>")) - call assert_equal(['one'], '.'->getregion('v', 'V')) - call assert_equal(['one'], '.'->getregion('v', 'v')) + call assert_equal(['one'], + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) + call assert_equal(['one'], + \ getregion(getpos('.'), getpos('v'), #{ type: "\<C-v>" })) + call assert_equal(['o'], + \ getregion(getpos('v'), getpos('v'), #{ type: "\<C-v>" })) + call assert_equal(['e'], + \ getregion(getpos('.'), getpos('.'), #{ type: "\<C-v>" })) + call assert_equal(['one'], + \ '.'->getpos()->getregion(getpos('v'), #{ type: 'V' })) + call assert_equal(['one'], + \ '.'->getpos()->getregion(getpos('v'), #{ type: 'v' })) " Using Marks call setpos("'a", [0, 2, 3, 0]) call cursor(1, 1) - call assert_equal(['one', 'two'], "'a"->getregion('.', 'v')) - call assert_equal(['one', 'two'], "."->getregion("'a", 'v')) - call assert_equal(['one', 'two'], "."->getregion("'a", 'V')) - call assert_equal(['two'], "'a"->getregion("'a", 'V')) - call assert_equal(['one', 'two'], "."->getregion("'a", "\<c-v>")) + call assert_equal(['one', 'two'], + \ "'a"->getpos()->getregion(getpos('.'), #{ type: 'v' })) + call assert_equal(['one', 'two'], + \ "."->getpos()->getregion(getpos("'a"), #{ type: 'v' })) + call assert_equal(['one', 'two'], + \ "."->getpos()->getregion(getpos("'a"), #{ type: 'V' })) + call assert_equal(['two'], + \ "'a"->getpos()->getregion(getpos("'a"), #{ type: 'V' })) + call assert_equal(['one', 'two'], + \ "."->getpos()->getregion(getpos("'a"), #{ type: "\<c-v>" })) + + " Using List + call cursor(1, 1) + call assert_equal(['one', 'two'], + \ [0, 2, 3, 0]->getregion(getpos('.'), #{ type: 'v' })) + call assert_equal(['one', 'two'], + \ '.'->getpos()->getregion([0, 2, 3, 0], #{ type: 'v' })) + call assert_equal(['one', 'two'], + \ '.'->getpos()->getregion([0, 2, 3, 0], #{ type: 'V' })) + call assert_equal(['two'], + \ [0, 2, 3, 0]->getregion([0, 2, 3, 0], #{ type: 'V' })) + call assert_equal(['one', 'two'], + \ '.'->getpos()->getregion([0, 2, 3, 0], #{ type: "\<c-v>" })) " Multiline with line visual mode call cursor(1, 1) call feedkeys("\<ESC>Vjj", 'tx') - call assert_equal(['one', 'two', 'three'], getregion('v', '.', 'V')) + call assert_equal(['one', 'two', 'three'], + \ getregion(getpos('v'), getpos('.'), #{ type: 'V' })) " Multiline with block visual mode call cursor(1, 1) call feedkeys("\<ESC>\<C-v>jj", 'tx') - call assert_equal(['o', 't', 't'], getregion('v', '.', "\<C-v>")) + call assert_equal(['o', 't', 't'], + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) call cursor(1, 1) call feedkeys("\<ESC>\<C-v>jj$", 'tx') - call assert_equal(['one', 'two', 'three'], getregion('v', '.', "\<C-v>")) + call assert_equal(['one', 'two', 'three'], + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) " 'virtualedit' set virtualedit=all call cursor(1, 1) call feedkeys("\<ESC>\<C-v>10ljj$", 'tx') call assert_equal(['one ', 'two ', 'three '], - \ getregion('v', '.', "\<C-v>")) + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) set virtualedit& " Invalid position call cursor(1, 1) call feedkeys("\<ESC>vjj$", 'tx') - call assert_fails("call getregion(1, 2, 'v')", 'E1174:') - call assert_fails("call getregion('.', {}, 'v')", 'E1174:') - call assert_equal([], getregion('', '.', 'v')) - call assert_equal([], getregion('.', '.', '')) - call feedkeys("\<ESC>", 'tx') - call assert_equal([], getregion('v', '.', 'v')) - - " using an unset mark - call assert_equal([], "'z"->getregion(".", 'V')) + call assert_fails("call getregion(1, 2)", 'E1211:') + call assert_fails("call getregion(getpos('.'), {})", 'E1211:') + call assert_equal([], getregion(getpos('.'), getpos('.'), #{ type: '' })) + " using the wrong type - call assert_fails(':echo "."->getregion([],"V")', 'E1174:') - call assert_fails(':echo "."->getregion("$", {})', 'E1174:') - call assert_fails(':echo [0, 1, 1, 0]->getregion("$", "v")', 'E1174:') + call assert_fails(':echo "."->getpos()->getregion("$", [])', 'E1211:') + " using a mark in another buffer new let newbuf = bufnr() @@ -1723,8 +1756,8 @@ func Test_visual_getregion() normal! GmA wincmd p call assert_equal([newbuf, 10, 1, 0], getpos("'A")) - call assert_equal([], getregion(".", "'A", 'v')) - call assert_equal([], getregion("'A", ".", 'v')) + call assert_equal([], getregion(getpos('.'), getpos("'A"), #{ type: 'v' })) + call assert_equal([], getregion(getpos("'A"), getpos('.'), #{ type: 'v' })) exe newbuf .. 'bwipe!' bwipe! @@ -1738,26 +1771,47 @@ func Test_visual_getregion() call cursor(1, 3) call feedkeys("\<Esc>\<C-v>ljj", 'xt') call assert_equal(['cd', "\u00ab ", '34'], - \ getregion('v', '.', "\<C-v>")) + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) call cursor(1, 4) call feedkeys("\<Esc>\<C-v>ljj", 'xt') call assert_equal(['de', "\U0001f1e7", '45'], - \ getregion('v', '.', "\<C-v>")) + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) call cursor(1, 5) call feedkeys("\<Esc>\<C-v>jj", 'xt') - call assert_equal(['e', ' ', '5'], getregion('v', '.', "\<C-v>")) + call assert_equal(['e', ' ', '5'], + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) call cursor(1, 1) call feedkeys("\<Esc>vj", 'xt') - call assert_equal(['abcdefghijk«', "\U0001f1e6"], getregion('v', '.', "v")) + call assert_equal(['abcdefghijk«', "\U0001f1e6"], + \ getregion(getpos('v'), getpos('.'), #{ type: 'v' })) " marks on multibyte chars set selection=exclusive call setpos("'a", [0, 1, 11, 0]) call setpos("'b", [0, 2, 16, 0]) call setpos("'c", [0, 2, 0, 0]) call cursor(1, 1) - call assert_equal(['ghijk', '🇨«🇩'], getregion("'a", "'b", "\<c-v>")) - call assert_equal(['k«', '🇦«🇧«🇨'], getregion("'a", "'b", "v")) - call assert_equal(['k«'], getregion("'a", "'c", "v")) + call assert_equal(['ghijk', '🇨«🇩'], + \ getregion(getpos("'a"), getpos("'b"), #{ type: "\<c-v>" })) + call assert_equal(['k«', '🇦«🇧«🇨'], + \ getregion(getpos("'a"), getpos("'b"), #{ type: 'v' })) + call assert_equal(['k«'], + \ getregion(getpos("'a"), getpos("'c"), #{ type: 'v' })) + + " use inclusive selection, although 'selection' is exclusive + call setpos("'a", [0, 1, 11, 0]) + call setpos("'b", [0, 1, 1, 0]) + call assert_equal(['abcdefghijk'], + \ getregion(getpos("'a"), getpos("'b"), #{ type: "\<c-v>", exclusive: v:false })) + call assert_equal(['abcdefghij'], + \ getregion(getpos("'a"), getpos("'b"), #{ type: "\<c-v>", exclusive: v:true })) + call assert_equal(['abcdefghijk'], + \ getregion(getpos("'a"), getpos("'b"), #{ type: 'v', exclusive: 0 })) + call assert_equal(['abcdefghij'], + \ getregion(getpos("'a"), getpos("'b"), #{ type: 'v', exclusive: 1 })) + call assert_equal(['abcdefghijk«'], + \ getregion(getpos("'a"), getpos("'b"), #{ type: 'V', exclusive: 0 })) + call assert_equal(['abcdefghijk«'], + \ getregion(getpos("'a"), getpos("'b"), #{ type: 'V', exclusive: 1 })) bwipe! @@ -1767,31 +1821,71 @@ func Test_visual_getregion() call setline(1, ["a\tc", "x\tz", '', '']) call cursor(1, 1) call feedkeys("\<Esc>v2l", 'xt') - call assert_equal(["a\t"], getregion('v', '.', 'v')) + call assert_equal(["a\t"], + \ getregion(getpos('v'), getpos('.'), #{ type: 'v' })) call cursor(1, 1) call feedkeys("\<Esc>v$G", 'xt') - call assert_equal(["a\tc", "x\tz", ''], getregion('v', '.', 'v')) + call assert_equal(["a\tc", "x\tz", ''], + \ getregion(getpos('v'), getpos('.'), #{ type: 'v' })) call cursor(1, 1) call feedkeys("\<Esc>v$j", 'xt') - call assert_equal(["a\tc", "x\tz"], getregion('v', '.', 'v')) + call assert_equal(["a\tc", "x\tz"], + \ getregion(getpos('v'), getpos('.'), #{ type: 'v' })) call cursor(1, 1) call feedkeys("\<Esc>\<C-v>$j", 'xt') - call assert_equal(["a\tc", "x\tz"], getregion('v', '.', "\<C-v>")) + call assert_equal(["a\tc", "x\tz"], + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) call cursor(1, 1) call feedkeys("\<Esc>\<C-v>$G", 'xt') - call assert_equal(["a", "x", '', ''], getregion('v', '.', "\<C-v>")) + call assert_equal(["a", "x", '', ''], + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) call cursor(1, 1) call feedkeys("\<Esc>wv2j", 'xt') - call assert_equal(["c", "x\tz"], getregion('v', '.', 'v')) + call assert_equal(["c", "x\tz"], + \ getregion(getpos('v'), getpos('.'), #{ type: 'v' })) + set selection& + + " Exclusive selection 2 + new + call setline(1, ["a\tc", "x\tz", '', '']) + call cursor(1, 1) + call feedkeys("\<Esc>v2l", 'xt') + call assert_equal(["a\t"], + \ getregion(getpos('v'), getpos('.'), #{ exclusive: v:true })) + call cursor(1, 1) + call feedkeys("\<Esc>v$G", 'xt') + call assert_equal(["a\tc", "x\tz", ''], + \ getregion(getpos('v'), getpos('.'), #{ exclusive: v:true })) + call cursor(1, 1) + call feedkeys("\<Esc>v$j", 'xt') + call assert_equal(["a\tc", "x\tz"], + \ getregion(getpos('v'), getpos('.'), #{ exclusive: v:true })) + call cursor(1, 1) + call feedkeys("\<Esc>\<C-v>$j", 'xt') + call assert_equal(["a\tc", "x\tz"], + \ getregion(getpos('v'), getpos('.'), + \ #{ exclusive: v:true, type: "\<C-v>" })) + call cursor(1, 1) + call feedkeys("\<Esc>\<C-v>$G", 'xt') + call assert_equal(["a", "x", '', ''], + \ getregion(getpos('v'), getpos('.'), + \ #{ exclusive: v:true, type: "\<C-v>" })) + call cursor(1, 1) + call feedkeys("\<Esc>wv2j", 'xt') + call assert_equal(["c", "x\tz"], + \ getregion(getpos('v'), getpos('.'), #{ exclusive: v:true })) " virtualedit + set selection=exclusive set virtualedit=all call cursor(1, 1) call feedkeys("\<Esc>2lv2lj", 'xt') - call assert_equal([' c', 'x '], getregion('v', '.', 'v')) + call assert_equal([' c', 'x '], + \ getregion(getpos('v'), getpos('.'), #{ type: 'v' })) call cursor(1, 1) call feedkeys("\<Esc>2l\<C-v>2l2j", 'xt') - call assert_equal([' ', ' ', ' '], getregion('v', '.', "\<C-v>")) + call assert_equal([' ', ' ', ' '], + \ getregion(getpos('v'), getpos('.'), #{ type: "\<C-v>" })) set virtualedit& set selection& |