0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 9.0.1728: missing winid argument for virtcol()

Problem: missing winid argument for virtcol()
Solution: Add a {winid} argument to virtcol()

Other functions col(), charcol() and virtcol2col() support a {winid}
argument, so it makes sense for virtcol() to also support than.

Also add test for virtcol2col() with 'showbreak' and {winid}.

closes: #12633

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
This commit is contained in:
zeertzjq
2023-08-17 22:55:25 +02:00
committed by Christian Brabandt
parent b0efa49ed1
commit 825cf813fa
6 changed files with 84 additions and 12 deletions

View File

@@ -713,7 +713,8 @@ uniq({list} [, {func} [, {dict}]])
utf16idx({string}, {idx} [, {countcc} [, {charidx}]]) utf16idx({string}, {idx} [, {countcc} [, {charidx}]])
Number UTF-16 index of byte {idx} in {string} Number UTF-16 index of byte {idx} in {string}
values({dict}) List values in {dict} values({dict}) List values in {dict}
virtcol({expr} [, {list}]) Number or List virtcol({expr} [, {list} [, {winid}])
Number or List
screen column of cursor or mark screen column of cursor or mark
virtcol2col({winid}, {lnum}, {col}) virtcol2col({winid}, {lnum}, {col})
Number byte index of a character on screen Number byte index of a character on screen
@@ -10283,7 +10284,7 @@ values({dict}) *values()*
Can also be used as a |method|: > Can also be used as a |method|: >
mydict->values() mydict->values()
virtcol({expr} [, {list}]) *virtcol()* virtcol({expr} [, {list} [, {winid}]]) *virtcol()*
The result is a Number, which is the screen column of the file The result is a Number, which is the screen column of the file
position given with {expr}. That is, the last screen position position given with {expr}. That is, the last screen position
occupied by the character at that position, when the screen occupied by the character at that position, when the screen
@@ -10315,10 +10316,13 @@ virtcol({expr} [, {list}]) *virtcol()*
returns the cursor position. Differs from |'<| in returns the cursor position. Differs from |'<| in
that it's updated right away. that it's updated right away.
If {list} is present and non-zero then virtcol() returns a List If {list} is present and non-zero then virtcol() returns a
with the first and last screen position occupied by the List with the first and last screen position occupied by the
character. character.
With the optional {winid} argument the values are obtained for
that window instead of the current window.
Note that only marks in the current file can be used. Note that only marks in the current file can be used.
Examples: > Examples: >
" With text "foo^Lbar" and cursor on the "^L": " With text "foo^Lbar" and cursor on the "^L":
@@ -10330,7 +10334,7 @@ virtcol({expr} [, {list}]) *virtcol()*
" With text " there", with 't at 'h': " With text " there", with 't at 'h':
virtcol("'t") " returns 6 virtcol("'t") " returns 6
< The first column is 1. 0 is returned for an error. < The first column is 1. 0 or [0, 0] is returned for an error.
A more advanced example that echoes the maximum length of A more advanced example that echoes the maximum length of
all lines: > all lines: >
echo max(map(range(1, line('$')), "virtcol([v:val, '$'])")) echo max(map(range(1, line('$')), "virtcol([v:val, '$'])"))

View File

@@ -1070,7 +1070,6 @@ static argcheck_T arg2_string_dict[] = {arg_string, arg_dict_any};
static argcheck_T arg2_string_list_number[] = {arg_string, arg_list_number}; static argcheck_T arg2_string_list_number[] = {arg_string, arg_list_number};
static argcheck_T arg2_string_number[] = {arg_string, arg_number}; static argcheck_T arg2_string_number[] = {arg_string, arg_number};
static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any}; static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any};
static argcheck_T arg2_string_or_list_bool[] = {arg_string_or_list_any, arg_bool};
static argcheck_T arg2_string_or_list_number[] = {arg_string_or_list_any, arg_number}; static argcheck_T arg2_string_or_list_number[] = {arg_string_or_list_any, arg_number};
static argcheck_T arg2_string_string_or_number[] = {arg_string, arg_string_or_nr}; static argcheck_T arg2_string_string_or_number[] = {arg_string, arg_string_or_nr};
static argcheck_T arg3_any_list_dict[] = {NULL, arg_list_any, arg_dict_any}; static argcheck_T arg3_any_list_dict[] = {NULL, arg_list_any, arg_dict_any};
@@ -1094,6 +1093,7 @@ static argcheck_T arg3_string_bool_bool[] = {arg_string, arg_bool, arg_bool};
static argcheck_T arg3_string_number_bool[] = {arg_string, arg_number, arg_bool}; static argcheck_T arg3_string_number_bool[] = {arg_string, arg_number, arg_bool};
static argcheck_T arg3_string_number_number[] = {arg_string, arg_number, arg_number}; static argcheck_T arg3_string_number_number[] = {arg_string, arg_number, arg_number};
static argcheck_T arg3_string_or_dict_bool_dict[] = {arg_string_or_dict_any, arg_bool, arg_dict_any}; static argcheck_T arg3_string_or_dict_bool_dict[] = {arg_string_or_dict_any, arg_bool, arg_dict_any};
static argcheck_T arg3_string_or_list_bool_number[] = {arg_string_or_list_any, arg_bool, arg_number};
static argcheck_T arg3_string_string_bool[] = {arg_string, arg_string, arg_bool}; static argcheck_T arg3_string_string_bool[] = {arg_string, arg_string, arg_bool};
static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any}; static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any};
static argcheck_T arg3_string_string_number[] = {arg_string, arg_string, arg_number}; static argcheck_T arg3_string_string_number[] = {arg_string, arg_string, arg_number};
@@ -1569,7 +1569,7 @@ ret_virtcol(int argcount,
type_T **decl_type) type_T **decl_type)
{ {
// Assume that if the second argument is passed it's non-zero // Assume that if the second argument is passed it's non-zero
if (argcount == 2) if (argcount > 1)
{ {
*decl_type = &t_list_any; *decl_type = &t_list_any;
return &t_list_number; return &t_list_number;
@@ -2806,7 +2806,7 @@ static funcentry_T global_functions[] =
ret_number, f_utf16idx}, ret_number, f_utf16idx},
{"values", 1, 1, FEARG_1, arg1_dict_any, {"values", 1, 1, FEARG_1, arg1_dict_any,
ret_list_member, f_values}, ret_list_member, f_values},
{"virtcol", 1, 2, FEARG_1, arg2_string_or_list_bool, {"virtcol", 1, 3, FEARG_1, arg3_string_or_list_bool_number,
ret_virtcol, f_virtcol}, ret_virtcol, f_virtcol},
{"virtcol2col", 3, 3, FEARG_1, arg3_number, {"virtcol2col", 3, 3, FEARG_1, arg3_number,
ret_number, f_virtcol2col}, ret_number, f_virtcol2col},
@@ -10737,7 +10737,7 @@ f_type(typval_T *argvars, typval_T *rettv)
} }
/* /*
* "virtcol(string, bool)" function * "virtcol({expr}, [, {list} [, {winid}]])" function
*/ */
static void static void
f_virtcol(typval_T *argvars, typval_T *rettv) f_virtcol(typval_T *argvars, typval_T *rettv)
@@ -10745,15 +10745,35 @@ f_virtcol(typval_T *argvars, typval_T *rettv)
colnr_T vcol_start = 0; colnr_T vcol_start = 0;
colnr_T vcol_end = 0; colnr_T vcol_end = 0;
pos_T *fp; pos_T *fp;
int fnum = curbuf->b_fnum; switchwin_T switchwin;
int winchanged = FALSE;
int len; int len;
if (in_vim9script() if (in_vim9script()
&& (check_for_string_or_list_arg(argvars, 0) == FAIL && (check_for_string_or_list_arg(argvars, 0) == FAIL
|| (argvars[1].v_type != VAR_UNKNOWN || (argvars[1].v_type != VAR_UNKNOWN
&& check_for_bool_arg(argvars, 1) == FAIL))) && (check_for_bool_arg(argvars, 1) == FAIL
|| check_for_opt_number_arg(argvars, 2) == FAIL))))
return; return;
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
{
tabpage_T *tp;
win_T *wp;
// use the window specified in the third argument
wp = win_id2wp_tp((int)tv_get_number(&argvars[2]), &tp);
if (wp == NULL || tp == NULL)
goto theend;
if (switch_win_noblock(&switchwin, wp, tp, TRUE) != OK)
goto theend;
check_cursor();
winchanged = TRUE;
}
int fnum = curbuf->b_fnum;
fp = var2fpos(&argvars[0], FALSE, &fnum, FALSE); fp = var2fpos(&argvars[0], FALSE, &fnum, FALSE);
if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
&& fnum == curbuf->b_fnum) && fnum == curbuf->b_fnum)
@@ -10772,6 +10792,7 @@ f_virtcol(typval_T *argvars, typval_T *rettv)
++vcol_end; ++vcol_end;
} }
theend:
if (argvars[1].v_type != VAR_UNKNOWN && tv_get_bool(&argvars[1])) if (argvars[1].v_type != VAR_UNKNOWN && tv_get_bool(&argvars[1]))
{ {
if (rettv_list_alloc(rettv) == OK) if (rettv_list_alloc(rettv) == OK)
@@ -10784,6 +10805,9 @@ f_virtcol(typval_T *argvars, typval_T *rettv)
} }
else else
rettv->vval.v_number = vcol_end; rettv->vval.v_number = vcol_end;
if (winchanged)
restore_win_noblock(&switchwin, TRUE);
} }
/* /*

View File

@@ -540,9 +540,28 @@ func Test_virtcol2col()
call assert_equal(8, virtcol2col(0, 1, 7)) call assert_equal(8, virtcol2col(0, 1, 7))
call assert_equal(8, virtcol2col(0, 1, 8)) call assert_equal(8, virtcol2col(0, 1, 8))
let w = winwidth(0)
call setline(2, repeat('a', w + 2))
let win_nosbr = win_getid()
split
setlocal showbreak=!!
let win_sbr = win_getid()
call assert_equal(w, virtcol2col(win_nosbr, 2, w))
call assert_equal(w + 1, virtcol2col(win_nosbr, 2, w + 1))
call assert_equal(w + 2, virtcol2col(win_nosbr, 2, w + 2))
call assert_equal(w + 2, virtcol2col(win_nosbr, 2, w + 3))
call assert_equal(w, virtcol2col(win_sbr, 2, w))
call assert_equal(w + 1, virtcol2col(win_sbr, 2, w + 1))
call assert_equal(w + 1, virtcol2col(win_sbr, 2, w + 2))
call assert_equal(w + 1, virtcol2col(win_sbr, 2, w + 3))
call assert_equal(w + 2, virtcol2col(win_sbr, 2, w + 4))
call assert_equal(w + 2, virtcol2col(win_sbr, 2, w + 5))
close
call assert_fails('echo virtcol2col("0", 1, 20)', 'E1210:') call assert_fails('echo virtcol2col("0", 1, 20)', 'E1210:')
call assert_fails('echo virtcol2col(0, "1", 20)', 'E1210:') call assert_fails('echo virtcol2col(0, "1", 20)', 'E1210:')
call assert_fails('echo virtcol2col(0, 1, "1")', 'E1210:') call assert_fails('echo virtcol2col(0, 1, "1")', 'E1210:')
bw! bw!
endfunc endfunc

View File

@@ -3514,12 +3514,32 @@ endfunc
" Test for virtcol() " Test for virtcol()
func Test_virtcol() func Test_virtcol()
enew! new
call setline(1, "the\tquick\tbrown\tfox") call setline(1, "the\tquick\tbrown\tfox")
norm! 4| norm! 4|
call assert_equal(8, virtcol('.')) call assert_equal(8, virtcol('.'))
call assert_equal(8, virtcol('.', v:false)) call assert_equal(8, virtcol('.', v:false))
call assert_equal([4, 8], virtcol('.', v:true)) call assert_equal([4, 8], virtcol('.', v:true))
let w = winwidth(0)
call setline(2, repeat('a', w + 2))
let win_nosbr = win_getid()
split
setlocal showbreak=!!
let win_sbr = win_getid()
call assert_equal([w, w], virtcol([2, w], v:true, win_nosbr))
call assert_equal([w + 1, w + 1], virtcol([2, w + 1], v:true, win_nosbr))
call assert_equal([w + 2, w + 2], virtcol([2, w + 2], v:true, win_nosbr))
call assert_equal([w, w], virtcol([2, w], v:true, win_sbr))
call assert_equal([w + 3, w + 3], virtcol([2, w + 1], v:true, win_sbr))
call assert_equal([w + 4, w + 4], virtcol([2, w + 2], v:true, win_sbr))
close
call assert_equal(0, virtcol(''))
call assert_equal([0, 0], virtcol('', v:true))
call assert_equal(0, virtcol('.', v:false, 5001))
call assert_equal([0, 0], virtcol('.', v:true, 5001))
bwipe! bwipe!
endfunc endfunc

View File

@@ -4811,6 +4811,9 @@ def Test_virtcol()
v9.CheckDefAndScriptFailure(['virtcol(".", "a")'], [ v9.CheckDefAndScriptFailure(['virtcol(".", "a")'], [
'E1013: Argument 2: type mismatch, expected bool but got string', 'E1013: Argument 2: type mismatch, expected bool but got string',
'E1212: Bool required for argument 2']) 'E1212: Bool required for argument 2'])
v9.CheckDefAndScriptFailure(['virtcol(".", v:true, [])'], [
'E1013: Argument 3: type mismatch, expected number but got list',
'E1210: Number required for argument 3'])
v9.CheckDefExecAndScriptFailure(['virtcol("")'], v9.CheckDefExecAndScriptFailure(['virtcol("")'],
'E1209: Invalid value for a line number') 'E1209: Invalid value for a line number')
new new

View File

@@ -695,6 +695,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 */
/**/
1728,
/**/ /**/
1727, 1727,
/**/ /**/