diff options
author | Yegappan Lakshmanan <yegappan@yahoo.com> | 2023-08-15 23:01:44 +0200 |
---|---|---|
committer | Christian Brabandt <cb@256bit.org> | 2023-08-15 23:01:44 +0200 |
commit | b209b86e6636a16088ccacdac98213416c065bf2 (patch) | |
tree | b6eb5f5ab5c0ab74a46a7d1ba0cd6e61e5548780 | |
parent | 15a0a0281a060fd5968ca2f3c80e750137106adb (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.txt | 3 | ||||
-rw-r--r-- | src/move.c | 21 | ||||
-rw-r--r-- | src/testdir/test_cursor_func.vim | 9 | ||||
-rw-r--r-- | src/version.c | 2 |
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, |