commit acc3554439e5a08be0707b1dea0c923c43a2091b
parent 94f7302e66965374c5b60f54c5e4b4f40b5a9c53
Author: zeertzjq <zeertzjq@outlook.com>
Date: Fri, 2 Jan 2026 08:21:55 +0800
vim-patch:9.1.2037: undo: cursor position not correctly restored (#37195)
Problem: undo: cursor position not correctly restored
Solution: Do not override the saved cursor position (altermo)
closes: vim/vim#19052
https://github.com/vim/vim/commit/a722da29c128576d581f451f3f6282de27680d9f
Co-authored-by: altermo <107814000+altermo@users.noreply.github.com>
Diffstat:
3 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
@@ -2298,15 +2298,17 @@ static void u_undoredo(bool undo, bool do_buf_event)
// Decide about the cursor position, depending on what text changed.
// Don't set it yet, it may be invalid if lines are going to be added.
- if (top < newlnum) {
+ {
// If the saved cursor is somewhere in this undo block, move it to
// the remembered position. Makes "gwap" put the cursor back
// where it was.
linenr_T lnum = curhead->uh_cursor.lnum;
if (lnum >= top && lnum <= top + newsize + 1) {
new_curpos = curhead->uh_cursor;
- newlnum = new_curpos.lnum - 1;
- } else {
+ // We don't want other entries to override saved cursor
+ // position.
+ newlnum = -1;
+ } else if (top < newlnum) {
// Use the first line that actually changed. Avoids that
// undoing auto-formatting puts the cursor in the previous
// line.
diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua
@@ -282,9 +282,9 @@ describe('Buffer highlighting', function()
screen:expect {
grid = [[
a {5:longer} example |
- ^in {6:order} to {7:de}{5:monstr}{7:ate} |
+ in {6:order} to {7:de}{5:monstr}{7:ate} |
{7:combin}{8:ing}{9: hi}ghlights |
- {9:from }{8:diff}{7:erent} sources |
+ {9:from }{8:diff}{7:erent} source^s |
{1:~ }|*3
1 change; before #2 {MATCH:.*}|
]],
diff --git a/test/old/testdir/test_undo.vim b/test/old/testdir/test_undo.vim
@@ -911,5 +911,16 @@ func Test_load_existing_undofile()
bw!
endfunc
+func Test_restore_cursor_position_after_undo()
+ CheckFeature persistent_undo
+ sp samples/test_undo.txt
+
+ 3 | exe "norm! gqk" | undojoin | 1 delete
+ call assert_equal(1, line('.'))
+ norm! u
+ call assert_equal(3, line('.'))
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab