1
0
forked from aniani/vim

patch 9.1.0394: Cannot get a list of positions describing a region

Problem:  Cannot get a list of positions describing a region
          (Justin M. Keyes, after v9.1.0120)
Solution: Add the getregionpos() function
          (Shougo Matsushita)

fixes: #14609
closes: #14617

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Shougo Matsushita
2024-05-07 20:49:24 +02:00
committed by Christian Brabandt
parent c5def6561d
commit b4757e627e
8 changed files with 351 additions and 89 deletions

View File

@@ -1,4 +1,4 @@
*builtin.txt* For Vim version 9.1. Last change: 2024 May 05
*builtin.txt* For Vim version 9.1. Last change: 2024 May 07
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -265,6 +265,8 @@ getreg([{regname} [, 1 [, {list}]]])
getreginfo([{regname}]) Dict information about a register
getregion({pos1}, {pos2} [, {opts}])
List get the text from {pos1} to {pos2}
getregionpos({pos1}, {pos2} [, {opts}])
List get a list of positions for a region
getregtype([{regname}]) String type of a register
getscriptinfo([{opts}]) List list of sourced scripts
gettabinfo([{expr}]) List list of tab pages
@@ -4327,6 +4329,26 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()*
Can also be used as a |method|: >
getpos('.')->getregion(getpos("'a"))
<
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.
Can also be used as a |method|: >
getpos('.')->getregionpos(getpos("'a"))
<
getregtype([{regname}]) *getregtype()*
The result is a String, which is type of register {regname}.
The value will be one of:

View File

@@ -7799,6 +7799,7 @@ getreg() builtin.txt /*getreg()*
getreginfo() builtin.txt /*getreginfo()*
getregion() builtin.txt /*getregion()*
getregion-notes builtin.txt /*getregion-notes*
getregionpos() builtin.txt /*getregionpos()*
getregtype() builtin.txt /*getregtype()*
getscript pi_getscript.txt /*getscript*
getscript-autoinstall pi_getscript.txt /*getscript-autoinstall*

View File

@@ -1,4 +1,4 @@
*usr_41.txt* For Vim version 9.1. Last change: 2024 Apr 26
*usr_41.txt* For Vim version 9.1. Last change: 2024 May 07
VIM USER MANUAL - by Bram Moolenaar
@@ -930,6 +930,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

View File

@@ -41574,6 +41574,7 @@ Functions: ~
|matchbufline()| all the matches of a pattern in a buffer
|matchstrlist()| all the matches of a pattern in a List of strings
|getregion()| get a region of text from a buffer
|getregionpos()| get a list of positions for a region
Autocommands: ~

View File

@@ -73,6 +73,7 @@ static void f_getpos(typval_T *argvars, typval_T *rettv);
static void f_getreg(typval_T *argvars, typval_T *rettv);
static void f_getreginfo(typval_T *argvars, typval_T *rettv);
static void f_getregion(typval_T *argvars, typval_T *rettv);
static void f_getregionpos(typval_T *argvars, typval_T *rettv);
static void f_getregtype(typval_T *argvars, typval_T *rettv);
static void f_gettagstack(typval_T *argvars, typval_T *rettv);
static void f_gettext(typval_T *argvars, typval_T *rettv);
@@ -2136,6 +2137,8 @@ static funcentry_T global_functions[] =
ret_dict_any, f_getreginfo},
{"getregion", 2, 3, FEARG_1, arg3_list_list_dict,
ret_list_string, f_getregion},
{"getregionpos", 2, 3, FEARG_1, arg3_list_list_dict,
ret_list_string, f_getregionpos},
{"getregtype", 0, 1, FEARG_1, arg1_string,
ret_string, f_getregtype},
{"getscriptinfo", 0, 1, 0, arg1_dict_any,
@@ -5481,40 +5484,35 @@ block_def2str(struct block_def *bd)
return ret;
}
/*
* "getregion()" function
*/
static void
f_getregion(typval_T *argvars, typval_T *rettv)
static int
getregionpos(
typval_T *argvars,
typval_T *rettv,
pos_T *p1, pos_T *p2,
int *inclusive,
int *region_type,
oparg_T *oa,
int *fnum)
{
linenr_T lnum;
oparg_T oa;
struct block_def bd;
char_u *akt = NULL;
int inclusive = TRUE;
int fnum1 = -1, fnum2 = -1;
pos_T p1, p2;
char_u *type;
buf_T *save_curbuf;
buf_T *findbuf;
char_u default_type[] = "v";
int save_virtual;
int l;
int region_type = -1;
int is_select_exclusive;
int l;
if (rettv_list_alloc(rettv) == FAIL)
return;
return FAIL;
if (check_for_list_arg(argvars, 0) == FAIL
|| check_for_list_arg(argvars, 1) == FAIL
|| check_for_opt_dict_arg(argvars, 2) == FAIL)
return;
return FAIL;
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;
if (argvars[2].v_type == VAR_DICT)
{
@@ -5532,125 +5530,152 @@ f_getregion(typval_T *argvars, typval_T *rettv)
}
if (type[0] == 'v' && type[1] == NUL)
region_type = MCHAR;
*region_type = MCHAR;
else if (type[0] == 'V' && type[1] == NUL)
region_type = MLINE;
*region_type = MLINE;
else if (type[0] == Ctrl_V && type[1] == NUL)
region_type = MBLOCK;
*region_type = MBLOCK;
else
{
semsg(_(e_invalid_value_for_argument_str_str), "type", type);
return;
return FAIL;
}
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)
if (p1->lnum < 1 || p1->lnum > findbuf->b_ml.ml_line_count)
{
semsg(_(e_invalid_line_number_nr), p1.lnum);
return;
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)
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;
semsg(_(e_invalid_column_number_nr), p1->col);
return FAIL;
}
if (p2.lnum < 1 || p2.lnum > findbuf->b_ml.ml_line_count)
if (p2->lnum < 1 || p2->lnum > findbuf->b_ml.ml_line_count)
{
semsg(_(e_invalid_line_number_nr), p2.lnum);
return;
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)
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;
semsg(_(e_invalid_column_number_nr), p2->col);
return FAIL;
}
save_curbuf = curbuf;
curbuf = findbuf;
curwin->w_buffer = curbuf;
save_virtual = virtual_op;
virtual_op = virtual_active();
// NOTE: Adjust is needed.
p1.col--;
p2.col--;
// NOTE: Adjustment is needed.
p1->col--;
p2->col--;
if (!LT_POS(p1, p2))
if (!LT_POS(*p1, *p2))
{
// swap position
pos_T p;
p = p1;
p1 = p2;
p2 = p;
p = *p1;
*p1 = *p2;
*p2 = p;
}
if (region_type == MCHAR)
if (*region_type == MCHAR)
{
// handle 'selection' == "exclusive"
if (is_select_exclusive && !EQUAL_POS(p1, p2))
if (is_select_exclusive && !EQUAL_POS(*p1, *p2))
{
if (p2.coladd > 0)
p2.coladd--;
else if (p2.col > 0)
if (p2->coladd > 0)
p2->coladd--;
else if (p2->col > 0)
{
p2.col--;
p2->col--;
mb_adjustpos(curbuf, &p2);
mb_adjustpos(curbuf, p2);
}
else if (p2.lnum > 1)
else if (p2->lnum > 1)
{
p2.lnum--;
p2.col = ml_get_len(p2.lnum);
if (p2.col > 0)
p2->lnum--;
p2->col = ml_get_len(p2->lnum);
if (p2->col > 0)
{
p2.col--;
p2->col--;
mb_adjustpos(curbuf, &p2);
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 == MBLOCK)
else if (*region_type == MBLOCK)
{
colnr_T sc1, ec1, sc2, ec2;
getvvcol(curwin, &p1, &sc1, NULL, &ec1);
getvvcol(curwin, &p2, &sc2, NULL, &ec2);
oa.motion_type = MBLOCK;
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 = MBLOCK;
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.
l = utfc_ptr2len((char_u *)ml_get_pos(&p2));
l = mb_ptr2len((char_u *)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)
{
pos_T p1, p2;
int inclusive = TRUE;
int region_type = -1;
oparg_T oa;
int fnum;
buf_T *save_curbuf;
int save_virtual;
char_u *akt = NULL;
linenr_T lnum;
save_curbuf = curbuf;
save_virtual = virtual_op;
if (getregionpos(argvars, rettv,
&p1, &p2, &inclusive, &region_type, &oa, &fnum) == FAIL)
return;
for (lnum = p1.lnum; lnum <= p2.lnum; lnum++)
{
int ret = 0;
struct block_def bd;
if (region_type == MLINE)
akt = vim_strsave(ml_get(lnum));
@@ -5681,6 +5706,127 @@ f_getregion(typval_T *argvars, typval_T *rettv)
}
}
// 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, *l2, *l3;
buf_T *findbuf;
int max_col1, max_col2;
l1 = list_alloc();
if (l1 == NULL)
return;
if (list_append_list(rettv->vval.v_list, l1) == FAIL)
{
vim_free(l1);
return;
}
l2 = list_alloc();
if (l2 == NULL)
return;
if (list_append_list(l1, l2) == FAIL)
{
vim_free(l2);
return;
}
l3 = list_alloc();
if (l3 == NULL)
return;
if (list_append_list(l1, l3) == FAIL)
{
vim_free(l3);
return;
}
findbuf = bufnr != 0 ? buflist_findnr(bufnr) : curbuf;
max_col1 = ml_get_buf_len(findbuf, lnum1);
list_append_number(l2, bufnr);
list_append_number(l2, lnum1);
list_append_number(l2, col1 > max_col1 ? max_col1 : col1);
list_append_number(l2, coladd1);
max_col2 = ml_get_buf_len(findbuf, lnum2);
list_append_number(l3, bufnr);
list_append_number(l3, lnum2);
list_append_number(l3, col2 > max_col2 ? max_col2 : col2);
list_append_number(l3, coladd2);
}
/*
* "getregionpos()" function
*/
static void
f_getregionpos(typval_T *argvars, typval_T *rettv)
{
pos_T p1, p2;
int inclusive = TRUE;
int region_type = -1;
oparg_T oa;
int fnum;
int lnum;
buf_T *save_curbuf;
int save_virtual;
save_curbuf = curbuf;
save_virtual = virtual_op;
if (getregionpos(argvars, rettv,
&p1, &p2, &inclusive, &region_type, &oa, &fnum) == FAIL)
return;
for (lnum = p1.lnum; lnum <= p2.lnum; lnum++)
{
struct block_def bd;
int start_col, end_col;
if (region_type == MLINE)
{
start_col = 1;
end_col = MAXCOL;
}
else if (region_type == MBLOCK)
{
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;

View File

@@ -5181,10 +5181,26 @@ enddef
def Test_getregion()
assert_equal(['x'], getregion(getpos('.'), getpos('.'))->map((_, _) => 'x'))
assert_equal(['x'], getregionpos(getpos('.'), getpos('.'))->map((_, _) => 'x'))
v9.CheckSourceDefAndScriptFailure(['getregion(10, getpos("."))'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1'])
assert_equal([''], getregion(getpos('.'), getpos('.')))
v9.CheckSourceDefAndScriptFailure(
['getregion(10, getpos("."))'],
['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1']
)
v9.CheckSourceDefAndScriptFailure(
['getregionpos(10, getpos("."))'],
['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1']
)
assert_equal(
[''],
getregion(getpos('.'), getpos('.'))
)
assert_equal(
[[[bufnr('%'), 1, 0, 0], [bufnr('%'), 1, 0, 0]]],
getregionpos(getpos('.'), getpos('.'))
)
v9.CheckSourceDefExecFailure(['getregion(getpos("a"), getpos("."))'], 'E1209:')
v9.CheckSourceDefExecFailure(['getregionpos(getpos("a"), getpos("."))'], 'E1209:')
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@@ -1642,16 +1642,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)
@@ -1746,9 +1774,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
@@ -1759,13 +1791,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>"]
@@ -1788,6 +1827,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:')
@@ -1819,6 +1860,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"],
@@ -1831,7 +1878,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«'],
@@ -1958,4 +2005,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

View File

@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
394,
/**/
393,
/**/