summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2023-08-15 23:01:44 +0200
committerChristian Brabandt <cb@256bit.org>2023-08-15 23:01:44 +0200
commitb209b86e6636a16088ccacdac98213416c065bf2 (patch)
treeb6eb5f5ab5c0ab74a46a7d1ba0cd6e61e5548780
parent15a0a0281a060fd5968ca2f3c80e750137106adb (diff)
patch 9.0.1717: virtcol2col returns last byte of a multi-byte charv9.0.1717
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>
-rw-r--r--runtime/doc/builtin.txt3
-rw-r--r--src/move.c21
-rw-r--r--src/testdir/test_cursor_func.vim9
-rw-r--r--src/version.c2
4 files changed, 34 insertions, 1 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 96db898b03..2f6961d7dc 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -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.
diff --git a/src/move.c b/src/move.c
index 22c37ce285..94dc7dc630 100644
--- a/src/move.c
+++ b/src/move.c
@@ -1557,6 +1557,25 @@ f_screenpos(typval_T *argvars UNUSED, typval_T *rettv)
}
/*
+ * 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
*/
void
@@ -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
diff --git a/src/testdir/test_cursor_func.vim b/src/testdir/test_cursor_func.vim
index 74d7581db6..2ae7580a4b 100644
--- a/src/testdir/test_cursor_func.vim
+++ b/src/testdir/test_cursor_func.vim
@@ -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:')
diff --git a/src/version.c b/src/version.c
index 80bd77d641..d5d18556a4 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 */
/**/
+ 1717,
+/**/
1716,
/**/
1715,