From: Hirohito Higashi Date: Thu, 30 Jul 2026 19:40:11 +0000 (+0000) Subject: patch 9.2.0881: 'smoothscroll' position is lost when the window height changes X-Git-Tag: v9.2.0881^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17f3923b8c8bacf5785e7721108d39705dc3179c;p=thirdparty%2Fvim.git patch 9.2.0881: 'smoothscroll' position is lost when the window height changes Problem: With 'smoothscroll' the scroll position of a window is lost when its height changes. Solution: Only reset the skipped columns when 'smoothscroll' is off, where they just serve to keep the cursor visible. closes: #20885 Co-Authored-By: Claude Opus 5 (1M context) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim index 6d4fc81b81..cf362b6a29 100644 --- a/src/testdir/test_scroll_opt.vim +++ b/src/testdir/test_scroll_opt.vim @@ -1306,6 +1306,30 @@ func Test_smoothscroll_next_topline() bwipe! endfunc +func Test_smoothscroll_keep_skipcol() + call NewWindow(10, 40) + setlocal smoothscroll + call setline(1, ['abcde '->repeat(150)]->repeat(2)) + + exe "norm! 10\" + redraw + let skipcol = winsaveview().skipcol + call assert_notequal(0, skipcol) + + " Changing the height of the window must not reset the scroll position. + resize -3 + resize +3 + redraw + call assert_equal(skipcol, winsaveview().skipcol) + + " Using the autocommand window changes the height as well. + call bufload(bufadd('')) + redraw + call assert_equal(skipcol, winsaveview().skipcol) + + bwipe! +endfunc + func Test_smoothscroll_long_line_zb() call NewWindow(10, 40) call setline(1, 'abcde '->repeat(150)) diff --git a/src/version.c b/src/version.c index caef0f750a..7f650d214a 100644 --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 881, /**/ 880, /**/ diff --git a/src/window.c b/src/window.c index f2ee69071d..04d3d86c4e 100644 --- a/src/window.c +++ b/src/window.c @@ -7413,7 +7413,10 @@ win_new_height(win_T *wp, int height) // values might be invalid. if (!exiting && *p_spk == 'c') { - wp->w_skipcol = 0; + // With 'smoothscroll' w_skipcol is the scroll position, keep it. + // Otherwise it only keeps the cursor visible and is computed again. + if (!wp->w_p_sms) + wp->w_skipcol = 0; scroll_to_fraction(wp, prev_height); } } @@ -7469,14 +7472,16 @@ scroll_to_fraction(win_T *wp, int prev_height) if (wp->w_wrow >= wp->w_height && (wp->w_width - win_col_off(wp)) > 0) { - wp->w_skipcol += wp->w_width - win_col_off(wp); + // The cursor must be visible, override the scroll position. + colnr_T skipcol = wp->w_width - win_col_off(wp); + --wp->w_wrow; while (wp->w_wrow >= wp->w_height) { - wp->w_skipcol += wp->w_width - win_col_off(wp) - + win_col_off2(wp); + skipcol += wp->w_width - win_col_off(wp) + win_col_off2(wp); --wp->w_wrow; } + wp->w_skipcol = skipcol; } } else if (sline > 0)