From e9dc4da86e16cee3898133ae82abafc712e1a70b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 12 Aug 2026 08:16:08 +0800 Subject: [PATCH] vim-patch:9.2.0938: cursorbind: cursor in the other window is not updated after undo (#41282) Problem: In diff mode with 'cursorbind' the cursor in the other window is not updated after an undo that changes which lines correspond. Solution: Also check whether the text changed before skipping the update (Hirohito Higashi). fixes: vim/vim#20982 related: vim/vim#13219 related: vim/vim#13210 closes: vim/vim#21004 https://github.com/vim/vim/commit/2045a20d4bf604c47828bfc22d2da25f0294bc01 Co-authored-by: Hirohito Higashi Co-authored-by: Claude Opus 5 (1M context) --- src/nvim/move.c | 11 ++++++++++- test/old/testdir/test_diffmode.vim | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/nvim/move.c b/src/nvim/move.c index 573bcab15b..dbcc597157 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -2588,12 +2588,21 @@ int pagescroll(Direction dir, int count, bool half) void do_check_cursorbind(void) { static win_T *prev_curwin = NULL; + static buf_T *prev_curbuf = NULL; + static varnumber_T prev_changedtick = 0; static pos_T prev_cursor = { 0, 0, 0 }; - if (curwin == prev_curwin && equalpos(curwin->w_cursor, prev_cursor)) { + assert(curwin != NULL && curbuf != NULL); + // Nothing to do when the cursor didn't move and the text didn't change. + // After a change the corresponding line in a diff may be different. + if (curwin == prev_curwin && curbuf == prev_curbuf + && buf_get_changedtick(curbuf) == prev_changedtick + && equalpos(curwin->w_cursor, prev_cursor)) { return; } prev_curwin = curwin; + prev_curbuf = curbuf; + prev_changedtick = buf_get_changedtick(curbuf); prev_cursor = curwin->w_cursor; linenr_T line = curwin->w_cursor.lnum; diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim index 2733ffc36b..3791849dce 100644 --- a/test/old/testdir/test_diffmode.vim +++ b/test/old/testdir/test_diffmode.vim @@ -3391,4 +3391,29 @@ func Test_diffput_to_empty_buf() call StopVimInTerminal(buf) endfunc +" Undo can change which lines correspond in a diff. 'cursorbind' must update +" the other window even when the cursor here did not move. +func Test_diff_cursorbind_after_undo() + call setline(1, ['x', 'y', 'c', 'd']) + let w1 = win_getid() + new + call setline(1, ['p', 'q', 'c', 'd']) + let w2 = win_getid() + windo diffthis + call win_gotoid(w1) + + normal! 2dd + call assert_equal(1, line('.', w1)) + call assert_equal(1, line('.', w2)) + normal! jk + call assert_equal(1, line('.', w1)) + call assert_equal(3, line('.', w2)) + + normal! u + call assert_equal(1, line('.', w1)) + call assert_equal(1, line('.', w2)) + + %bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab