]> granicus.if.org Git - vim/commitdiff
patch 9.0.0863: col() and charcol() only work for the current window v9.0.0863
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 12 Nov 2022 16:07:47 +0000 (16:07 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 12 Nov 2022 16:07:47 +0000 (16:07 +0000)
Problem:    col() and charcol() only work for the current window.
Solution:   Add an optional winid argument. (Yegappan Lakshmanan,
            closes #11466, closes #11461)

runtime/doc/builtin.txt
src/evalfunc.c
src/testdir/test_cursor_func.vim
src/testdir/test_functions.vim
src/testdir/test_vim9_builtin.vim
src/testdir/test_vim9_expr.vim
src/version.c

index 372fa1f68c19ec993a287e20d500b70382d7f553..ff93437caf979375f286aa09d61e1d266a36eb28 100644 (file)
@@ -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
index 8943a30b0ccb82172e35aabb99b29d6d592a2e72..4c9ee4cd8d69c179dce39f54001d9e587dc06057 100644 (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_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);
 }
 
 /*
index d2685ed9d858923217e1b1e62fd025abfa6352e7..a48db15e66b7082f2a699eb87ea8524c2bc25f5c 100644 (file)
@@ -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
 
index 131db109e3da703760afab9142b65df970bcf37a..d0508ce7d1d048622bf1086e5858bfbf6ba433e9 100644 (file)
@@ -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
 
index 10ae2eeb03824ac2b96d6c2b5aec3b1914d0eeb7..ecbfeacd68ea78654e03282a7396f21a311f7be1 100644 (file)
@@ -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
index 5a178803e494ab0d0ce8a5699c09d564e46e35fb..faaa915ac98f1c91aa450b87ba47e76fbc1ed3f6 100644 (file)
@@ -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)
 
index 8e970257b6adfaa36cd9f78601610c4e45916afe..64ed6487e77a0c8d8ddf99487118339ede29992f 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    863,
 /**/
     862,
 /**/