From 0b91e9f83b8807bf3fb584a70607deb1360824bd Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Fri, 27 Jun 2025 11:16:23 +0200 Subject: [PATCH] vim-patch:9.1.1482: scrolling with 'splitkeep' and line() (#34670) Problem: Topline is preemptively updated by line() in WinResized autocmd with 'splitkeep' != "cursor". Solution: Set `skip_update_topline` when 'splitkeep' != "cursor". (Luuk van Baal) https://github.com/vim/vim/commit/fe803c8c04c1b73453c0dab970863ab53e3eeec7 --- src/nvim/eval/funcs.c | 10 ++++---- test/functional/legacy/window_cmd_spec.lua | 27 ++++++++++++++++++++++ test/old/testdir/test_window_cmd.vim | 18 +++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 126935837e..6f98d0eb5f 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -4379,17 +4379,15 @@ static void f_line(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (wp != NULL && tp != NULL) { switchwin_T switchwin; if (switch_win_noblock(&switchwin, wp, tp, true) == OK) { - // in diff mode, prevent that the window scrolls - // and keep the topline - if (curwin->w_p_diff && switchwin.sw_curwin->w_p_diff) { + // With 'splitkeep' != cursor and in diff mode, prevent that the + // window scrolls and keep the topline. + if (*p_spk != 'c' || (curwin->w_p_diff && switchwin.sw_curwin->w_p_diff)) { skip_update_topline = true; } check_cursor(curwin); fp = var2fpos(&argvars[0], true, &fnum, false); } - if (curwin->w_p_diff && switchwin.sw_curwin->w_p_diff) { - skip_update_topline = false; - } + skip_update_topline = false; restore_win_noblock(&switchwin, true); } } else { diff --git a/test/functional/legacy/window_cmd_spec.lua b/test/functional/legacy/window_cmd_spec.lua index fac982354c..37d1101ff2 100644 --- a/test/functional/legacy/window_cmd_spec.lua +++ b/test/functional/legacy/window_cmd_spec.lua @@ -326,4 +326,31 @@ describe('splitkeep', function() | ]]) end) + + -- oldtest: Test_splitkeep_line() + it("no scrolling with 'splitkeep' and line()", function() + screen:try_resize(40, 6) + exec([[ + set splitkeep=screen nosplitbelow + autocmd WinResized * call line('w0', 1000) + call setline(1, range(1000)) + ]]) + screen:expect([[ + ^0 | + 1 | + 2 | + 3 | + 4 | + | + ]]) + feed(':wincmd s') + screen:expect([[ + ^0 | + 1 | + {3:[No Name] [+] }| + 3 | + {2:[No Name] [+] }| + :wincmd s | + ]]) + end) end) diff --git a/test/old/testdir/test_window_cmd.vim b/test/old/testdir/test_window_cmd.vim index 3501672f95..ae59adbc6e 100644 --- a/test/old/testdir/test_window_cmd.vim +++ b/test/old/testdir/test_window_cmd.vim @@ -2075,6 +2075,24 @@ func Test_splitkeep_skipcol() call VerifyScreenDump(buf, 'Test_splitkeep_skipcol_1', {}) endfunc +func Test_splitkeep_line() + CheckScreendump + + let lines =<< trim END + set splitkeep=screen nosplitbelow + autocmd WinResized * call line('w0', 1000) + call setline(1, range(1000)) + END + + call writefile(lines, 'XTestSplitkeepSkipcol', 'D') + let buf = RunVimInTerminal('-S XTestSplitkeepSkipcol', #{rows: 6, cols: 40}) + + call VerifyScreenDump(buf, 'Test_splitkeep_line_1', {}) + + call term_sendkeys(buf, ":wincmd s\") + call VerifyScreenDump(buf, 'Test_splitkeep_line_2', {}) +endfunc + func Test_new_help_window_on_error() help change.txt execute "normal! /CTRL-@\"