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:
committed by
Christian Brabandt
parent
9ad706735d
commit
b2e6b328da
40
src/mark.c
40
src/mark.c
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user