patch 9.1.2019: inconsistent cursor encoding past EOL with ve=all
Commit:
https://github.com/vim/vim/commit/491f0fa4574207b311f399a5a454033c79772872
Author: McAuley Penney <[email protected]>
Date: Fri Dec 26 15:10:01 2025 +0000
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 <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/ops.c b/src/ops.c
index 7310efae8..3fad2b44f 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 3d3fdd0be..03b8539d7 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! \<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
diff --git a/src/version.c b/src/version.c
index c4f7f40b0..5c16b6f50 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,
/**/
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1vZ9X0-00Gs45-3s%40256bit.org.