From: McAuley Penney Date: Fri, 26 Dec 2025 15:10:01 +0000 (+0000) Subject: patch 9.1.2019: inconsistent cursor encoding past EOL with ve=all X-Git-Tag: v9.1.2019^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=491f0fa4574207b311f399a5a454033c79772872;p=thirdparty%2Fvim.git patch 9.1.2019: inconsistent cursor encoding past EOL with ve=all 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 Signed-off-by: Christian Brabandt --- diff --git a/src/ops.c b/src/ops.c index 7310efae83..3fad2b44fd 100644 --- 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; diff --git a/src/testdir/test_virtualedit.vim b/src/testdir/test_virtualedit.vim index 3d3fdd0bec..03b8539d76 100644 --- a/src/testdir/test_virtualedit.vim +++ b/src/testdir/test_virtualedit.vim @@ -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! \ + + 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 diff --git a/src/version.c b/src/version.c index c4f7f40b0e..5c16b6f508 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2019, /**/ 2018, /**/