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:
committed by
Christian Brabandt
parent
c5def6561d
commit
b4757e627e
@@ -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
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -265,6 +265,8 @@ getreg([{regname} [, 1 [, {list}]]])
|
|||||||
getreginfo([{regname}]) Dict information about a register
|
getreginfo([{regname}]) Dict information about a register
|
||||||
getregion({pos1}, {pos2} [, {opts}])
|
getregion({pos1}, {pos2} [, {opts}])
|
||||||
List get the text from {pos1} to {pos2}
|
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
|
getregtype([{regname}]) String type of a register
|
||||||
getscriptinfo([{opts}]) List list of sourced scripts
|
getscriptinfo([{opts}]) List list of sourced scripts
|
||||||
gettabinfo([{expr}]) List list of tab pages
|
gettabinfo([{expr}]) List list of tab pages
|
||||||
@@ -4327,6 +4329,26 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()*
|
|||||||
Can also be used as a |method|: >
|
Can also be used as a |method|: >
|
||||||
getpos('.')->getregion(getpos("'a"))
|
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()*
|
getregtype([{regname}]) *getregtype()*
|
||||||
The result is a String, which is type of register {regname}.
|
The result is a String, which is type of register {regname}.
|
||||||
The value will be one of:
|
The value will be one of:
|
||||||
|
@@ -7799,6 +7799,7 @@ getreg() builtin.txt /*getreg()*
|
|||||||
getreginfo() builtin.txt /*getreginfo()*
|
getreginfo() builtin.txt /*getreginfo()*
|
||||||
getregion() builtin.txt /*getregion()*
|
getregion() builtin.txt /*getregion()*
|
||||||
getregion-notes builtin.txt /*getregion-notes*
|
getregion-notes builtin.txt /*getregion-notes*
|
||||||
|
getregionpos() builtin.txt /*getregionpos()*
|
||||||
getregtype() builtin.txt /*getregtype()*
|
getregtype() builtin.txt /*getregtype()*
|
||||||
getscript pi_getscript.txt /*getscript*
|
getscript pi_getscript.txt /*getscript*
|
||||||
getscript-autoinstall pi_getscript.txt /*getscript-autoinstall*
|
getscript-autoinstall pi_getscript.txt /*getscript-autoinstall*
|
||||||
|
@@ -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
|
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*
|
Working with text in the current buffer: *text-functions*
|
||||||
getline() get a line or list of lines from the buffer
|
getline() get a line or list of lines from the buffer
|
||||||
getregion() get a region of text 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
|
setline() replace a line in the buffer
|
||||||
append() append line or list of lines in the buffer
|
append() append line or list of lines in the buffer
|
||||||
indent() indent of a specific line
|
indent() indent of a specific line
|
||||||
|
@@ -41574,6 +41574,7 @@ Functions: ~
|
|||||||
|matchbufline()| all the matches of a pattern in a buffer
|
|matchbufline()| all the matches of a pattern in a buffer
|
||||||
|matchstrlist()| all the matches of a pattern in a List of strings
|
|matchstrlist()| all the matches of a pattern in a List of strings
|
||||||
|getregion()| get a region of text from a buffer
|
|getregion()| get a region of text from a buffer
|
||||||
|
|getregionpos()| get a list of positions for a region
|
||||||
|
|
||||||
|
|
||||||
Autocommands: ~
|
Autocommands: ~
|
||||||
|
302
src/evalfunc.c
302
src/evalfunc.c
@@ -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_getreg(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_getreginfo(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_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_getregtype(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_gettagstack(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);
|
static void f_gettext(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -2136,6 +2137,8 @@ static funcentry_T global_functions[] =
|
|||||||
ret_dict_any, f_getreginfo},
|
ret_dict_any, f_getreginfo},
|
||||||
{"getregion", 2, 3, FEARG_1, arg3_list_list_dict,
|
{"getregion", 2, 3, FEARG_1, arg3_list_list_dict,
|
||||||
ret_list_string, f_getregion},
|
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,
|
{"getregtype", 0, 1, FEARG_1, arg1_string,
|
||||||
ret_string, f_getregtype},
|
ret_string, f_getregtype},
|
||||||
{"getscriptinfo", 0, 1, 0, arg1_dict_any,
|
{"getscriptinfo", 0, 1, 0, arg1_dict_any,
|
||||||
@@ -5481,40 +5484,35 @@ block_def2str(struct block_def *bd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int
|
||||||
* "getregion()" function
|
getregionpos(
|
||||||
*/
|
typval_T *argvars,
|
||||||
static void
|
typval_T *rettv,
|
||||||
f_getregion(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;
|
int fnum1 = -1, fnum2 = -1;
|
||||||
pos_T p1, p2;
|
|
||||||
char_u *type;
|
char_u *type;
|
||||||
buf_T *save_curbuf;
|
|
||||||
buf_T *findbuf;
|
buf_T *findbuf;
|
||||||
char_u default_type[] = "v";
|
char_u default_type[] = "v";
|
||||||
int save_virtual;
|
|
||||||
int l;
|
|
||||||
int region_type = -1;
|
|
||||||
int is_select_exclusive;
|
int is_select_exclusive;
|
||||||
|
int l;
|
||||||
|
|
||||||
if (rettv_list_alloc(rettv) == FAIL)
|
if (rettv_list_alloc(rettv) == FAIL)
|
||||||
return;
|
return FAIL;
|
||||||
|
|
||||||
if (check_for_list_arg(argvars, 0) == FAIL
|
if (check_for_list_arg(argvars, 0) == FAIL
|
||||||
|| check_for_list_arg(argvars, 1) == FAIL
|
|| check_for_list_arg(argvars, 1) == FAIL
|
||||||
|| check_for_opt_dict_arg(argvars, 2) == FAIL)
|
|| check_for_opt_dict_arg(argvars, 2) == FAIL)
|
||||||
return;
|
return FAIL;
|
||||||
|
|
||||||
if (list2fpos(&argvars[0], &p1, &fnum1, NULL, FALSE) != OK
|
if (list2fpos(&argvars[0], p1, &fnum1, NULL, FALSE) != OK
|
||||||
|| list2fpos(&argvars[1], &p2, &fnum2, NULL, FALSE) != OK
|
|| list2fpos(&argvars[1], p2, &fnum2, NULL, FALSE) != OK
|
||||||
|| fnum1 != fnum2)
|
|| fnum1 != fnum2)
|
||||||
return;
|
return FAIL;
|
||||||
|
|
||||||
if (argvars[2].v_type == VAR_DICT)
|
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)
|
if (type[0] == 'v' && type[1] == NUL)
|
||||||
region_type = MCHAR;
|
*region_type = MCHAR;
|
||||||
else if (type[0] == 'V' && type[1] == NUL)
|
else if (type[0] == 'V' && type[1] == NUL)
|
||||||
region_type = MLINE;
|
*region_type = MLINE;
|
||||||
else if (type[0] == Ctrl_V && type[1] == NUL)
|
else if (type[0] == Ctrl_V && type[1] == NUL)
|
||||||
region_type = MBLOCK;
|
*region_type = MBLOCK;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
semsg(_(e_invalid_value_for_argument_str_str), "type", type);
|
semsg(_(e_invalid_value_for_argument_str_str), "type", type);
|
||||||
return;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
findbuf = fnum1 != 0 ? buflist_findnr(fnum1) : curbuf;
|
findbuf = fnum1 != 0 ? buflist_findnr(fnum1) : curbuf;
|
||||||
|
*fnum = fnum1 != 0 ? fnum1 : curbuf->b_fnum;
|
||||||
if (findbuf == NULL || findbuf->b_ml.ml_mfp == NULL)
|
if (findbuf == NULL || findbuf->b_ml.ml_mfp == NULL)
|
||||||
{
|
{
|
||||||
emsg(_(e_buffer_is_not_loaded));
|
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);
|
semsg(_(e_invalid_line_number_nr), p1->lnum);
|
||||||
return;
|
return FAIL;
|
||||||
}
|
}
|
||||||
if (p1.col == MAXCOL)
|
if (p1->col == MAXCOL)
|
||||||
p1.col = ml_get_buf_len(findbuf, p1.lnum) + 1;
|
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)
|
else if (p1->col < 1 || p1->col > ml_get_buf_len(findbuf, p1->lnum) + 1)
|
||||||
{
|
{
|
||||||
semsg(_(e_invalid_column_number_nr), p1.col);
|
semsg(_(e_invalid_column_number_nr), p1->col);
|
||||||
return;
|
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);
|
semsg(_(e_invalid_line_number_nr), p2->lnum);
|
||||||
return;
|
return FAIL;
|
||||||
}
|
}
|
||||||
if (p2.col == MAXCOL)
|
if (p2->col == MAXCOL)
|
||||||
p2.col = ml_get_buf_len(findbuf, p2.lnum) + 1;
|
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)
|
else if (p2->col < 1 || p2->col > ml_get_buf_len(findbuf, p2->lnum) + 1)
|
||||||
{
|
{
|
||||||
semsg(_(e_invalid_column_number_nr), p2.col);
|
semsg(_(e_invalid_column_number_nr), p2->col);
|
||||||
return;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_curbuf = curbuf;
|
|
||||||
curbuf = findbuf;
|
curbuf = findbuf;
|
||||||
curwin->w_buffer = curbuf;
|
curwin->w_buffer = curbuf;
|
||||||
save_virtual = virtual_op;
|
|
||||||
virtual_op = virtual_active();
|
virtual_op = virtual_active();
|
||||||
|
|
||||||
// NOTE: Adjust is needed.
|
// NOTE: Adjustment is needed.
|
||||||
p1.col--;
|
p1->col--;
|
||||||
p2.col--;
|
p2->col--;
|
||||||
|
|
||||||
if (!LT_POS(p1, p2))
|
if (!LT_POS(*p1, *p2))
|
||||||
{
|
{
|
||||||
// swap position
|
// swap position
|
||||||
pos_T p;
|
pos_T p;
|
||||||
|
|
||||||
p = p1;
|
p = *p1;
|
||||||
p1 = p2;
|
*p1 = *p2;
|
||||||
p2 = p;
|
*p2 = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region_type == MCHAR)
|
if (*region_type == MCHAR)
|
||||||
{
|
{
|
||||||
// handle 'selection' == "exclusive"
|
// handle 'selection' == "exclusive"
|
||||||
if (is_select_exclusive && !EQUAL_POS(p1, p2))
|
if (is_select_exclusive && !EQUAL_POS(*p1, *p2))
|
||||||
{
|
{
|
||||||
if (p2.coladd > 0)
|
if (p2->coladd > 0)
|
||||||
p2.coladd--;
|
p2->coladd--;
|
||||||
else if (p2.col > 0)
|
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->lnum--;
|
||||||
p2.col = ml_get_len(p2.lnum);
|
p2->col = ml_get_len(p2->lnum);
|
||||||
if (p2.col > 0)
|
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 fp2 is on NUL (empty line) inclusive becomes false
|
||||||
if (*ml_get_pos(&p2) == NUL && !virtual_op)
|
if (*ml_get_pos(p2) == NUL && !virtual_op)
|
||||||
inclusive = FALSE;
|
*inclusive = FALSE;
|
||||||
}
|
}
|
||||||
else if (region_type == MBLOCK)
|
else if (*region_type == MBLOCK)
|
||||||
{
|
{
|
||||||
colnr_T sc1, ec1, sc2, ec2;
|
colnr_T sc1, ec1, sc2, ec2;
|
||||||
|
|
||||||
getvvcol(curwin, &p1, &sc1, NULL, &ec1);
|
getvvcol(curwin, p1, &sc1, NULL, &ec1);
|
||||||
getvvcol(curwin, &p2, &sc2, NULL, &ec2);
|
getvvcol(curwin, p2, &sc2, NULL, &ec2);
|
||||||
oa.motion_type = MBLOCK;
|
oa->motion_type = MBLOCK;
|
||||||
oa.inclusive = TRUE;
|
oa->inclusive = TRUE;
|
||||||
oa.op_type = OP_NOP;
|
oa->op_type = OP_NOP;
|
||||||
oa.start = p1;
|
oa->start = *p1;
|
||||||
oa.end = p2;
|
oa->end = *p2;
|
||||||
oa.start_vcol = MIN(sc1, sc2);
|
oa->start_vcol = MIN(sc1, sc2);
|
||||||
if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1)
|
if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1)
|
||||||
oa.end_vcol = sc2 - 1;
|
oa->end_vcol = sc2 - 1;
|
||||||
else
|
else
|
||||||
oa.end_vcol = MAX(ec1, ec2);
|
oa->end_vcol = MAX(ec1, ec2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include the trailing byte of a multi-byte char.
|
// 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)
|
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, ®ion_type, &oa, &fnum) == FAIL)
|
||||||
|
return;
|
||||||
|
|
||||||
for (lnum = p1.lnum; lnum <= p2.lnum; lnum++)
|
for (lnum = p1.lnum; lnum <= p2.lnum; lnum++)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
struct block_def bd;
|
||||||
|
|
||||||
if (region_type == MLINE)
|
if (region_type == MLINE)
|
||||||
akt = vim_strsave(ml_get(lnum));
|
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, ®ion_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;
|
curbuf = save_curbuf;
|
||||||
curwin->w_buffer = curbuf;
|
curwin->w_buffer = curbuf;
|
||||||
virtual_op = save_virtual;
|
virtual_op = save_virtual;
|
||||||
|
@@ -5181,10 +5181,26 @@ enddef
|
|||||||
|
|
||||||
def Test_getregion()
|
def Test_getregion()
|
||||||
assert_equal(['x'], getregion(getpos('.'), getpos('.'))->map((_, _) => 'x'))
|
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'])
|
v9.CheckSourceDefAndScriptFailure(
|
||||||
assert_equal([''], getregion(getpos('.'), getpos('.')))
|
['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(['getregion(getpos("a"), getpos("."))'], 'E1209:')
|
||||||
|
v9.CheckSourceDefExecFailure(['getregionpos(getpos("a"), getpos("."))'], 'E1209:')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||||
|
@@ -1642,16 +1642,44 @@ func Test_visual_getregion()
|
|||||||
call feedkeys("\<ESC>vjl", 'tx')
|
call feedkeys("\<ESC>vjl", 'tx')
|
||||||
call assert_equal(['one', 'tw'],
|
call assert_equal(['one', 'tw'],
|
||||||
\ 'v'->getpos()->getregion(getpos('.')))
|
\ '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'],
|
call assert_equal(['one', 'tw'],
|
||||||
\ '.'->getpos()->getregion(getpos('v')))
|
\ '.'->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'],
|
call assert_equal(['o'],
|
||||||
\ 'v'->getpos()->getregion(getpos('v')))
|
\ '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'],
|
call assert_equal(['w'],
|
||||||
\ '.'->getpos()->getregion(getpos('.'), {'type': 'v' }))
|
\ '.'->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'],
|
call assert_equal(['one', 'two'],
|
||||||
\ getpos('.')->getregion(getpos('v'), {'type': 'V' }))
|
\ 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'],
|
call assert_equal(['on', 'tw'],
|
||||||
\ getpos('.')->getregion(getpos('v'), {'type': "\<C-v>" }))
|
\ 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
|
#" Line visual mode
|
||||||
call cursor(1, 1)
|
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(1, 2)", 'E1211:')
|
||||||
call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
|
call assert_fails("call getregion(getpos('.'), {})", 'E1211:')
|
||||||
call assert_fails(':echo "."->getpos()->getregion("$", [])', '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"
|
#" using invalid value for "type"
|
||||||
call assert_fails("call getregion(getpos('.'), getpos('.'), {'type': '' })", 'E475:')
|
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
|
#" using a mark from another buffer to current buffer
|
||||||
new
|
new
|
||||||
@@ -1759,13 +1791,20 @@ func Test_visual_getregion()
|
|||||||
call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
|
call assert_equal([g:buf, 10, 1, 0], getpos("'A"))
|
||||||
call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
|
call assert_equal([], getregion(getpos('.'), getpos("'A"), {'type': 'v' }))
|
||||||
call assert_equal([], getregion(getpos("'A"), getpos('.'), {'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
|
#" using two marks from another buffer
|
||||||
wincmd p
|
wincmd p
|
||||||
normal! GmB
|
normal! GmB
|
||||||
wincmd p
|
wincmd p
|
||||||
call assert_equal([g:buf, 10, 1, 0], getpos("'B"))
|
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
|
#" using two positions from another buffer
|
||||||
for type in ['v', 'V', "\<C-V>"]
|
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, 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, 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, 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
|
#" using invalid buffer
|
||||||
call assert_fails('call getregion([10000, 10, 1, 0], [10000, 10, 1, 0])', 'E681:')
|
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 feedkeys("\<Esc>\<C-v>jj", 'xt')
|
||||||
call assert_equal(['e', ' ', '5'],
|
call assert_equal(['e', ' ', '5'],
|
||||||
\ getregion(getpos('v'), getpos('.'), {'type': "\<C-v>" }))
|
\ 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 cursor(1, 1)
|
||||||
call feedkeys("\<Esc>vj", 'xt')
|
call feedkeys("\<Esc>vj", 'xt')
|
||||||
call assert_equal(['abcdefghijk«', "\U0001f1e6"],
|
call assert_equal(['abcdefghijk«', "\U0001f1e6"],
|
||||||
@@ -1831,7 +1878,7 @@ func Test_visual_getregion()
|
|||||||
call setpos("'c", [0, 2, 0, 0])
|
call setpos("'c", [0, 2, 0, 0])
|
||||||
call cursor(1, 1)
|
call cursor(1, 1)
|
||||||
call assert_equal(['ghijk', '🇨«🇩'],
|
call assert_equal(['ghijk', '🇨«🇩'],
|
||||||
\ getregion(getpos("'a"), getpos("'b"), {'type': "\<c-v>" }))
|
\ getregion(getpos("'a"), getpos("'b"), {'type': "\<C-v>" }))
|
||||||
call assert_equal(['k«', '🇦«🇧«🇨'],
|
call assert_equal(['k«', '🇦«🇧«🇨'],
|
||||||
\ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
|
\ getregion(getpos("'a"), getpos("'b"), {'type': 'v' }))
|
||||||
call assert_equal(['k«'],
|
call assert_equal(['k«'],
|
||||||
@@ -1958,4 +2005,30 @@ func Test_getregion_invalid_buf()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
394,
|
||||||
/**/
|
/**/
|
||||||
393,
|
393,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user