From f623fad9c4bf534de8d7c16a2131a62b13d3f1f8 Mon Sep 17 00:00:00 2001 From: "neovim-backports[bot]" <175700243+neovim-backports[bot]@users.noreply.github.com> Date: Tue, 13 May 2025 10:43:25 +0200 Subject: [PATCH] vim-patch:9.1.1385: inefficient loop for 'nosmoothscroll' scrolling (#33992) Problem: Loop that ensures "w_skipcol" is zero with 'nosmoothscroll' for (half)-page scrolling is inefficient. Solution: Calculate the required "count" instead of looping until "w_skipcol" is zero (Luuk van Baal). https://github.com/vim/vim/commit/acf0ebe8a8f4dd389a8fe8cea52ff43bc8bfe1be (cherry picked from commit d539a952da2520bac7e0b4d4b28bf6ff53c39b7b) --------- Co-authored-by: luukvbaal Co-authored-by: zeertzjq --- src/nvim/move.c | 13 +++++++++---- test/old/testdir/test_normal.vim | 9 +++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/nvim/move.c b/src/nvim/move.c index dcd81bc936..f6b34911f7 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -2424,11 +2424,16 @@ static bool scroll_with_sms(Direction dir, int count, int *curscount) if (labs(curwin->w_topline - prev_topline) > (dir == BACKWARD)) { fixdir = dir * -1; } - while (curwin->w_skipcol > 0 - && curwin->w_topline < curbuf->b_ml.ml_line_count) { - scroll_redraw(fixdir == FORWARD, 1); - *curscount += (fixdir == dir ? 1 : -1); + + int width1 = curwin->w_width_inner - win_col_off(curwin); + int width2 = width1 + win_col_off2(curwin); + count = 1 + (curwin->w_skipcol - width1) / width2; + if (fixdir == FORWARD) { + count = 2 + (linetabsize_eol(curwin, curwin->w_topline) + - curwin->w_skipcol - width1) / width2; } + scroll_redraw(fixdir == FORWARD, count); + *curscount += count * (fixdir == dir ? 1 : -1); } curwin->w_p_sms = prev_sms; diff --git a/test/old/testdir/test_normal.vim b/test/old/testdir/test_normal.vim index b82e544e62..38ab6965a3 100644 --- a/test/old/testdir/test_normal.vim +++ b/test/old/testdir/test_normal.vim @@ -4339,4 +4339,13 @@ func Test_scroll_longline_scrolloff() bwipe! endfunc +" Benchmark test for Ctrl-F with 'nosmoothscroll' +func Test_scroll_longline_benchmark() + call setline(1, ['foo'->repeat(20000)] + ['']) + let start = reltime() + exe "normal! \" + call assert_inrange(0, 0.1, reltimefloat(reltime(start))) + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab nofoldenable