Patch 9.0.0863
Problem:    col() and charcol() only work for the current window.
Solution:   Add an optional winid argument. (Yegappan Lakshmanan,
            closes #11466, closes #11461)
Files:      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


*** ../vim-9.0.0862/runtime/doc/builtin.txt     2022-11-05 23:46:30.720146269 
+0000
--- runtime/doc/builtin.txt     2022-11-12 16:00:49.725535590 +0000
***************
*** 116,128 ****
  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
  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
  complete({startcol}, {matches}) none  set Insert mode completion
  complete_add({expr})          Number  add completion match
  complete_check()              Number  check for key typed during completion
--- 116,128 ----
  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} [, {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} [, {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
***************
*** 1321,1327 ****
  
        echo "A window containing buffer 1 is " .. (bufwinid(1))
  <
!               Only deals with the current tab page.
  
                Can also be used as a |method|: >
                        FindBuffer()->bufwinid()
--- 1321,1328 ----
  
        echo "A window containing buffer 1 is " .. (bufwinid(1))
  <
!               Only deals with the current tab page.  See |win_findbuf()| for
!               finding more.
  
                Can also be used as a |method|: >
                        FindBuffer()->bufwinid()
***************
*** 1473,1479 ****
                Returns 0 if {string} is not a |String|.
  
  
! charcol({expr})                                               *charcol()*
                Same as |col()| but returns the character index of the column
                position given with {expr} instead of the byte position.
  
--- 1474,1480 ----
                Returns 0 if {string} is not a |String|.
  
  
! charcol({expr} [, {winid}])                           *charcol()*
                Same as |col()| but returns the character index of the column
                position given with {expr} instead of the byte position.
  
***************
*** 1556,1563 ****
                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
                position given with {expr}.  The accepted positions are:
                    .       the cursor position
                    $       the end of the cursor line (the result is the
--- 1557,1564 ----
                Can also be used as a |method|: >
                        GetWin()->clearmatches()
  <
! 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
***************
*** 1572,1577 ****
--- 1573,1580 ----
                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
***************
*** 1582,1597 ****
                        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.
                For an uppercase mark the column may actually be in another
                buffer.
                For the cursor position, when 'virtualedit' is active, the
                column is one higher if the cursor is after the end of the
!               line.  This can be used to obtain the column in Insert mode: >
!                       :imap <F2> <C-O>:let save_ve = &ve<CR>
!                               \<C-O>:set ve=all<CR>
!                               \<C-O>:echo col(".") .. "\n" <Bar>
!                               \let &ve = save_ve<CR>
  
  <             Can also be used as a |method|: >
                        GetPos()->col()
--- 1585,1599 ----
                        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 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
                column is one higher if the cursor is after the end of the
!               line.  Also, when using a <Cmd> mapping the cursor isn't
!               moved, this can be used to obtain the column in Insert mode: >
!                       :imap <F2> <Cmd>echowin col(".")<CR>
  
  <             Can also be used as a |method|: >
                        GetPos()->col()
***************
*** 10205,10210 ****
--- 10208,10214 ----
                FALSE otherwise.
                This will fail for the rightmost window and a full-width
                window, since it has no separator on the right.
+               Only works for the current tab page. *E1308*
  
                Can also be used as a |method|: >
                        GetWinnr()->win_move_separator(offset)
***************
*** 10219,10224 ****
--- 10223,10229 ----
                movement may be smaller than specified (e.g., as a consequence
                of maintaining 'winminheight'). Returns TRUE if the window can
                be found and FALSE otherwise.
+               Only works for the current tab page.
  
                Can also be used as a |method|: >
                        GetWinnr()->win_move_statusline(offset)
*** ../vim-9.0.0862/src/evalfunc.c      2022-10-19 14:02:34.961276576 +0100
--- src/evalfunc.c      2022-11-12 16:03:05.997700716 +0000
***************
*** 1058,1063 ****
--- 1058,1064 ----
  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,1780 ****
                        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,
                        ret_number,         f_charcol},
      {"charidx",               2, 3, FEARG_1,      arg3_string_number_bool,
                        ret_number,         f_charidx},
--- 1775,1781 ----
                        ret_number,         f_char2nr},
      {"charclass",     1, 1, FEARG_1,      arg1_string,
                        ret_number,         f_charclass},
!     {"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,1790 ****
                        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,
                        ret_number,         f_col},
      {"complete",      2, 2, FEARG_2,      arg2_number_list,
                        ret_void,           f_complete},
--- 1785,1791 ----
                        ret_number,         f_cindent},
      {"clearmatches",  0, 1, FEARG_1,      arg1_number,
                        ret_void,           f_clearmatches},
!     {"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,3400 ****
  {
      colnr_T   col = 0;
      pos_T     *fp;
!     int               fnum = curbuf->b_fnum;
  
!     if (in_vim9script()
!           && check_for_string_or_list_arg(argvars, 0) == FAIL)
        return;
  
      fp = var2fpos(&argvars[0], FALSE, &fnum, charcol);
      if (fp != NULL && fnum == curbuf->b_fnum)
      {
--- 3390,3420 ----
  {
      colnr_T   col = 0;
      pos_T     *fp;
!     switchwin_T       switchwin;
!     int               winchanged = FALSE;
  
!     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,3432 ****
--- 3447,3455 ----
        }
      }
      rettv->vval.v_number = col;
+ 
+     if (winchanged)
+       restore_win_noblock(&switchwin, TRUE);
  }
  
  /*
*** ../vim-9.0.0862/src/testdir/test_cursor_func.vim    2022-10-10 
12:42:52.476239815 +0100
--- src/testdir/test_cursor_func.vim    2022-11-12 15:58:35.545348935 +0000
***************
*** 287,294 ****
  
  " Test for the charcol() function
  func Test_charcol()
!   call assert_fails('call charcol({})', 'E731:')
!   call assert_equal(0, charcol(0))
    new
    call setline(1, ['', "01\tà4è678", 'Ⅵ', '012345678'])
  
--- 287,295 ----
  
  " Test for the charcol() function
  func Test_charcol()
!   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,349 ****
--- 345,369 ----
    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
  
*** ../vim-9.0.0862/src/testdir/test_functions.vim      2022-11-05 
23:46:30.720146269 +0000
--- src/testdir/test_functions.vim      2022-11-12 15:53:44.613076920 +0000
***************
*** 1484,1490 ****
    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:')
  
    " test for getting the visual start column
    func T()
--- 1484,1491 ----
    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({})', 'E1222:')
!   call assert_fails('let c = col(".", [])', 'E1210:')
  
    " test for getting the visual start column
    func T()
***************
*** 1514,1519 ****
--- 1515,1529 ----
    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
  
*** ../vim-9.0.0862/src/testdir/test_vim9_builtin.vim   2022-11-05 
23:46:30.720146269 +0000
--- src/testdir/test_vim9_builtin.vim   2022-11-12 15:53:44.617076922 +0000
***************
*** 687,692 ****
--- 687,693 ----
  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,739 ****
--- 735,741 ----
    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
*** ../vim-9.0.0862/src/testdir/test_vim9_expr.vim      2022-11-06 
18:27:09.363922860 +0000
--- src/testdir/test_vim9_expr.vim      2022-11-12 15:53:44.617076922 +0000
***************
*** 53,59 ****
        assert_equal(function('len'), Res)
  
        var RetOne: func(string): number = function('len')
!       var RetTwo: func(string): number = function('charcol')
        var RetThat: func = g:atrue ? RetOne : RetTwo
        assert_equal(function('len'), RetThat)
  
--- 53,59 ----
        assert_equal(function('len'), Res)
  
        var RetOne: func(string): number = function('len')
!       var RetTwo: func(string): number = function('strlen')
        var RetThat: func = g:atrue ? RetOne : RetTwo
        assert_equal(function('len'), RetThat)
  
*** ../vim-9.0.0862/src/version.c       2022-11-12 11:54:19.209571526 +0000
--- src/version.c       2022-11-12 15:55:37.201132670 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     863,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
43. You tell the kids they can't use the computer because "Daddy's got work to
    do" and you don't even have a job.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221112160816.5D8881C0473%40moolenaar.net.

Raspunde prin e-mail lui