patch 9.2.0804: wincol() is wrong for a double-wide character with 'rightleft'
Commit:
https://github.com/vim/vim/commit/6f02e5cd7c27fc098d0b8dfec99542c7663a807e
Author: Hirohito Higashi <
h.eas...@gmail.com>
Date: Sat Jul 18 16:57:57 2026 +0000
patch 9.2.0804: wincol() is wrong for a double-wide character with 'rightleft'
Problem: With 'rightleft' set and the cursor on a double-wide character,
wincol() returns the column one to the right of where the cursor
actually is (after v9.2.0791)
Solution: Take the width of the character under the cursor into account,
like the cursor positioning already does.
related: #20763
closes: #20785
Co-Authored-By: Claude Opus 4.8 (1M context) <
nor...@anthropic.com>
Signed-off-by: Hirohito Higashi <
h.eas...@gmail.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/evalwindow.c b/src/evalwindow.c
index 23cd92b67..f91398040 100644
--- a/src/evalwindow.c
+++ b/src/evalwindow.c
@@ -1129,7 +1129,7 @@ f_wincol(typval_T *argvars UNUSED, typval_T *rettv)
int col = curwin->w_wcol + 1;
# ifdef FEAT_RIGHTLEFT
if (curwin->w_p_rl)
- col = curwin->w_width - col + 1;
+ col = curwin->w_width - curwin->w_wcol - cursor_screen_cells() + 1;
# endif
rettv->vval.v_number = col;
}
diff --git a/src/proto/
screen.pro b/src/proto/
screen.pro
index a1d5714d8..4a10729e2 100644
--- a/src/proto/
screen.pro
+++ b/src/proto/
screen.pro
@@ -36,6 +36,7 @@ int can_clear(char_u *p);
void screen_start(void);
void windgoto(int row, int col);
void setcursor(void);
+int cursor_screen_cells(void);
void setcursor_mayforce(int force);
int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear);
int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear, int clear_attr);
diff --git a/src/screen.c b/src/screen.c
index 7d75af022..17d4c1563 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -4038,6 +4038,19 @@ setcursor(void)
setcursor_mayforce(FALSE);
}
+#ifdef FEAT_RIGHTLEFT
+/*
+ * Return the number of screen cells used by the character under the cursor
+ * in the current window.
+ */
+ int
+cursor_screen_cells(void)
+{
+ return has_mbyte && (*mb_ptr2cells)(ml_get_cursor()) == 2
+ && vim_isprintc(gchar_cursor()) ? 2 : 1;
+}
+#endif
+
/*
* Set cursor to its position in the current window.
* When "force" is TRUE also when not redrawing.
@@ -4054,9 +4067,7 @@ setcursor_mayforce(int force)
// With 'rightleft' set and the cursor on a double-wide
// character, position it on the leftmost column.
curwin->w_p_rl ? ((int)curwin->w_width - curwin->w_wcol
- - ((has_mbyte
- && (*mb_ptr2cells)(ml_get_cursor()) == 2
- && vim_isprintc(gchar_cursor())) ? 2 : 1)) :
+ - cursor_screen_cells()) :
#endif
curwin->w_wcol));
}
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index 988218342..645ff531e 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -4738,6 +4738,24 @@ func Test_wincol()
set rightleft&
endif
+ " With 'rightleft' the cursor is on the leftmost cell of a double-wide
+ " character, so wincol() is one less than where the character starts.
+ call setline(1, "あいうえお")
+
+ norm! 0
+ call assert_equal([1, 1], [winline(), wincol()])
+ norm! l
+ call assert_equal([1, 3], [winline(), wincol()])
+
+ if has('rightleft')
+ set rightleft
+ norm! 0
+ call assert_equal([1, win_width - 1], [winline(), wincol()])
+ norm! l
+ call assert_equal([1, win_width - 3], [winline(), wincol()])
+ set rightleft&
+ endif
+
set ff& mouse&
bw!
endfunc
diff --git a/src/version.c b/src/version.c
index 29624fe21..349057f28 100644
--- a/src/version.c
+++ b/src/version.c
@@ -759,6 +759,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 804,
/**/
803,
/**/