mirror of
https://github.com/vim/vim.git
synced 2025-10-03 05:14:07 -04:00
patch 8.2.5019: cannot get the first screen column of a character
Problem: Cannot get the first screen column of a character. Solution: Let virtcol() optionally return a list. (closes #10482, closes #7964)
This commit is contained in:
@@ -994,6 +994,7 @@ 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_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_bool[] = {arg_string_or_list_any, arg_bool};
|
||||
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_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum};
|
||||
@@ -1457,6 +1458,20 @@ ret_getreg(int argcount,
|
||||
return &t_string;
|
||||
}
|
||||
|
||||
static type_T *
|
||||
ret_virtcol(int argcount,
|
||||
type2_T *argtypes UNUSED,
|
||||
type_T **decl_type)
|
||||
{
|
||||
// Assume that if the second argument is passed it's non-zero
|
||||
if (argcount == 2)
|
||||
{
|
||||
*decl_type = &t_list_any;
|
||||
return &t_list_number;
|
||||
}
|
||||
return &t_number;
|
||||
}
|
||||
|
||||
static type_T *
|
||||
ret_maparg(int argcount,
|
||||
type2_T *argtypes UNUSED,
|
||||
@@ -2665,8 +2680,8 @@ static funcentry_T global_functions[] =
|
||||
ret_first_arg, f_uniq},
|
||||
{"values", 1, 1, FEARG_1, arg1_dict_any,
|
||||
ret_list_any, f_values},
|
||||
{"virtcol", 1, 1, FEARG_1, arg1_string_or_list_any,
|
||||
ret_number, f_virtcol},
|
||||
{"virtcol", 1, 2, FEARG_1, arg2_string_or_list_bool,
|
||||
ret_virtcol, f_virtcol},
|
||||
{"visualmode", 0, 1, 0, arg1_bool,
|
||||
ret_string, f_visualmode},
|
||||
{"wildmenumode", 0, 0, 0, NULL,
|
||||
@@ -10380,23 +10395,26 @@ f_type(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
|
||||
/*
|
||||
* "virtcol(string)" function
|
||||
* "virtcol(string, bool)" function
|
||||
*/
|
||||
static void
|
||||
f_virtcol(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
colnr_T vcol = 0;
|
||||
colnr_T vcol_start = 0;
|
||||
colnr_T vcol_end = 0;
|
||||
pos_T *fp;
|
||||
int fnum = curbuf->b_fnum;
|
||||
int len;
|
||||
|
||||
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
|
||||
&& check_for_bool_arg(argvars, 1) == FAIL)))
|
||||
return;
|
||||
|
||||
fp = var2fpos(&argvars[0], FALSE, &fnum, FALSE);
|
||||
if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
|
||||
&& fnum == curbuf->b_fnum)
|
||||
&& fnum == curbuf->b_fnum)
|
||||
{
|
||||
// Limit the column to a valid value, getvvcol() doesn't check.
|
||||
if (fp->col < 0)
|
||||
@@ -10407,11 +10425,23 @@ f_virtcol(typval_T *argvars, typval_T *rettv)
|
||||
if (fp->col > len)
|
||||
fp->col = len;
|
||||
}
|
||||
getvvcol(curwin, fp, NULL, NULL, &vcol);
|
||||
++vcol;
|
||||
getvvcol(curwin, fp, &vcol_start, NULL, &vcol_end);
|
||||
++vcol_start;
|
||||
++vcol_end;
|
||||
}
|
||||
|
||||
rettv->vval.v_number = vcol;
|
||||
if (argvars[1].v_type != VAR_UNKNOWN && tv_get_bool(&argvars[1]))
|
||||
{
|
||||
if (rettv_list_alloc(rettv) == OK)
|
||||
{
|
||||
list_append_number(rettv->vval.v_list, vcol_start);
|
||||
list_append_number(rettv->vval.v_list, vcol_end);
|
||||
}
|
||||
else
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else
|
||||
rettv->vval.v_number = vcol_end;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -2947,4 +2947,15 @@ func Test_exepath()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" Test for virtcol()
|
||||
func Test_virtcol()
|
||||
enew!
|
||||
call setline(1, "the\tquick\tbrown\tfox")
|
||||
norm! 4|
|
||||
call assert_equal(8, virtcol('.'))
|
||||
call assert_equal(8, virtcol('.', v:false))
|
||||
call assert_equal([4, 8], virtcol('.', v:true))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@@ -4494,14 +4494,23 @@ def Test_values()
|
||||
enddef
|
||||
|
||||
def Test_virtcol()
|
||||
v9.CheckDefAndScriptFailure(['virtcol(1.1)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1222: String or List required for argument 1'])
|
||||
v9.CheckDefExecAndScriptFailure(['virtcol("")'], 'E1209: Invalid value for a line number')
|
||||
v9.CheckDefAndScriptFailure(['virtcol(1.1)'], [
|
||||
'E1013: Argument 1: type mismatch, expected string but got float',
|
||||
'E1222: String or List required for argument 1'])
|
||||
v9.CheckDefAndScriptFailure(['virtcol(".", "a")'], [
|
||||
'E1013: Argument 2: type mismatch, expected bool but got string',
|
||||
'E1212: Bool required for argument 2'])
|
||||
v9.CheckDefExecAndScriptFailure(['virtcol("")'],
|
||||
'E1209: Invalid value for a line number')
|
||||
new
|
||||
setline(1, ['abcdefgh'])
|
||||
setline(1, ['abcde和平fgh'])
|
||||
cursor(1, 4)
|
||||
assert_equal(4, virtcol('.'))
|
||||
assert_equal([4, 4], virtcol('.', 1))
|
||||
cursor(1, 6)
|
||||
assert_equal([6, 7], virtcol('.', 1))
|
||||
assert_equal(4, virtcol([1, 4]))
|
||||
assert_equal(9, virtcol([1, '$']))
|
||||
assert_equal(13, virtcol([1, '$']))
|
||||
assert_equal(0, virtcol([10, '$']))
|
||||
bw!
|
||||
enddef
|
||||
|
@@ -734,6 +734,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
5019,
|
||||
/**/
|
||||
5018,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user