]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0804: wincol() is wrong for a double-wide character with 'rightleft' v9.2.0804
authorHirohito Higashi <h.east.727@gmail.com>
Sat, 18 Jul 2026 16:57:57 +0000 (16:57 +0000)
committerChristian Brabandt <cb@256bit.org>
Sat, 18 Jul 2026 16:57:57 +0000 (16:57 +0000)
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) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/evalwindow.c
src/proto/screen.pro
src/screen.c
src/testdir/test_functions.vim
src/version.c

index 23cd92b677d42b56aee2741b80b4519995789786..f913980404d084cd6d76a71baafc93ba942d4213 100644 (file)
@@ -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;
 }
index a1d5714d8f32bf8405d51f059716a3c775f99886..4a10729e212a3103e396f23746ab6026e26014a8 100644 (file)
@@ -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);
index 7d75af0226e1a25be9ce0c389230d455d8ed9e96..17d4c1563c6e52ba060769a36a7b642bc03a7c0b 100644 (file)
@@ -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));
     }
index 988218342923b649f07ec509eff72d3cb399b2ab..645ff531ed0d8697a74fa8880f7791145d8413a8 100644 (file)
@@ -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
index 29624fe2111887e9d065360f6e777811397ba032..349057f2891e827dfc4e2ddf05bef0fd15730e3e 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    804,
 /**/
     803,
 /**/