Commit: patch 9.2.0881: 'smoothscroll' position is lost when the window height changes

Christian Brabandt <[email protected]> Thu, 30 Jul 2026 21:45:06 +0200
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
patch 9.2.0881: 'smoothscroll' position is lost when the window height changes

Commit: https://github.com/vim/vim/commit/17f3923b8c8bacf5785e7721108d39705dc3179c
Author: Hirohito Higashi <[email protected]>
Date:   Thu Jul 30 19:40:11 2026 +0000

    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) <[email protected]>
    Signed-off-by: Hirohito Higashi <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index 6d4fc81b8..cf362b6a2 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\<C-E>"
+  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 caef0f750..7f650d214 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 f2ee69071..04d3d86c4 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)

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wpWgk-004cyZ-Nu%40256bit.org.