]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0885: scroll: 'smoothscroll' position is lost when the window is squeezed v9.2.0885
authorHirohito Higashi <h.east.727@gmail.com>
Fri, 31 Jul 2026 18:39:49 +0000 (18:39 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 31 Jul 2026 18:39:49 +0000 (18:39 +0000)
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) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/move.c
src/testdir/test_scroll_opt.vim
src/version.c

index 9f90134249e762d8e941d33f8ea93bcdadc6e852..cd9169de94a575a4eb5eaf6925c65f3801f5ef45 100644 (file)
@@ -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
index 992d76388c878074adfd35bd715919f1ef108b4c..fc266da03e852bbc071a0660b55c1bf443232790 100644 (file)
@@ -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))
index 29de0350fa210e39dbe37fc27aefa5d455d129aa..55f755f23f656171cad1183ec57f8fa3b01d8211 100644 (file)
@@ -758,6 +758,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    885,
 /**/
     884,
 /**/