Commit: patch 9.2.0885: scroll: 'smoothscroll' position is lost when the window is squeezed

Christian Brabandt <[email protected]> Fri, 31 Jul 2026 21:00:05 +0200
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
patch 9.2.0885: scroll: 'smoothscroll' position is lost when the window is squeezed

Commit: https://github.com/vim/vim/commit/15f8ba5cec35feea22622fbc7c78f3204aad50df
Author: Hirohito Higashi <[email protected]>
Date:   Fri Jul 31 18:39:49 2026 +0000

    patch 9.2.0885: scroll: 'smoothscroll' position is lost when the window is squeezed
    
    Problem:  With 'smoothscroll' the scroll position in a long line is lost when
              a window is temporarily squeezed to a couple of lines, for example
              when opening and closing a help window.
    Solution: When the cursor ends up in the skipped columns, skip up to the
              screen line the cursor is in instead of showing the start of the
              line.
    
    closes: #20892
    
    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/move.c b/src/move.c
index 9f9013424..cd9169de9 100644
--- a/src/move.c
+++ b/src/move.c
@@ -2537,9 +2537,23 @@ scroll_cursor_top(int min_scroll, int always)
 	{
 	    validate_virtcol();
 	    if (curwin->w_skipcol >= curwin->w_virtcol)
-		// TODO: if the line doesn't fit may optimize w_skipcol instead
-		// of making it zero
-		reset_skipcol();
+	    {
+		// Skip up to the screen line the cursor is in, so that the
+		// position in the line is kept.
+		int	width1 = curwin->w_width - curwin_col_off();
+		int	width2 = width1 + curwin_col_off2();
+		int	plines_off = 0;
+		int	skipcol;
+
+		if (width2 > 0 && curwin->w_virtcol >= (colnr_T)width1)
+		    plines_off = (curwin->w_virtcol - width1) / width2 + 1;
+		skipcol = skipcol_from_plines(curwin, plines_off);
+		if (skipcol != curwin->w_skipcol)
+		{
+		    curwin->w_skipcol = skipcol;
+		    redraw_later(UPD_SOME_VALID);
+		}
+	    }
 	}
 	if (curwin->w_topline != old_topline
 		|| curwin->w_skipcol != old_skipcol
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index 992d76388..fc266da03 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -1349,6 +1349,27 @@ func Test_smoothscroll_cursor_back_in_line()
   bwipe!
 endfunc
 
+func Test_smoothscroll_squeezed_window()
+  setlocal smoothscroll
+  call setline(1, [repeat('x', 3000)] + repeat(['line'], 10))
+  exe "norm! gg10\<C-E>"
+  redraw
+  let skipcol = winsaveview().skipcol
+  call assert_notequal(0, skipcol)
+  let virtcol = virtcol('.')
+
+  " Squeezing the window to one line and restoring it must not scroll back to
+  " the start of the line.
+  new
+  wincmd _
+  close
+  redraw
+  call assert_notequal(0, winsaveview().skipcol)
+  call assert_equal(virtcol, virtcol('.'))
+
+  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 29de0350f..55f755f23 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 */
+/**/
+    885,
 /**/
     884,
 /**/

-- 
-- 
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/E1wpsSj-006Ff6-O4%40256bit.org.