Patch 8.2.5034
Problem:    There is no way to get the byte index from a virtual column.
Solution:   Add virtcol2col(). (Yegappan Lakshmanan, closes #10477,
            closes #10098)
Files:      runtime/doc/builtin.txt, runtime/doc/usr_41.txt, src/evalfunc.c,
            src/move.c, src/proto/move.pro, src/testdir/test_cursor_func.vim


*** ../vim-8.2.5033/runtime/doc/builtin.txt     2022-05-27 18:05:28.335620087 
+0100
--- runtime/doc/builtin.txt     2022-05-27 21:55:21.511821046 +0100
***************
*** 691,696 ****
--- 691,698 ----
  values({dict})                        List    values in {dict}
  virtcol({expr} [, {list}])    Number or List
                                        screen column of cursor or mark
+ virtcol2col({winid}, {lnum}, {col})
+                               Number  byte index of a character on screen
  visualmode([expr])            String  last visual mode used
  wildmenumode()                        Number  whether 'wildmenu' mode is 
active
  win_execute({id}, {command} [, {silent}])
***************
*** 6211,6221 ****
--- 6213,6229 ----
  or({expr}, {expr})                                    *or()*
                Bitwise OR on the two arguments.  The arguments are converted
                to a number.  A List, Dict or Float argument causes an error.
+               Also see `and()` and `xor()`.
                Example: >
                        :let bits = or(bits, 0x80)
  <             Can also be used as a |method|: >
                        :let bits = bits->or(0x80)
  
+ <             Rationale: The reason this is a function and not using the "|"
+               character like many languages, is that Vi has always used "|"
+               to separate commands.  In many places it would not be clear if
+               "|" is an operator or a command separator.
+ 
  
  pathshorten({path} [, {len}])                         *pathshorten()*
                Shorten directory names in the path {path} and return the
***************
*** 9788,9793 ****
--- 9796,9820 ----
  <             Can also be used as a |method|: >
                        GetPos()->virtcol()
  
+ virtcol2col({winid}, {lnum}, {col})                   *virtcol2col()*
+               The result is a Number, which is the byte index of the
+               character in window {winid} at buffer line {lnum} and virtual
+               column {col}.
+ 
+               If {col} is greater than the last virtual column in line
+               {lnum}, then the byte index of the character at the last
+               virtual column is returned.
+ 
+               The {winid} argument can be the window number or the
+               |window-ID|. If this is zero, then the current window is used.
+ 
+               Returns -1 if the window {winid} doesn't exist or the buffer
+               line {lnum} or virtual column {col} is invalid.
+ 
+               See also |screenpos()|, |virtcol()| and |col()|.
+ 
+               Can also be used as a |method|: >
+                       GetWinid()->virtcol2col(lnum, col)
  
  visualmode([{expr}])                                          *visualmode()*
                The result is a String, which describes the last Visual mode
***************
*** 10220,10225 ****
--- 10247,10253 ----
  xor({expr}, {expr})                                   *xor()*
                Bitwise XOR on the two arguments.  The arguments are converted
                to a number.  A List, Dict or Float argument causes an error.
+               Also see `and()` and `or()`.
                Example: >
                        :let bits = xor(bits, 0x80)
  <
*** ../vim-8.2.5033/runtime/doc/usr_41.txt      2022-05-22 14:48:26.343247288 
+0100
--- runtime/doc/usr_41.txt      2022-05-27 21:52:46.215904252 +0100
***************
*** 835,840 ****
--- 835,841 ----
        screencol()             get screen column of the cursor
        screenrow()             get screen row of the cursor
        screenpos()             screen row and col of a text character
+       virtcol2col()           byte index of a text character on screen
        getcurpos()             get position of the cursor
        getpos()                get position of cursor, mark, etc.
        setpos()                set position of cursor, mark, etc.
*** ../vim-8.2.5033/src/evalfunc.c      2022-05-26 12:10:33.589893490 +0100
--- src/evalfunc.c      2022-05-27 21:52:46.215904252 +0100
***************
*** 2682,2687 ****
--- 2682,2689 ----
                        ret_list_any,       f_values},
      {"virtcol",               1, 2, FEARG_1,      arg2_string_or_list_bool,
                        ret_virtcol,        f_virtcol},
+     {"virtcol2col",   3, 3, FEARG_1,      arg3_number,
+                       ret_number,         f_virtcol2col},
      {"visualmode",    0, 1, 0,            arg1_bool,
                        ret_string,         f_visualmode},
      {"wildmenumode",  0, 0, 0,            NULL,
*** ../vim-8.2.5033/src/move.c  2022-05-09 20:09:19.290641428 +0100
--- src/move.c  2022-05-27 21:52:46.215904252 +0100
***************
*** 1322,1327 ****
--- 1322,1360 ----
      dict_add_number(dict, "curscol", ccol);
      dict_add_number(dict, "endcol", ecol);
  }
+ 
+ /*
+  * "virtcol2col({winid}, {lnum}, {col})" function
+  */
+     void
+ f_virtcol2col(typval_T *argvars UNUSED, typval_T *rettv)
+ {
+     win_T     *wp;
+     linenr_T  lnum;
+     int               screencol;
+     int               error = FALSE;
+ 
+     rettv->vval.v_number = -1;
+ 
+     if (check_for_number_arg(argvars, 0) == FAIL
+           || check_for_number_arg(argvars, 1) == FAIL
+           || check_for_number_arg(argvars, 2) == FAIL)
+       return;
+ 
+     wp = find_win_by_nr_or_id(&argvars[0]);
+     if (wp == NULL)
+       return;
+ 
+     lnum = tv_get_number_chk(&argvars[1], &error);
+     if (error || lnum < 0 || lnum > wp->w_buffer->b_ml.ml_line_count)
+       return;
+ 
+     screencol = tv_get_number_chk(&argvars[2], &error);
+     if (error || screencol < 0)
+       return;
+ 
+     rettv->vval.v_number = vcol2col(wp, lnum, screencol);
+ }
  #endif
  
  /*
*** ../vim-8.2.5033/src/proto/move.pro  2022-03-23 14:55:19.709745872 +0000
--- src/proto/move.pro  2022-05-27 21:52:46.215904252 +0100
***************
*** 30,35 ****
--- 30,36 ----
  void curs_columns(int may_scroll);
  void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int 
*ccolp, int *ecolp);
  void f_screenpos(typval_T *argvars, typval_T *rettv);
+ void f_virtcol2col(typval_T *argvars, typval_T *rettv);
  void scrolldown(long line_count, int byfold);
  void scrollup(long line_count, int byfold);
  void check_topfill(win_T *wp, int down);
*** ../vim-8.2.5033/src/testdir/test_cursor_func.vim    2022-04-11 
13:05:11.855669449 +0100
--- src/testdir/test_cursor_func.vim    2022-05-27 21:52:46.215904252 +0100
***************
*** 419,422 ****
--- 419,444 ----
    %bw!
  endfunc
  
+ " Test for virtcol2col()
+ func Test_virtcol2col()
+   new
+   call setline(1, ["a\tb\tc"])
+   call assert_equal(1, virtcol2col(0, 1, 1))
+   call assert_equal(2, virtcol2col(0, 1, 2))
+   call assert_equal(2, virtcol2col(0, 1, 8))
+   call assert_equal(3, virtcol2col(0, 1, 9))
+   call assert_equal(4, virtcol2col(0, 1, 10))
+   call assert_equal(4, virtcol2col(0, 1, 16))
+   call assert_equal(5, virtcol2col(0, 1, 17))
+   call assert_equal(-1, virtcol2col(10, 1, 1))
+   call assert_equal(-1, virtcol2col(0, 10, 1))
+   call assert_equal(-1, virtcol2col(0, -1, 1))
+   call assert_equal(-1, virtcol2col(0, 1, -1))
+   call assert_equal(5, virtcol2col(0, 1, 20))
+   call assert_fails('echo virtcol2col("0", 1, 20)', 'E1210:')
+   call assert_fails('echo virtcol2col(0, "1", 20)', 'E1210:')
+   call assert_fails('echo virtcol2col(0, 1, "1")', 'E1210:')
+   bw!
+ endfunc
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.5033/src/version.c       2022-05-27 21:16:29.297019075 +0100
--- src/version.c       2022-05-27 21:52:26.915914551 +0100
***************
*** 736,737 ****
--- 736,739 ----
  {   /* Add new patch number below this line */
+ /**/
+     5034,
  /**/

-- 
PRINCE:    He's come to rescue me, father.
LAUNCELOT: (embarrassed) Well, let's not jump to conclusions ...
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// 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/20220527205831.6ECEB1C1929%40moolenaar.net.

Raspunde prin e-mail lui