0
0
mirror of https://github.com/vim/vim.git synced 2025-11-13 22:54:27 -05:00

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 <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
zeertzjq
2025-10-28 20:27:19 +00:00
committed by Christian Brabandt
parent 9ad706735d
commit b2e6b328da
3 changed files with 58 additions and 15 deletions

View File

@@ -1031,6 +1031,25 @@ ex_changes(exarg_T *eap UNUSED)
*lp += amount_after; \ *lp += amount_after; \
} }
// Like one_adjust_nodel(), but if the position is within the deleted range,
// move it to the start of the line before the range.
#define one_adjust_cursor(pp) \
{ \
pos_T *posp = pp; \
if (posp->lnum >= line1 && posp->lnum <= line2) \
{ \
if (amount == MAXLNUM) /* line with cursor is deleted */ \
{ \
posp->lnum = MAX(line1 - 1, 1); \
posp->col = 0; \
} \
else /* keep cursor on the same line */ \
posp->lnum += amount; \
} \
else if (amount_after && posp->lnum > line2) \
posp->lnum += amount_after; \
}
/* /*
* Adjust marks between "line1" and "line2" (inclusive) to move "amount" lines. * Adjust marks between "line1" and "line2" (inclusive) to move "amount" lines.
* Must be called before changed_*(), appended_lines() or deleted_lines(). * Must be called before changed_*(), appended_lines() or deleted_lines().
@@ -1075,6 +1094,7 @@ mark_adjust_internal(
linenr_T *lp; linenr_T *lp;
win_T *win; win_T *win;
tabpage_T *tab; tabpage_T *tab;
wininfo_T *wip;
static pos_T initpos = {1, 0, 0}; static pos_T initpos = {1, 0, 0};
if (line2 < line1 && amount_after == 0L) // nothing to do if (line2 < line1 && amount_after == 0L) // nothing to do
@@ -1192,21 +1212,7 @@ mark_adjust_internal(
win->w_topfill = 0; win->w_topfill = 0;
#endif #endif
} }
if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) one_adjust_cursor(&(win->w_cursor));
{
if (amount == MAXLNUM) // line with cursor is deleted
{
if (line1 <= 1)
win->w_cursor.lnum = 1;
else
win->w_cursor.lnum = line1 - 1;
win->w_cursor.col = 0;
}
else // keep cursor on the same line
win->w_cursor.lnum += amount;
}
else if (amount_after && win->w_cursor.lnum > line2)
win->w_cursor.lnum += amount_after;
} }
#ifdef FEAT_FOLDING #ifdef FEAT_FOLDING
@@ -1221,6 +1227,10 @@ mark_adjust_internal(
// adjust diffs // adjust diffs
diff_mark_adjust(line1, line2, amount, amount_after); diff_mark_adjust(line1, line2, amount, amount_after);
#endif #endif
// adjust per-window "last cursor" positions
FOR_ALL_BUF_WININFO(curbuf, wip)
one_adjust_cursor(&(wip->wi_fpos));
} }
// This code is used often, needs to be fast. // This code is used often, needs to be fast.

View File

@@ -623,17 +623,48 @@ func Test_switch_to_previously_viewed_buffer()
vsplit vsplit
call cursor(100, 3) call cursor(100, 3)
call assert_equal('100', getline('.'))
edit Xotherbuf edit Xotherbuf
buffer Xviewbuf buffer Xviewbuf
call assert_equal([0, 100, 3, 0], getpos('.')) call assert_equal([0, 100, 3, 0], getpos('.'))
call assert_equal('100', getline('.'))
edit Xotherbuf
wincmd p
normal! gg10dd
wincmd p
buffer Xviewbuf
call assert_equal([0, 90, 3, 0], getpos('.'))
call assert_equal('100', getline('.'))
edit Xotherbuf
wincmd p
normal! ggP
wincmd p
buffer Xviewbuf
call assert_equal([0, 100, 3, 0], getpos('.'))
call assert_equal('100', getline('.'))
edit Xotherbuf
wincmd p
normal! 96gg10ddgg
wincmd p
buffer Xviewbuf
" The original cursor line was deleted, so cursor is restored to the start
" of the line before the deleted range.
call assert_equal([0, 95, 1, 0], getpos('.'))
call assert_equal('95', getline('.'))
normal! u
exe win_id2win(oldwin) .. 'close' exe win_id2win(oldwin) .. 'close'
setlocal bufhidden=hide setlocal bufhidden=hide
call cursor(200, 3) call cursor(200, 3)
call assert_equal('200', getline('.'))
edit Xotherbuf edit Xotherbuf
buffer Xviewbuf buffer Xviewbuf
call assert_equal([0, 200, 3, 0], getpos('.')) call assert_equal([0, 200, 3, 0], getpos('.'))
call assert_equal('200', getline('.'))
bwipe! Xotherbuf bwipe! Xotherbuf
bwipe! Xviewbuf bwipe! Xviewbuf

View File

@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1885,
/**/ /**/
1884, 1884,
/**/ /**/