neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit e53accf8ec5a2cb4522af8fe477acebea5c0ce1b
parent 922816877febf397fe854f01d8013a510d73f1d2
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Sun, 28 Dec 2025 07:01:10 +0800

vim-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:  vim/vim#16276
closes: vim/vim#19009

https://github.com/vim/vim/commit/491f0fa4574207b311f399a5a454033c79772872

Co-authored-by: McAuley Penney <jacobmpenney@gmail.com>

Diffstat:
Msrc/nvim/ops.c | 1+
Mtest/old/testdir/test_virtualedit.vim | 20++++++++++++++++++++
2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/src/nvim/ops.c b/src/nvim/ops.c @@ -1793,6 +1793,7 @@ void adjust_cursor_eol(void) const bool adj_cursor = (curwin->w_cursor.col > 0 && gchar_cursor() == NUL && (cur_ve_flags & kOptVeFlagOnemore) == 0 + && (cur_ve_flags & kOptVeFlagAll) == 0 && !(restart_edit || (State & MODE_INSERT))); if (!adj_cursor) { return; diff --git a/test/old/testdir/test_virtualedit.vim b/test/old/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