Skip to content

Commit 491f0fa

Browse files
mcauley-penneychrisbra
authored andcommitted
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 <jacobmpenney@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent eb3007b commit 491f0fa

3 files changed

Lines changed: 23 additions & 0 deletions

File tree

src/ops.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,7 @@ adjust_cursor_eol(void)
20512051
int adj_cursor = (curwin->w_cursor.col > 0
20522052
&& gchar_cursor() == NUL
20532053
&& (cur_ve_flags & VE_ONEMORE) == 0
2054+
&& (cur_ve_flags & VE_ALL) == 0
20542055
&& !(restart_edit || (State & MODE_INSERT)));
20552056
if (!adj_cursor)
20562057
return;

src/testdir/test_virtualedit.vim

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,4 +732,24 @@ func Test_virtualedit_set_cursor_pos_maxcol()
732732
bwipe!
733733
endfunc
734734

735+
" Verify that getpos() remains consistent when the cursor is past EOL after toggling Visual mode with virtualedit=all.
736+
func Test_virtualedit_getpos_stable_past_eol_after_visual()
737+
new
738+
set virtualedit=all
739+
call setline(1, 'abc')
740+
741+
normal! gg$3l
742+
let p1 = getpos('.')
743+
744+
normal! v
745+
redraw
746+
normal! \<Esc>
747+
748+
let p2 = getpos('.')
749+
call assert_equal(p1, p2, 'Position should not be re-encoded after leaving Visual mode')
750+
751+
set virtualedit&
752+
bwipe!
753+
endfunc
754+
735755
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ static char *(features[]) =
734734

735735
static int included_patches[] =
736736
{ /* Add new patch number below this line */
737+
/**/
738+
2019,
737739
/**/
738740
2018,
739741
/**/

0 commit comments

Comments
 (0)