]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1717: virtcol2col returns last byte of a multi-byte char v9.0.1717
authorYegappan Lakshmanan <yegappan@yahoo.com>
Tue, 15 Aug 2023 21:01:44 +0000 (23:01 +0200)
committerChristian Brabandt <cb@256bit.org>
Tue, 15 Aug 2023 21:01:44 +0000 (23:01 +0200)
Problem: virtcol2col returns last byte of a multi-byte char
Solution: Make it return the first byte for a multi-byte char

closes: #12786
closes: #12799

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
runtime/doc/builtin.txt
src/move.c
src/testdir/test_cursor_func.vim
src/version.c

index 96db898b0375761bc157c776696b1ba240f2fa52..2f6961d7dc7be58bb2b04ac053729735ea338fb0 100644 (file)
@@ -10347,6 +10347,9 @@ virtcol2col({winid}, {lnum}, {col})                     *virtcol2col()*
                {lnum}, then the byte index of the character at the last
                virtual column is returned.
 
+               For a multi-byte character, the column number of the first
+               byte in the character is returned.
+
                The {winid} argument can be the window number or the
                |window-ID|. If this is zero, then the current window is used.
 
index 22c37ce28591ed9a6ac83c98d73b0c1910e6ef26..94dc7dc630f5361e37d581e2b00e716183e5ef53 100644 (file)
@@ -1556,6 +1556,25 @@ f_screenpos(typval_T *argvars UNUSED, typval_T *rettv)
     dict_add_number(dict, "endcol", ecol);
 }
 
+/*
+ * Convert a virtual (screen) column to a character column.  The first column
+ * is one.  For a multibyte character, the column number of the first byte is
+ * returned.
+ */
+    static int
+virtcol2col(win_T *wp, linenr_T lnum, int vcol)
+{
+    int                offset = vcol2col(wp, lnum, vcol);
+    char_u     *line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+    char_u     *p = line + offset;
+
+    // For a multibyte character, need to return the column number of the first
+    // byte.
+    MB_PTR_BACK(line, p);
+
+    return (int)(p - line + 1);
+}
+
 /*
  * "virtcol2col({winid}, {lnum}, {col})" function
  */
@@ -1586,7 +1605,7 @@ f_virtcol2col(typval_T *argvars UNUSED, typval_T *rettv)
     if (error || screencol < 0)
        return;
 
-    rettv->vval.v_number = vcol2col(wp, lnum, screencol);
+    rettv->vval.v_number = virtcol2col(wp, lnum, screencol);
 }
 #endif
 
index 74d7581db61c66d0e58ad22a5192dfb21b3db0bd..2ae7580a4b4ce90f6f09042fd9c349c3e867e779 100644 (file)
@@ -531,6 +531,15 @@ func Test_virtcol2col()
   call assert_equal(-1, virtcol2col(0, -1, 1))
   call assert_equal(-1, virtcol2col(0, 1, -1))
   call assert_equal(5, virtcol2col(0, 1, 20))
+
+  " Multibyte character
+  call setline(1, ['a✅✅✅'])
+  call assert_equal(1, virtcol2col(0, 1, 1))
+  call assert_equal(2, virtcol2col(0, 1, 3))
+  call assert_equal(5, virtcol2col(0, 1, 5))
+  call assert_equal(8, virtcol2col(0, 1, 7))
+  call assert_equal(8, virtcol2col(0, 1, 8))
+
   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:')
index 80bd77d6417fcaca3c1f0b39893eee7ebc9df073..d5d18556a4365c6068350a365ae8d29dd55b38c7 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1717,
 /**/
     1716,
 /**/