0
0
mirror of https://github.com/vim/vim.git synced 2025-09-29 04:34:16 -04:00

patch 9.0.0863: col() and charcol() only work for the current window

Problem:    col() and charcol() only work for the current window.
Solution:   Add an optional winid argument. (Yegappan Lakshmanan,
            closes #11466, closes #11461)
This commit is contained in:
Yegappan Lakshmanan
2022-11-12 16:07:47 +00:00
committed by Bram Moolenaar
parent 0aad88f073
commit 4c8d2f02b3
7 changed files with 75 additions and 15 deletions

View File

@@ -116,13 +116,13 @@ ch_status({handle} [, {options}])
changenr() Number current change number changenr() Number current change number
char2nr({expr} [, {utf8}]) Number ASCII/UTF-8 value of first char in {expr} char2nr({expr} [, {utf8}]) Number ASCII/UTF-8 value of first char in {expr}
charclass({string}) Number character class of {string} charclass({string}) Number character class of {string}
charcol({expr}) Number column number of cursor or mark charcol({expr} [, {winid}]) Number column number of cursor or mark
charidx({string}, {idx} [, {countcc}]) charidx({string}, {idx} [, {countcc}])
Number char index of byte {idx} in {string} Number char index of byte {idx} in {string}
chdir({dir}) String change current working directory chdir({dir}) String change current working directory
cindent({lnum}) Number C indent for line {lnum} cindent({lnum}) Number C indent for line {lnum}
clearmatches([{win}]) none clear all matches clearmatches([{win}]) none clear all matches
col({expr}) Number column byte index of cursor or mark col({expr} [, {winid}]) Number column byte index of cursor or mark
complete({startcol}, {matches}) none set Insert mode completion complete({startcol}, {matches}) none set Insert mode completion
complete_add({expr}) Number add completion match complete_add({expr}) Number add completion match
complete_check() Number check for key typed during completion complete_check() Number check for key typed during completion
@@ -1474,7 +1474,7 @@ charclass({string}) *charclass()*
Returns 0 if {string} is not a |String|. Returns 0 if {string} is not a |String|.
charcol({expr}) *charcol()* charcol({expr} [, {winid}]) *charcol()*
Same as |col()| but returns the character index of the column Same as |col()| but returns the character index of the column
position given with {expr} instead of the byte position. position given with {expr} instead of the byte position.
@@ -1557,8 +1557,8 @@ clearmatches([{win}]) *clearmatches()*
Can also be used as a |method|: > Can also be used as a |method|: >
GetWin()->clearmatches() GetWin()->clearmatches()
< <
*col()* col({expr} [, {winid}) *col()*
col({expr}) The result is a Number, which is the byte index of the column The result is a Number, which is the byte index of the column
position given with {expr}. The accepted positions are: position given with {expr}. 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
@@ -1573,6 +1573,8 @@ col({expr}) The result is a Number, which is the byte index of the column
and column number. Most useful when the column is "$", to get and column number. Most useful when the column is "$", to get
the last column of a specific line. When "lnum" or "col" is the last column of a specific line. When "lnum" or "col" is
out of range then col() returns zero. out of range then col() returns zero.
With the optional {winid} argument the values are obtained for
that window instead of the current window.
To get the line number use |line()|. To get both use To get the line number use |line()|. To get both use
|getpos()|. |getpos()|.
For the screen column position use |virtcol()|. For the For the screen column position use |virtcol()|. For the
@@ -1583,7 +1585,8 @@ col({expr}) The result is a Number, which is the byte index of the column
col("$") length of cursor line plus one col("$") length of cursor line plus one
col("'t") column of mark t col("'t") column of mark t
col("'" .. markname) column of mark markname col("'" .. markname) column of mark markname
< The first column is 1. Returns 0 if {expr} is invalid. < The first column is 1. Returns 0 if {expr} is invalid or when
the window with ID {winid} is not found.
For an uppercase mark the column may actually be in another For an uppercase mark the column may actually be in another
buffer. buffer.
For the cursor position, when 'virtualedit' is active, the For the cursor position, when 'virtualedit' is active, the

View File

@@ -1058,6 +1058,7 @@ 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_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_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};
@@ -1774,7 +1775,7 @@ static funcentry_T global_functions[] =
ret_number, f_char2nr}, ret_number, f_char2nr},
{"charclass", 1, 1, FEARG_1, arg1_string, {"charclass", 1, 1, FEARG_1, arg1_string,
ret_number, f_charclass}, ret_number, f_charclass},
{"charcol", 1, 1, FEARG_1, arg1_string_or_list_any, {"charcol", 1, 2, FEARG_1, arg2_string_or_list_number,
ret_number, f_charcol}, ret_number, f_charcol},
{"charidx", 2, 3, FEARG_1, arg3_string_number_bool, {"charidx", 2, 3, FEARG_1, arg3_string_number_bool,
ret_number, f_charidx}, ret_number, f_charidx},
@@ -1784,7 +1785,7 @@ static funcentry_T global_functions[] =
ret_number, f_cindent}, ret_number, f_cindent},
{"clearmatches", 0, 1, FEARG_1, arg1_number, {"clearmatches", 0, 1, FEARG_1, arg1_number,
ret_void, f_clearmatches}, ret_void, f_clearmatches},
{"col", 1, 1, FEARG_1, arg1_string_or_list_any, {"col", 1, 2, FEARG_1, arg2_string_or_list_number,
ret_number, f_col}, ret_number, f_col},
{"complete", 2, 2, FEARG_2, arg2_number_list, {"complete", 2, 2, FEARG_2, arg2_number_list,
ret_void, f_complete}, ret_void, f_complete},
@@ -3389,12 +3390,31 @@ get_col(typval_T *argvars, typval_T *rettv, int charcol)
{ {
colnr_T col = 0; colnr_T col = 0;
pos_T *fp; pos_T *fp;
int fnum = curbuf->b_fnum; switchwin_T switchwin;
int winchanged = FALSE;
if (in_vim9script() if (check_for_string_or_list_arg(argvars, 0) == FAIL
&& check_for_string_or_list_arg(argvars, 0) == FAIL) || check_for_opt_number_arg(argvars, 1) == FAIL)
return; return;
if (argvars[1].v_type != VAR_UNKNOWN)
{
tabpage_T *tp;
win_T *wp;
// use the window specified in the second argument
wp = win_id2wp_tp((int)tv_get_number(&argvars[1]), &tp);
if (wp == NULL || tp == NULL)
return;
if (switch_win_noblock(&switchwin, wp, tp, TRUE) != OK)
return;
check_cursor();
winchanged = TRUE;
}
int fnum = curbuf->b_fnum;
fp = var2fpos(&argvars[0], FALSE, &fnum, charcol); fp = var2fpos(&argvars[0], FALSE, &fnum, charcol);
if (fp != NULL && fnum == curbuf->b_fnum) if (fp != NULL && fnum == curbuf->b_fnum)
{ {
@@ -3427,6 +3447,9 @@ get_col(typval_T *argvars, typval_T *rettv, int charcol)
} }
} }
rettv->vval.v_number = col; rettv->vval.v_number = col;
if (winchanged)
restore_win_noblock(&switchwin, TRUE);
} }
/* /*

View File

@@ -287,8 +287,9 @@ endfunc
" Test for the charcol() function " Test for the charcol() function
func Test_charcol() func Test_charcol()
call assert_fails('call charcol({})', 'E731:') call assert_fails('call charcol({})', 'E1222:')
call assert_equal(0, charcol(0)) call assert_fails('call charcol(".", [])', 'E1210:')
call assert_fails('call charcol(0)', 'E1222:')
new new
call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678']) call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678'])
@@ -344,6 +345,25 @@ func Test_charcol()
call assert_equal([1, 10, 2, 10, 7], g:InsertCurrentCol) call assert_equal([1, 10, 2, 10, 7], g:InsertCurrentCol)
iunmap <F3> iunmap <F3>
" Test for getting the column number in another window.
let winid = win_getid()
new
call win_execute(winid, 'normal 1G')
call assert_equal(1, charcol('.', winid))
call assert_equal(1, charcol('$', winid))
call win_execute(winid, 'normal 2G6l')
call assert_equal(7, charcol('.', winid))
call assert_equal(10, charcol('$', winid))
" calling from another tab page also works
tabnew
call assert_equal(7, charcol('.', winid))
call assert_equal(10, charcol('$', winid))
tabclose
" unknown window ID
call assert_equal(0, charcol('.', 10001))
%bw! %bw!
endfunc endfunc

View File

@@ -1484,7 +1484,8 @@ func Test_col()
call assert_equal(0, col([1, 100])) call assert_equal(0, col([1, 100]))
call assert_equal(0, col([1])) call assert_equal(0, col([1]))
call assert_equal(0, col(test_null_list())) call assert_equal(0, col(test_null_list()))
call assert_fails('let c = col({})', 'E731:') call assert_fails('let c = col({})', 'E1222:')
call assert_fails('let c = col(".", [])', 'E1210:')
" test for getting the visual start column " test for getting the visual start column
func T() func T()
@@ -1514,6 +1515,15 @@ func Test_col()
call assert_equal(4, col('.')) call assert_equal(4, col('.'))
set virtualedit& set virtualedit&
" Test for getting the column number in another window
let winid = win_getid()
new
call win_execute(winid, 'normal 1G$')
call assert_equal(3, col('.', winid))
call win_execute(winid, 'normal 2G')
call assert_equal(8, col('$', winid))
call assert_equal(0, col('.', 5001))
bw! bw!
endfunc endfunc

View File

@@ -687,6 +687,7 @@ enddef
def Test_charcol() def Test_charcol()
v9.CheckDefAndScriptFailure(['charcol(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) v9.CheckDefAndScriptFailure(['charcol(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
v9.CheckDefAndScriptFailure(['charcol({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) v9.CheckDefAndScriptFailure(['charcol({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
v9.CheckDefAndScriptFailure(['charcol(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<unknown>', 'E1210: Number required for argument 2'])
v9.CheckDefExecAndScriptFailure(['charcol("")'], 'E1209: Invalid value for a line number') v9.CheckDefExecAndScriptFailure(['charcol("")'], 'E1209: Invalid value for a line number')
new new
setline(1, ['abcdefgh']) setline(1, ['abcdefgh'])
@@ -734,6 +735,7 @@ def Test_col()
v9.CheckDefAndScriptFailure(['col(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1']) v9.CheckDefAndScriptFailure(['col(10)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1222: String or List required for argument 1'])
v9.CheckDefAndScriptFailure(['col({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1']) v9.CheckDefAndScriptFailure(['col({a: 10})'], ['E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1222: String or List required for argument 1'])
v9.CheckDefAndScriptFailure(['col(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1222: String or List required for argument 1']) v9.CheckDefAndScriptFailure(['col(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1222: String or List required for argument 1'])
v9.CheckDefAndScriptFailure(['col(".", [])'], ['E1013: Argument 2: type mismatch, expected number but got list<unknown>', 'E1210: Number required for argument 2'])
v9.CheckDefExecAndScriptFailure(['col("")'], 'E1209: Invalid value for a line number') v9.CheckDefExecAndScriptFailure(['col("")'], 'E1209: Invalid value for a line number')
bw! bw!
enddef enddef

View File

@@ -53,7 +53,7 @@ def Test_expr1_ternary()
assert_equal(function('len'), Res) assert_equal(function('len'), Res)
var RetOne: func(string): number = function('len') var RetOne: func(string): number = function('len')
var RetTwo: func(string): number = function('charcol') var RetTwo: func(string): number = function('strlen')
var RetThat: func = g:atrue ? RetOne : RetTwo var RetThat: func = g:atrue ? RetOne : RetTwo
assert_equal(function('len'), RetThat) assert_equal(function('len'), RetThat)

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 */
/**/
863,
/**/ /**/
862, 862,
/**/ /**/