summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2022-11-12 16:07:47 +0000
committerBram Moolenaar <Bram@vim.org>2022-11-12 16:07:47 +0000
commit4c8d2f02b3ce037bbe1d5ee12887e343c6bde88f (patch)
treeb9f8e07114c29a8427817d5c9aa8ab37b2c13b3c
parent0aad88f073602849d1623122eb3c323f8e252def (diff)
patch 9.0.0863: col() and charcol() only work for the current windowv9.0.0863
Problem: col() and charcol() only work for the current window. Solution: Add an optional winid argument. (Yegappan Lakshmanan, closes #11466, closes #11461)
-rw-r--r--runtime/doc/builtin.txt15
-rw-r--r--src/evalfunc.c33
-rw-r--r--src/testdir/test_cursor_func.vim24
-rw-r--r--src/testdir/test_functions.vim12
-rw-r--r--src/testdir/test_vim9_builtin.vim2
-rw-r--r--src/testdir/test_vim9_expr.vim2
-rw-r--r--src/version.c2
7 files changed, 75 insertions, 15 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 372fa1f68c..ff93437caf 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -116,13 +116,13 @@ ch_status({handle} [, {options}])
changenr() Number current change number
char2nr({expr} [, {utf8}]) Number ASCII/UTF-8 value of first char in {expr}
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}])
Number char index of byte {idx} in {string}
chdir({dir}) String change current working directory
cindent({lnum}) Number C indent for line {lnum}
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_add({expr}) Number add completion match
complete_check() Number check for key typed during completion
@@ -1474,7 +1474,7 @@ charclass({string}) *charclass()*
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
position given with {expr} instead of the byte position.
@@ -1557,8 +1557,8 @@ clearmatches([{win}]) *clearmatches()*
Can also be used as a |method|: >
GetWin()->clearmatches()
<
- *col()*
-col({expr}) The result is a Number, which is the byte index of the column
+col({expr} [, {winid}) *col()*
+ The result is a Number, which is the byte index of the column
position given with {expr}. The accepted positions are:
. the cursor position
$ 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
the last column of a specific line. When "lnum" or "col" is
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
|getpos()|.
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("'t") column of mark t
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
buffer.
For the cursor position, when 'virtualedit' is active, the
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 8943a30b0c..4c9ee4cd8d 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -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_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_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};
@@ -1774,7 +1775,7 @@ static funcentry_T global_functions[] =
ret_number, f_char2nr},
{"charclass", 1, 1, FEARG_1, arg1_string,
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},
{"charidx", 2, 3, FEARG_1, arg3_string_number_bool,
ret_number, f_charidx},
@@ -1784,7 +1785,7 @@ static funcentry_T global_functions[] =
ret_number, f_cindent},
{"clearmatches", 0, 1, FEARG_1, arg1_number,
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},
{"complete", 2, 2, FEARG_2, arg2_number_list,
ret_void, f_complete},
@@ -3389,12 +3390,31 @@ get_col(typval_T *argvars, typval_T *rettv, int charcol)
{
colnr_T col = 0;
pos_T *fp;
- int fnum = curbuf->b_fnum;
+ switchwin_T switchwin;
+ int winchanged = FALSE;
- if (in_vim9script()
- && check_for_string_or_list_arg(argvars, 0) == FAIL)
+ if (check_for_string_or_list_arg(argvars, 0) == FAIL
+ || check_for_opt_number_arg(argvars, 1) == FAIL)
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);
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;
+
+ if (winchanged)
+ restore_win_noblock(&switchwin, TRUE);
}
/*
diff --git a/src/testdir/test_cursor_func.vim b/src/testdir/test_cursor_func.vim
index d2685ed9d8..a48db15e66 100644
--- a/src/testdir/test_cursor_func.vim
+++ b/src/testdir/test_cursor_func.vim
@@ -287,8 +287,9 @@ endfunc
" Test for the charcol() function
func Test_charcol()
- call assert_fails('call charcol({})', 'E731:')
- call assert_equal(0, charcol(0))
+ call assert_fails('call charcol({})', 'E1222:')
+ call assert_fails('call charcol(".", [])', 'E1210:')
+ call assert_fails('call charcol(0)', 'E1222:')
new
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)
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!
endfunc
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index 131db109e3..d0508ce7d1 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -1484,7 +1484,8 @@ func Test_col()
call assert_equal(0, col([1, 100]))
call assert_equal(0, col([1]))
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
func T()
@@ -1514,6 +1515,15 @@ func Test_col()
call assert_equal(4, col('.'))
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!
endfunc
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 10ae2eeb03..ecbfeacd68 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -687,6 +687,7 @@ enddef
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({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')
new
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({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(".", [])'], ['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')
bw!
enddef
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index 5a178803e4..faaa915ac9 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -53,7 +53,7 @@ def Test_expr1_ternary()
assert_equal(function('len'), Res)
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
assert_equal(function('len'), RetThat)
diff --git a/src/version.c b/src/version.c
index 8e970257b6..64ed6487e7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 863,
+/**/
862,
/**/
861,