mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -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:
parent
c3caa7f788
commit
0f7a3e1de6
@ -689,7 +689,8 @@ undotree() List undo file tree
|
|||||||
uniq({list} [, {func} [, {dict}]])
|
uniq({list} [, {func} [, {dict}]])
|
||||||
List remove adjacent duplicates from a list
|
List remove adjacent duplicates from a list
|
||||||
values({dict}) List values in {dict}
|
values({dict}) List values in {dict}
|
||||||
virtcol({expr}) Number screen column of cursor or mark
|
virtcol({expr} [, {list}]) Number or List
|
||||||
|
screen column of cursor or mark
|
||||||
visualmode([expr]) String last visual mode used
|
visualmode([expr]) String last visual mode used
|
||||||
wildmenumode() Number whether 'wildmenu' mode is active
|
wildmenumode() Number whether 'wildmenu' mode is active
|
||||||
win_execute({id}, {command} [, {silent}])
|
win_execute({id}, {command} [, {silent}])
|
||||||
@ -780,6 +781,7 @@ add({object}, {expr}) *add()*
|
|||||||
and({expr}, {expr}) *and()*
|
and({expr}, {expr}) *and()*
|
||||||
Bitwise AND on the two arguments. The arguments are converted
|
Bitwise AND on the two arguments. The arguments are converted
|
||||||
to a number. A List, Dict or Float argument causes an error.
|
to a number. A List, Dict or Float argument causes an error.
|
||||||
|
Also see `or()` and `xor()`.
|
||||||
Example: >
|
Example: >
|
||||||
:let flag = and(bits, 0x80)
|
:let flag = and(bits, 0x80)
|
||||||
< Can also be used as a |method|: >
|
< Can also be used as a |method|: >
|
||||||
@ -936,13 +938,14 @@ autocmd_add({acmds}) *autocmd_add()*
|
|||||||
item is ignored.
|
item is ignored.
|
||||||
cmd Ex command to execute for this autocmd event
|
cmd Ex command to execute for this autocmd event
|
||||||
event autocmd event name. Refer to |autocmd-events|.
|
event autocmd event name. Refer to |autocmd-events|.
|
||||||
|
TODO: currently only accepts one event.
|
||||||
group autocmd group name. Refer to |autocmd-groups|.
|
group autocmd group name. Refer to |autocmd-groups|.
|
||||||
If this group doesn't exist then it is
|
If this group doesn't exist then it is
|
||||||
created. If not specified or empty, then the
|
created. If not specified or empty, then the
|
||||||
default group is used.
|
default group is used.
|
||||||
nested boolean flag, set to v:true to add a nested
|
nested boolean flag, set to v:true to add a nested
|
||||||
autocmd. Refer to |autocmd-nested|.
|
autocmd. Refer to |autocmd-nested|.
|
||||||
once boolean flag, set to v:true to add a autocmd
|
once boolean flag, set to v:true to add an autocmd
|
||||||
which executes only once. Refer to
|
which executes only once. Refer to
|
||||||
|autocmd-once|.
|
|autocmd-once|.
|
||||||
pattern autocmd pattern string. Refer to
|
pattern autocmd pattern string. Refer to
|
||||||
@ -952,7 +955,7 @@ autocmd_add({acmds}) *autocmd_add()*
|
|||||||
commands associated with the specified autocmd
|
commands associated with the specified autocmd
|
||||||
event and group and add the {cmd}. This is
|
event and group and add the {cmd}. This is
|
||||||
useful to avoid adding the same command
|
useful to avoid adding the same command
|
||||||
multiple times for a autocmd event in a group.
|
multiple times for an autocmd event in a group.
|
||||||
|
|
||||||
Returns v:true on success and v:false on failure.
|
Returns v:true on success and v:false on failure.
|
||||||
Examples: >
|
Examples: >
|
||||||
@ -9727,7 +9730,7 @@ values({dict}) *values()*
|
|||||||
Can also be used as a |method|: >
|
Can also be used as a |method|: >
|
||||||
mydict->values()
|
mydict->values()
|
||||||
|
|
||||||
virtcol({expr}) *virtcol()*
|
virtcol({expr} [, {list}]) *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
|
||||||
@ -9736,13 +9739,17 @@ virtcol({expr}) *virtcol()*
|
|||||||
the <Tab>. For example, for a <Tab> in column 1, with 'ts'
|
the <Tab>. For example, for a <Tab> in column 1, with 'ts'
|
||||||
set to 8, it returns 8. |conceal| is ignored.
|
set to 8, it returns 8. |conceal| is ignored.
|
||||||
For the byte position use |col()|.
|
For the byte position use |col()|.
|
||||||
|
|
||||||
For the use of {expr} see |col()|.
|
For the use of {expr} see |col()|.
|
||||||
When 'virtualedit' is used {expr} can be [lnum, col, off], where
|
|
||||||
"off" is the offset in screen columns from the start of the
|
When 'virtualedit' is used {expr} can be [lnum, col, off],
|
||||||
character. E.g., a position within a <Tab> or after the last
|
where "off" is the offset in screen columns from the start of
|
||||||
character. When "off" is omitted zero is used.
|
the character. E.g., a position within a <Tab> or after the
|
||||||
When Virtual editing is active in the current mode, a position
|
last character. When "off" is omitted zero is used. When
|
||||||
beyond the end of the line can be returned. |'virtualedit'|
|
Virtual editing is active in the current mode, a position
|
||||||
|
beyond the end of the line can be returned. Also see
|
||||||
|
|'virtualedit'|
|
||||||
|
|
||||||
The accepted positions are:
|
The accepted positions are:
|
||||||
. the cursor position
|
. the cursor position
|
||||||
$ the end of the cursor line (the result is the
|
$ the end of the cursor line (the result is the
|
||||||
@ -9754,11 +9761,22 @@ virtcol({expr}) *virtcol()*
|
|||||||
cursor is the end). When not in Visual mode
|
cursor is the end). When not in Visual mode
|
||||||
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
|
||||||
|
with the first and last screen position occupied by the
|
||||||
|
character.
|
||||||
|
|
||||||
Note that only marks in the current file can be used.
|
Note that only marks in the current file can be used.
|
||||||
Examples: >
|
Examples: >
|
||||||
virtcol(".") with text "foo^Lbar", with cursor on the "^L", returns 5
|
" With text "foo^Lbar" and cursor on the "^L":
|
||||||
virtcol("$") with text "foo^Lbar", returns 9
|
|
||||||
virtcol("'t") with text " there", with 't at 'h', returns 6
|
virtcol(".") " returns 5
|
||||||
|
virtcol(".", 1) " returns [4, 5]
|
||||||
|
virtcol("$") " returns 9
|
||||||
|
|
||||||
|
" With text " there", with 't at 'h':
|
||||||
|
|
||||||
|
virtcol("'t") " returns 6
|
||||||
< The first column is 1. 0 is returned for an error.
|
< The first column is 1. 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: >
|
||||||
|
@ -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_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_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};
|
||||||
static argcheck_T arg3_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum};
|
static argcheck_T arg3_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum};
|
||||||
@ -1457,6 +1458,20 @@ ret_getreg(int argcount,
|
|||||||
return &t_string;
|
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 *
|
static type_T *
|
||||||
ret_maparg(int argcount,
|
ret_maparg(int argcount,
|
||||||
type2_T *argtypes UNUSED,
|
type2_T *argtypes UNUSED,
|
||||||
@ -2665,8 +2680,8 @@ static funcentry_T global_functions[] =
|
|||||||
ret_first_arg, f_uniq},
|
ret_first_arg, f_uniq},
|
||||||
{"values", 1, 1, FEARG_1, arg1_dict_any,
|
{"values", 1, 1, FEARG_1, arg1_dict_any,
|
||||||
ret_list_any, f_values},
|
ret_list_any, f_values},
|
||||||
{"virtcol", 1, 1, FEARG_1, arg1_string_or_list_any,
|
{"virtcol", 1, 2, FEARG_1, arg2_string_or_list_bool,
|
||||||
ret_number, f_virtcol},
|
ret_virtcol, f_virtcol},
|
||||||
{"visualmode", 0, 1, 0, arg1_bool,
|
{"visualmode", 0, 1, 0, arg1_bool,
|
||||||
ret_string, f_visualmode},
|
ret_string, f_visualmode},
|
||||||
{"wildmenumode", 0, 0, 0, NULL,
|
{"wildmenumode", 0, 0, 0, NULL,
|
||||||
@ -10380,18 +10395,21 @@ f_type(typval_T *argvars, typval_T *rettv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "virtcol(string)" function
|
* "virtcol(string, bool)" function
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
f_virtcol(typval_T *argvars, typval_T *rettv)
|
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;
|
pos_T *fp;
|
||||||
int fnum = curbuf->b_fnum;
|
int fnum = curbuf->b_fnum;
|
||||||
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
|
||||||
|
&& check_for_bool_arg(argvars, 1) == FAIL)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fp = var2fpos(&argvars[0], FALSE, &fnum, FALSE);
|
fp = var2fpos(&argvars[0], FALSE, &fnum, FALSE);
|
||||||
@ -10407,11 +10425,23 @@ f_virtcol(typval_T *argvars, typval_T *rettv)
|
|||||||
if (fp->col > len)
|
if (fp->col > len)
|
||||||
fp->col = len;
|
fp->col = len;
|
||||||
}
|
}
|
||||||
getvvcol(curwin, fp, NULL, NULL, &vcol);
|
getvvcol(curwin, fp, &vcol_start, NULL, &vcol_end);
|
||||||
++vcol;
|
++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
|
endif
|
||||||
endfunc
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -4494,14 +4494,23 @@ def Test_values()
|
|||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_virtcol()
|
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.CheckDefAndScriptFailure(['virtcol(1.1)'], [
|
||||||
v9.CheckDefExecAndScriptFailure(['virtcol("")'], 'E1209: Invalid value for a line number')
|
'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
|
new
|
||||||
setline(1, ['abcdefgh'])
|
setline(1, ['abcde和平fgh'])
|
||||||
cursor(1, 4)
|
cursor(1, 4)
|
||||||
assert_equal(4, virtcol('.'))
|
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(4, virtcol([1, 4]))
|
||||||
assert_equal(9, virtcol([1, '$']))
|
assert_equal(13, virtcol([1, '$']))
|
||||||
assert_equal(0, virtcol([10, '$']))
|
assert_equal(0, virtcol([10, '$']))
|
||||||
bw!
|
bw!
|
||||||
enddef
|
enddef
|
||||||
|
@ -734,6 +734,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 */
|
||||||
|
/**/
|
||||||
|
5019,
|
||||||
/**/
|
/**/
|
||||||
5018,
|
5018,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user