Skip to content

Commit b2e6b32

Browse files
zeertzjqchrisbra
authored andcommitted
patch 9.1.1885: Wrong restored cursor pos when re-entering buffer after changes
Problem: Wrong restored cursor position when re-entering a buffer previously viewed in a window after making changes to the same buffer in another window. Solution: Adjust per-window "last cursor" positions on buffer changes. (zeertzjq) closes: #18655 Signed-off-by: zeertzjq <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent 9ad7067 commit b2e6b32

3 files changed

Lines changed: 58 additions & 15 deletions

File tree

src/mark.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,25 @@ ex_changes(exarg_T *eap UNUSED)
10311031
*lp += amount_after; \
10321032
}
10331033

1034+
// Like one_adjust_nodel(), but if the position is within the deleted range,
1035+
// move it to the start of the line before the range.
1036+
#define one_adjust_cursor(pp) \
1037+
{ \
1038+
pos_T *posp = pp; \
1039+
if (posp->lnum >= line1 && posp->lnum <= line2) \
1040+
{ \
1041+
if (amount == MAXLNUM) /* line with cursor is deleted */ \
1042+
{ \
1043+
posp->lnum = MAX(line1 - 1, 1); \
1044+
posp->col = 0; \
1045+
} \
1046+
else /* keep cursor on the same line */ \
1047+
posp->lnum += amount; \
1048+
} \
1049+
else if (amount_after && posp->lnum > line2) \
1050+
posp->lnum += amount_after; \
1051+
}
1052+
10341053
/*
10351054
* Adjust marks between "line1" and "line2" (inclusive) to move "amount" lines.
10361055
* Must be called before changed_*(), appended_lines() or deleted_lines().
@@ -1075,6 +1094,7 @@ mark_adjust_internal(
10751094
linenr_T *lp;
10761095
win_T *win;
10771096
tabpage_T *tab;
1097+
wininfo_T *wip;
10781098
static pos_T initpos = {1, 0, 0};
10791099

10801100
if (line2 < line1 && amount_after == 0L) // nothing to do
@@ -1192,21 +1212,7 @@ mark_adjust_internal(
11921212
win->w_topfill = 0;
11931213
#endif
11941214
}
1195-
if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2)
1196-
{
1197-
if (amount == MAXLNUM) // line with cursor is deleted
1198-
{
1199-
if (line1 <= 1)
1200-
win->w_cursor.lnum = 1;
1201-
else
1202-
win->w_cursor.lnum = line1 - 1;
1203-
win->w_cursor.col = 0;
1204-
}
1205-
else // keep cursor on the same line
1206-
win->w_cursor.lnum += amount;
1207-
}
1208-
else if (amount_after && win->w_cursor.lnum > line2)
1209-
win->w_cursor.lnum += amount_after;
1215+
one_adjust_cursor(&(win->w_cursor));
12101216
}
12111217

12121218
#ifdef FEAT_FOLDING
@@ -1221,6 +1227,10 @@ mark_adjust_internal(
12211227
// adjust diffs
12221228
diff_mark_adjust(line1, line2, amount, amount_after);
12231229
#endif
1230+
1231+
// adjust per-window "last cursor" positions
1232+
FOR_ALL_BUF_WININFO(curbuf, wip)
1233+
one_adjust_cursor(&(wip->wi_fpos));
12241234
}
12251235

12261236
// This code is used often, needs to be fast.

src/testdir/test_buffer.vim

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,17 +623,48 @@ func Test_switch_to_previously_viewed_buffer()
623623
vsplit
624624

625625
call cursor(100, 3)
626+
call assert_equal('100', getline('.'))
626627
edit Xotherbuf
627628
buffer Xviewbuf
628629
call assert_equal([0, 100, 3, 0], getpos('.'))
630+
call assert_equal('100', getline('.'))
629631

632+
edit Xotherbuf
633+
wincmd p
634+
normal! gg10dd
635+
wincmd p
636+
buffer Xviewbuf
637+
call assert_equal([0, 90, 3, 0], getpos('.'))
638+
call assert_equal('100', getline('.'))
639+
640+
edit Xotherbuf
641+
wincmd p
642+
normal! ggP
643+
wincmd p
644+
buffer Xviewbuf
645+
call assert_equal([0, 100, 3, 0], getpos('.'))
646+
call assert_equal('100', getline('.'))
647+
648+
edit Xotherbuf
649+
wincmd p
650+
normal! 96gg10ddgg
651+
wincmd p
652+
buffer Xviewbuf
653+
" The original cursor line was deleted, so cursor is restored to the start
654+
" of the line before the deleted range.
655+
call assert_equal([0, 95, 1, 0], getpos('.'))
656+
call assert_equal('95', getline('.'))
657+
658+
normal! u
630659
exe win_id2win(oldwin) .. 'close'
631660
setlocal bufhidden=hide
632661

633662
call cursor(200, 3)
663+
call assert_equal('200', getline('.'))
634664
edit Xotherbuf
635665
buffer Xviewbuf
636666
call assert_equal([0, 200, 3, 0], getpos('.'))
667+
call assert_equal('200', getline('.'))
637668

638669
bwipe! Xotherbuf
639670
bwipe! Xviewbuf

src/version.c

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

730730
static int included_patches[] =
731731
{ /* Add new patch number below this line */
732+
/**/
733+
1885,
732734
/**/
733735
1884,
734736
/**/

0 commit comments

Comments
 (0)