aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/builtin.txt17
-rw-r--r--runtime/doc/usr_41.txt1
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua22
-rw-r--r--src/nvim/eval.lua25
-rw-r--r--src/nvim/eval/funcs.c228
-rw-r--r--test/old/testdir/test_visual.vim77
6 files changed, 299 insertions, 71 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index bbbabea2a4..0f0e33b54e 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -2969,6 +2969,23 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()*
\ getpos('v'), getpos('.'), #{ type: mode() })<CR>
<
+getregionpos({pos1}, {pos2} [, {opts}]) *getregionpos()*
+ Same as |getregion()|, but returns a list of positions
+ describing the buffer text segments bound by {pos1} and
+ {pos2}.
+ The segments are a pair of positions for every line: >
+ [[{start_pos}, {end_pos}], ...]
+<
+ The position is a |List| with four numbers:
+ [bufnum, lnum, col, off]
+ "bufnum" is the buffer number.
+ "lnum" and "col" are the position in the buffer. The first
+ column is 1.
+ The "off" number is zero, unless 'virtualedit' is used. Then
+ it is the offset in screen columns from the start of the
+ character. E.g., a position within a <Tab> or after the last
+ character.
+
getregtype([{regname}]) *getregtype()*
The result is a String, which is type of register {regname}.
The value will be one of:
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 9515548cc5..ab2eecdfaf 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -794,6 +794,7 @@ Cursor and mark position: *cursor-functions* *mark-functions*
Working with text in the current buffer: *text-functions*
getline() get a line or list of lines from the buffer
getregion() get a region of text from the buffer
+ getregionpos() get a list of positions for a region
setline() replace a line in the buffer
append() append line or list of lines in the buffer
indent() indent of a specific line
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index 853f354275..fbcdd52116 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -3581,6 +3581,28 @@ function vim.fn.getreginfo(regname) end
--- @return string[]
function vim.fn.getregion(pos1, pos2, opts) end
+--- Same as |getregion()|, but returns a list of positions
+--- describing the buffer text segments bound by {pos1} and
+--- {pos2}.
+--- The segments are a pair of positions for every line: >
+--- [[{start_pos}, {end_pos}], ...]
+--- <
+--- The position is a |List| with four numbers:
+--- [bufnum, lnum, col, off]
+--- "bufnum" is the buffer number.
+--- "lnum" and "col" are the position in the buffer. The first
+--- column is 1.
+--- The "off" number is zero, unless 'virtualedit' is used. Then
+--- it is the offset in screen columns from the start of the
+--- character. E.g., a position within a <Tab> or after the last
+--- character.
+---
+--- @param pos1 table
+--- @param pos2 table
+--- @param opts? table
+--- @return integer[][][]
+function vim.fn.getregionpos(pos1, pos2, opts) end
+
--- The result is a String, which is type of register {regname}.
--- The value will be one of:
--- "v" for |charwise| text
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index f0eeca2f10..0653a51f96 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -4414,6 +4414,31 @@ M.funcs = {
returns = 'string[]',
signature = 'getregion({pos1}, {pos2} [, {opts}])',
},
+ getregionpos = {
+ args = { 2, 3 },
+ base = 1,
+ desc = [=[
+ Same as |getregion()|, but returns a list of positions
+ describing the buffer text segments bound by {pos1} and
+ {pos2}.
+ The segments are a pair of positions for every line: >
+ [[{start_pos}, {end_pos}], ...]
+ <
+ The position is a |List| with four numbers:
+ [bufnum, lnum, col, off]
+ "bufnum" is the buffer number.
+ "lnum" and "col" are the position in the buffer. The first
+ column is 1.
+ The "off" number is zero, unless 'virtualedit' is used. Then
+ it is the offset in screen columns from the start of the
+ character. E.g., a position within a <Tab> or after the last
+ character.
+ ]=],
+ name = 'getregionpos',
+ params = { { 'pos1', 'table' }, { 'pos2', 'table' }, { 'opts', 'table' } },
+ returns = 'integer[][][]',
+ signature = 'getregionpos({pos1}, {pos2} [, {opts}])',
+ },
getregtype = {
args = { 0, 1 },
base = 1,
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 0b4b79c6ca..2667f4a694 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -2823,24 +2823,25 @@ static char *block_def2str(struct block_def *bd)
return ret;
}
-/// "getregion()" function
-static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+static int getregionpos(typval_T *argvars, typval_T *rettv, pos_T *p1, pos_T *p2,
+ bool *const inclusive, MotionType *region_type, oparg_T *oa,
+ int *const fnum)
+ FUNC_ATTR_NONNULL_ALL
{
tv_list_alloc_ret(rettv, kListLenMayKnow);
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;
+ return FAIL;
}
int fnum1 = -1;
int fnum2 = -1;
- pos_T p1, p2;
- if (list2fpos(&argvars[0], &p1, &fnum1, NULL, false) != OK
- || list2fpos(&argvars[1], &p2, &fnum2, NULL, false) != OK
+ if (list2fpos(&argvars[0], p1, &fnum1, NULL, false) != OK
+ || list2fpos(&argvars[1], p2, &fnum2, NULL, false) != OK
|| fnum1 != fnum2) {
- return;
+ return FAIL;
}
bool is_select_exclusive;
@@ -2858,108 +2859,123 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
type = default_type;
}
- MotionType region_type = kMTUnknown;
if (type[0] == 'v' && type[1] == NUL) {
- region_type = kMTCharWise;
+ *region_type = kMTCharWise;
} else if (type[0] == 'V' && type[1] == NUL) {
- region_type = kMTLineWise;
+ *region_type = kMTLineWise;
} else if (type[0] == Ctrl_V && type[1] == NUL) {
- region_type = kMTBlockWise;
+ *region_type = kMTBlockWise;
} else {
semsg(_(e_invargNval), "type", type);
- return;
+ return FAIL;
}
buf_T *findbuf = fnum1 != 0 ? buflist_findnr(fnum1) : curbuf;
+ *fnum = fnum1 != 0 ? fnum1 : curbuf->b_fnum;
if (findbuf == NULL || findbuf->b_ml.ml_mfp == NULL) {
emsg(_(e_buffer_is_not_loaded));
- return;
+ return FAIL;
}
- if (p1.lnum < 1 || p1.lnum > findbuf->b_ml.ml_line_count) {
- semsg(_(e_invalid_line_number_nr), p1.lnum);
- return;
+ if (p1->lnum < 1 || p1->lnum > findbuf->b_ml.ml_line_count) {
+ semsg(_(e_invalid_line_number_nr), p1->lnum);
+ return FAIL;
}
- if (p1.col == MAXCOL) {
- p1.col = ml_get_buf_len(findbuf, p1.lnum) + 1;
- } else if (p1.col < 1 || p1.col > ml_get_buf_len(findbuf, p1.lnum) + 1) {
- semsg(_(e_invalid_column_number_nr), p1.col);
- return;
+ if (p1->col == MAXCOL) {
+ p1->col = ml_get_buf_len(findbuf, p1->lnum) + 1;
+ } else if (p1->col < 1 || p1->col > ml_get_buf_len(findbuf, p1->lnum) + 1) {
+ semsg(_(e_invalid_column_number_nr), p1->col);
+ return FAIL;
}
- if (p2.lnum < 1 || p2.lnum > findbuf->b_ml.ml_line_count) {
- semsg(_(e_invalid_line_number_nr), p2.lnum);
- return;
+ if (p2->lnum < 1 || p2->lnum > findbuf->b_ml.ml_line_count) {
+ semsg(_(e_invalid_line_number_nr), p2->lnum);
+ return FAIL;
}
- if (p2.col == MAXCOL) {
- p2.col = ml_get_buf_len(findbuf, p2.lnum) + 1;
- } else if (p2.col < 1 || p2.col > ml_get_buf_len(findbuf, p2.lnum) + 1) {
- semsg(_(e_invalid_column_number_nr), p2.col);
- return;
+ if (p2->col == MAXCOL) {
+ p2->col = ml_get_buf_len(findbuf, p2->lnum) + 1;
+ } else if (p2->col < 1 || p2->col > ml_get_buf_len(findbuf, p2->lnum) + 1) {
+ semsg(_(e_invalid_column_number_nr), p2->col);
+ return FAIL;
}
- buf_T *const save_curbuf = curbuf;
curbuf = findbuf;
curwin->w_buffer = curbuf;
- const TriState save_virtual = virtual_op;
virtual_op = virtual_active(curwin);
- // NOTE: Adjust is needed.
- p1.col--;
- p2.col--;
+ // NOTE: Adjustment is needed.
+ p1->col--;
+ p2->col--;
- if (!lt(p1, p2)) {
+ if (!lt(*p1, *p2)) {
// swap position
- pos_T p = p1;
- p1 = p2;
- p2 = p;
+ pos_T p = *p1;
+ *p1 = *p2;
+ *p2 = p;
}
- oparg_T oa;
- bool inclusive = true;
-
- if (region_type == kMTCharWise) {
+ if (*region_type == kMTCharWise) {
// handle 'selection' == "exclusive"
- if (is_select_exclusive && !equalpos(p1, p2)) {
- if (p2.coladd > 0) {
- p2.coladd--;
- } else if (p2.col > 0) {
- p2.col--;
- mark_mb_adjustpos(curbuf, &p2);
- } else if (p2.lnum > 1) {
- p2.lnum--;
- p2.col = ml_get_len(p2.lnum);
- if (p2.col > 0) {
- p2.col--;
- mark_mb_adjustpos(curbuf, &p2);
+ if (is_select_exclusive && !equalpos(*p1, *p2)) {
+ if (p2->coladd > 0) {
+ p2->coladd--;
+ } else if (p2->col > 0) {
+ p2->col--;
+ mark_mb_adjustpos(curbuf, p2);
+ } else if (p2->lnum > 1) {
+ p2->lnum--;
+ p2->col = ml_get_len(p2->lnum);
+ if (p2->col > 0) {
+ p2->col--;
+ mark_mb_adjustpos(curbuf, p2);
}
}
}
// if fp2 is on NUL (empty line) inclusive becomes false
- if (*ml_get_pos(&p2) == NUL && !virtual_op) {
- inclusive = false;
+ if (*ml_get_pos(p2) == NUL && !virtual_op) {
+ *inclusive = false;
}
- } else if (region_type == kMTBlockWise) {
+ } else if (*region_type == kMTBlockWise) {
colnr_T sc1, ec1, sc2, ec2;
- getvvcol(curwin, &p1, &sc1, NULL, &ec1);
- getvvcol(curwin, &p2, &sc2, NULL, &ec2);
- oa.motion_type = kMTBlockWise;
- oa.inclusive = true;
- oa.op_type = OP_NOP;
- oa.start = p1;
- oa.end = p2;
- oa.start_vcol = MIN(sc1, sc2);
+ getvvcol(curwin, p1, &sc1, NULL, &ec1);
+ getvvcol(curwin, p2, &sc2, NULL, &ec2);
+ oa->motion_type = kMTBlockWise;
+ oa->inclusive = true;
+ oa->op_type = OP_NOP;
+ oa->start = *p1;
+ oa->end = *p2;
+ oa->start_vcol = MIN(sc1, sc2);
if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1) {
- oa.end_vcol = sc2 - 1;
+ oa->end_vcol = sc2 - 1;
} else {
- oa.end_vcol = MAX(ec1, ec2);
+ oa->end_vcol = MAX(ec1, ec2);
}
}
// Include the trailing byte of a multi-byte char.
- int l = utfc_ptr2len(ml_get_pos(&p2));
+ int l = utfc_ptr2len(ml_get_pos(p2));
if (l > 1) {
- p2.col += l - 1;
+ p2->col += l - 1;
+ }
+
+ return OK;
+}
+
+/// "getregion()" function
+static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+{
+ buf_T *const save_curbuf = curbuf;
+ const TriState save_virtual = virtual_op;
+
+ pos_T p1, p2;
+ bool inclusive = true;
+ MotionType region_type = kMTUnknown;
+ oparg_T oa;
+ int fnum;
+
+ if (getregionpos(argvars, rettv,
+ &p1, &p2, &inclusive, &region_type, &oa, &fnum) == FAIL) {
+ return;
}
for (linenr_T lnum = p1.lnum; lnum <= p2.lnum; lnum++) {
@@ -2983,6 +2999,80 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
tv_list_append_allocated_string(rettv->vval.v_list, akt);
}
+ // getregionpos() breaks curbuf and virtual_op
+ curbuf = save_curbuf;
+ curwin->w_buffer = curbuf;
+ virtual_op = save_virtual;
+}
+
+static void add_regionpos_range(typval_T *rettv, int bufnr, int lnum1, int col1, int coladd1,
+ int lnum2, int col2, int coladd2)
+{
+ list_T *l1 = tv_list_alloc(2);
+ tv_list_append_list(rettv->vval.v_list, l1);
+
+ list_T *l2 = tv_list_alloc(4);
+ tv_list_append_list(l1, l2);
+
+ list_T *l3 = tv_list_alloc(4);
+ tv_list_append_list(l1, l3);
+
+ buf_T *findbuf = bufnr != 0 ? buflist_findnr(bufnr) : curbuf;
+
+ int max_col1 = ml_get_buf_len(findbuf, lnum1);
+ tv_list_append_number(l2, bufnr);
+ tv_list_append_number(l2, lnum1);
+ tv_list_append_number(l2, col1 > max_col1 ? max_col1 : col1);
+ tv_list_append_number(l2, coladd1);
+
+ int max_col2 = ml_get_buf_len(findbuf, lnum2);
+ tv_list_append_number(l3, bufnr);
+ tv_list_append_number(l3, lnum2);
+ tv_list_append_number(l3, col2 > max_col2 ? max_col2 : col2);
+ tv_list_append_number(l3, coladd2);
+}
+
+/// "getregionpos()" function
+static void f_getregionpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+{
+ buf_T *const save_curbuf = curbuf;
+ const TriState save_virtual = virtual_op;
+
+ pos_T p1, p2;
+ bool inclusive = true;
+ MotionType region_type = kMTUnknown;
+ oparg_T oa;
+ int fnum;
+
+ if (getregionpos(argvars, rettv,
+ &p1, &p2, &inclusive, &region_type, &oa, &fnum) == FAIL) {
+ return;
+ }
+
+ for (linenr_T lnum = p1.lnum; lnum <= p2.lnum; lnum++) {
+ int start_col, end_col;
+
+ if (region_type == kMTLineWise) {
+ start_col = 1;
+ end_col = MAXCOL;
+ } else if (region_type == kMTBlockWise) {
+ struct block_def bd;
+ block_prep(&oa, &bd, lnum, false);
+ start_col = bd.start_vcol + 1;
+ end_col = bd.end_vcol;
+ } else if (p1.lnum < lnum && lnum < p2.lnum) {
+ start_col = 1;
+ end_col = MAXCOL;
+ } else {
+ start_col = p1.lnum == lnum ? p1.col + 1 : 1;
+ end_col = p2.lnum == lnum ? p2.col + 1 : MAXCOL;
+ }
+
+ add_regionpos_range(rettv, fnum, lnum, start_col,
+ p1.coladd, lnum, end_col, p2.coladd);
+ }
+
+ // getregionpos() may change curbuf and virtual_op
curbuf = save_curbuf;
curwin->w_buffer = curbuf;
virtual_op = save_virtual;
diff --git a/test/old/testdir/test_visual.vim b/test/old/testdir/test_visual.vim
index bc84fde98e..a3d49468e6 100644
--- a/test/old/testdir/test_visual.vim
+++ b/test/old/testdir/test_visual.vim
@@ -1646,16 +1646,44 @@ func Test_visual_getregion()
call feedkeys("\<ESC>vjl", 'tx')
call assert_equal(['one', 'tw'],
\ 'v'->getpos()->getregion(getpos('.')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
+ \ ],
+ \ 'v'->getpos()->getregionpos(getpos('.')))
call assert_equal(['one', 'tw'],
\ '.'->getpos()->getregion(getpos('v')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]]
+ \ ],
+ \ '.'->getpos()->getregionpos(getpos('v')))
call assert_equal(['o'],
\ 'v'->getpos()->getregion(getpos('v')))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 1, 0]],
+ \ ],
+ \ 'v'->getpos()->getregionpos(getpos('v')))
call assert_equal(['w'],
\ '.'->getpos()->getregion(getpos('.'), {'type': 'v' }))
+ call assert_equal([
+ \ [[bufnr('%'), 2, 2, 0], [bufnr('%'), 2, 2, 0]],
+ \ ],
+ \ '.'->getpos()->getregionpos(getpos('.'), {'type': 'v' }))
call assert_equal(['one', 'two'],
\ getpos('.')->getregion(getpos('v'), {'type': 'V' }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 3, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 3, 0]],
+ \ ],
+ \ getpos('.')->getregionpos(getpos('v'), {'type': 'V' }))
call assert_equal(['on', 'tw'],
\ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 2, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 2, 0]],
+ \ ],
+ \ getpos('.')->getregionpos(getpos('v'), {'type': "\<C-v>" }))
#" Line visual mode
call cursor(1, 1)
@@ -1750,9 +1778,13 @@ func Test_visual_getregion()
call assert_fails("call getregion(1, 2)", 'E1211:')
call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
call assert_fails(':echo "."->getpos()->getregion("$", [])', 'E1211:')
+ call assert_fails("call getregionpos(1, 2)", 'E1211:')
+ call assert_fails("call getregionpos(getpos('.'), {})", 'E1211:')
+ call assert_fails(':echo "."->getpos()->getregionpos("$", [])', 'E1211:')
#" using invalid value for "type"
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
+ call assert_fails("call getregionpos(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
#" using a mark from another buffer to current buffer
new
@@ -1763,13 +1795,20 @@ func Test_visual_getregion()
call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
call assert_equal([], getregion(getpos("'A"), getpos('.'), {'type': 'v' }))
+ call assert_equal([], getregionpos(getpos('.'), getpos("'A"), {'type': 'v' }))
+ call assert_equal([], getregionpos(getpos("'A"), getpos('.'), {'type': 'v' }))
#" using two marks from another buffer
wincmd p
normal! GmB
wincmd p
call assert_equal([g:buf, 10, 1, 0], getpos("'B"))
- call assert_equal(['9'], getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
+ call assert_equal(['9'],
+ \ getregion(getpos("'B"), getpos("'A"), {'type': 'v' }))
+ call assert_equal([
+ \ [[g:buf, 10, 1, 0], [g:buf, 10, 1, 0]],
+ \ ],
+ \ getregionpos(getpos("'B"), getpos("'A"), {'type': 'v' }))
#" using two positions from another buffer
for type in ['v', 'V', "\<C-V>"]
@@ -1792,6 +1831,8 @@ func Test_visual_getregion()
call assert_fails('call getregion([g:buf, 10, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 10, 3, 0])', 'E964:')
call assert_fails('call getregion([g:buf, 10, 3, 0], [g:buf, 1, 1, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 1, 0, 0], [g:buf, 1, 1, 0])', 'E964:')
+ call assert_fails('call getregion([g:buf, 1, 1, 0], [g:buf, 1, 0, 0])', 'E964:')
#" using invalid buffer
call assert_fails('call getregion([10000, 10, 1, 0], [10000, 10, 1, 0])', 'E681:')
@@ -1823,6 +1864,12 @@ func Test_visual_getregion()
call feedkeys("\<Esc>\<C-v>jj", 'xt')
call assert_equal(['e', ' ', '5'],
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
+ call assert_equal([
+ \ [[bufnr('%'), 1, 5, 0], [bufnr('%'), 1, 13, 0]],
+ \ [[bufnr('%'), 2, 1, 0], [bufnr('%'), 2, 22, 0]],
+ \ [[bufnr('%'), 3, 1, 0], [bufnr('%'), 3, 5, 0]],
+ \ ],
+ \ getregionpos(getpos('v'), getpos('.'), {'type': 'v' }))
call cursor(1, 1)
call feedkeys("\<Esc>vj", 'xt')
call assert_equal(['abcdefghijk«', "\U0001f1e6"],
@@ -1835,7 +1882,7 @@ func Test_visual_getregion()
call setpos("'c", [0, 2, 0, 0])
call cursor(1, 1)
call assert_equal(['ghijk', '🇨«🇩'],
- \ getregion(getpos("'a"), getpos("'b"), {'type': "\<c-v>" }))
+ \ getregion(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
call assert_equal(['k«', '🇦«🇧«🇨'],
\ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
call assert_equal(['k«'],
@@ -1962,4 +2009,30 @@ func Test_getregion_invalid_buf()
bwipe!
endfunc
+func Test_getregion_maxcol()
+ new
+ autocmd TextYankPost *
+ \ : if v:event.operator ==? 'y'
+ \ | call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ ],
+ \ getregionpos(getpos("'["), getpos("']"),
+ \ #{ mode: visualmode() }))
+ \ | call assert_equal(['abcd'],
+ \ getregion(getpos("'["), getpos("']"),
+ \ #{ mode: visualmode() }))
+ \ | call assert_equal([
+ \ [[bufnr('%'), 1, 1, 0], [bufnr('%'), 1, 4, 0]],
+ \ ],
+ \ getregionpos(getpos("']"), getpos("'["),
+ \ #{ mode: visualmode() }))
+ \ | call assert_equal(['abcd'],
+ \ getregion(getpos("']"), getpos("'["),
+ \ #{ mode: visualmode() }))
+ \ | endif
+ call setline(1, ['abcd', 'efghij'])
+ normal yy
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab