From b2e6b328dafe1cdfff10f1e811355e514da8071d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 28 Oct 2025 20:27:19 +0000 Subject: [PATCH] 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 Signed-off-by: Christian Brabandt --- src/mark.c | 40 +++++++++++++++++++++++-------------- src/testdir/test_buffer.vim | 31 ++++++++++++++++++++++++++++ src/version.c | 2 ++ 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/mark.c b/src/mark.c index 33cd55feaf..c872e2f0ff 100644 --- a/src/mark.c +++ b/src/mark.c @@ -1031,6 +1031,25 @@ ex_changes(exarg_T *eap UNUSED) *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. * Must be called before changed_*(), appended_lines() or deleted_lines(). @@ -1075,6 +1094,7 @@ mark_adjust_internal( linenr_T *lp; win_T *win; tabpage_T *tab; + wininfo_T *wip; static pos_T initpos = {1, 0, 0}; if (line2 < line1 && amount_after == 0L) // nothing to do @@ -1192,21 +1212,7 @@ mark_adjust_internal( win->w_topfill = 0; #endif } - if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) - { - 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; + one_adjust_cursor(&(win->w_cursor)); } #ifdef FEAT_FOLDING @@ -1221,6 +1227,10 @@ mark_adjust_internal( // adjust diffs diff_mark_adjust(line1, line2, amount, amount_after); #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. diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim index 90b7a9aa43..1ffa7ae879 100644 --- a/src/testdir/test_buffer.vim +++ b/src/testdir/test_buffer.vim @@ -623,17 +623,48 @@ func Test_switch_to_previously_viewed_buffer() vsplit call cursor(100, 3) + call assert_equal('100', getline('.')) edit Xotherbuf buffer Xviewbuf 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' setlocal bufhidden=hide call cursor(200, 3) + call assert_equal('200', getline('.')) edit Xotherbuf buffer Xviewbuf call assert_equal([0, 200, 3, 0], getpos('.')) + call assert_equal('200', getline('.')) bwipe! Xotherbuf bwipe! Xviewbuf diff --git a/src/version.c b/src/version.c index e225e9439b..7b814f7260 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1885, /**/ 1884, /**/ -- 2.47.3