From acc3554439e5a08be0707b1dea0c923c43a2091b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 2 Jan 2026 08:21:55 +0800 Subject: [PATCH] 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> --- src/nvim/undo.c | 8 +++++--- test/functional/ui/bufhl_spec.lua | 4 ++-- test/old/testdir/test_undo.vim | 11 +++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/nvim/undo.c b/src/nvim/undo.c index f013665fd0..fc5c2fd7a8 100644 --- 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 index 58fd50e724..f8151f5c55 100644 --- 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 index 41c4284bef..68a2fc7857 100644 --- 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