]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.2019: inconsistent cursor encoding past EOL with ve=all v9.1.2019
authorMcAuley Penney <jacobmpenney@gmail.com>
Fri, 26 Dec 2025 15:10:01 +0000 (15:10 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 26 Dec 2025 15:10:01 +0000 (15:10 +0000)
Problem:  When virtualedit is set to all, the cursor is supposed to be
          permitted to reside anywhere, including on the virtual space
          beyond the end of the buffer's text. Switching modes triggered
          a routine that "fixed" a cursor that was past the end of the
          line by shifting it back to the last actual character in the
          line and compensating with a virtual column offset. While
          visually identical, this re-encoding changed the underlying
          byte index, causing position-reporting functions to return
          inconsistent values after a mode change.
Solution: Skip this coordinate adjustment when virtual editing is fully
          enabled. By treating the line terminator as a valid, stable
          position, the cursor’s internal representation remains
          unchanged when entering or exiting Visual mode, ensuring
          consistent coordinate reporting. Add a regression test to
          check this functionality.
          (McAuley Penney)

fixes:  #16276
closes: #19009

Signed-off-by: McAuley Penney <jacobmpenney@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/ops.c
src/testdir/test_virtualedit.vim
src/version.c

index 7310efae83e9560d2155e05c474b830232822754..3fad2b44fd0401c7fd3bec708fd644a408c2537f 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -2051,6 +2051,7 @@ adjust_cursor_eol(void)
     int adj_cursor = (curwin->w_cursor.col > 0
                                && gchar_cursor() == NUL
                                && (cur_ve_flags & VE_ONEMORE) == 0
+                               && (cur_ve_flags & VE_ALL) == 0
                                && !(restart_edit || (State & MODE_INSERT)));
     if (!adj_cursor)
        return;
index 3d3fdd0becf6a4ec69d78ed43432c6cc6539d767..03b8539d764d8ecf926fce2e4db93c2d724faed4 100644 (file)
@@ -732,4 +732,24 @@ func Test_virtualedit_set_cursor_pos_maxcol()
   bwipe!
 endfunc
 
+" Verify that getpos() remains consistent when the cursor is past EOL after toggling Visual mode with virtualedit=all.
+func Test_virtualedit_getpos_stable_past_eol_after_visual()
+  new
+  set virtualedit=all
+  call setline(1, 'abc')
+
+  normal! gg$3l
+  let p1 = getpos('.')
+
+  normal! v
+  redraw
+  normal! \<Esc>
+
+  let p2 = getpos('.')
+  call assert_equal(p1, p2, 'Position should not be re-encoded after leaving Visual mode')
+
+  set virtualedit&
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index c4f7f40b0ea8a349b77539f402b8eddeffb4146a..5c16b6f508254980be033c3bd4013b64d86f2f39 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2019,
 /**/
     2018,
 /**/