]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0208: MS-Windows: excessive scroll-behaviour with go+=! v9.2.0208
authorYasuhiro Matsumoto <mattn.jp@gmail.com>
Thu, 19 Mar 2026 21:48:57 +0000 (21:48 +0000)
committerChristian Brabandt <cb@256bit.org>
Thu, 19 Mar 2026 21:48:57 +0000 (21:48 +0000)
Problem:  MS-Windows: excessive scroll-behaviour with go+=! after
          switching to ConPTY as default (after v9.2.0048).
Solution: Use tl_cursor_pos to determine the number of lines to scroll
          (Yasuhiro Matsumoto).

Since patch 9.2.0048 (71cc1b12) made ConPTY the default on Windows 11,
running :!cmd with guioptions+=! scrolls up the entire window height
instead of only the output lines.

ConPTY damages all terminal rows on initialization even when they are
empty, which causes tl_dirty_row_end to equal Rows.  The scroll-up loop
in update_system_term() then scrolls the full screen because
(Rows - tl_toprow) < tl_dirty_row_end is always true until tl_toprow
reaches 0.

Use the cursor position instead of tl_dirty_row_end for the scroll
calculation, since it reflects where actual content has been written.

The scroll bug only occurs with ConPTY.  With winpty the terminal
finishes too quickly for the timer-based screen check to work.

closes: #19735

Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/terminal.c
src/testdir/test_gui.vim
src/version.c

index aaf30a1832d72196381fe605f338b5074cb04e7c..734282c82566d2feab1b420edfaddebf5c17f2b6 100644 (file)
@@ -4008,8 +4008,11 @@ update_system_term(term_T *term)
     screen = vterm_obtain_screen(term->tl_vterm);
 
     // Scroll up to make more room for terminal lines if needed.
+    // Use the cursor position to determine how much to scroll, because
+    // ConPTY may damage all rows on initialization even when most are
+    // empty, which would cause unnecessary scrolling.
     while (term->tl_toprow > 0
-                         && (Rows - term->tl_toprow) < term->tl_dirty_row_end)
+                 && (Rows - term->tl_toprow) < term->tl_cursor_pos.row + 1)
     {
        int save_p_more = p_more;
 
index 67b0500aa656dbd446922d9ab86f1b757be3303c..0b0eb02715f415eb53313b50517db337577c5e32 100644 (file)
@@ -960,6 +960,47 @@ func Test_gui_run_cmd_in_terminal()
   let &guioptions = save_guioptions
 endfunc
 
+" Test that :! with guioptions+=! doesn't scroll more than necessary.
+" With ConPTY on Windows 11, the terminal may damage all rows on init,
+" which previously caused the entire screen to scroll up.
+func Test_gui_system_term_scroll()
+  CheckFeature terminal
+  CheckFeature conpty
+  let save_guioptions = &guioptions
+  set guioptions+=!
+
+  enew
+  call setline(1, repeat(['AAAA'], &lines + 5))
+  redraw
+
+  " Timer fires during terminal_loop to check the screen while the command
+  " is still running.  Row 1 should still show buffer content if scrolling
+  " is correct.
+  let g:system_term_row1 = ''
+  func s:CheckScroll(timer)
+    let g:system_term_row1 = screenstring(1, 1)
+  endfunc
+  call timer_start(200, function('s:CheckScroll'))
+
+  " Use a command that runs long enough for the timer to fire during
+  " terminal_loop.  wait_return() returns immediately when sourcing a script,
+  " so the timer must fire before the command finishes.
+  if has('win32')
+    !ping -n 2 127.0.0.1 > nul
+  else
+    !sleep 1
+  endif
+
+  " With the ConPTY scroll bug, the screen scrolled up entirely and row 1
+  " became blank.  With the fix, only the output lines scroll and the buffer
+  " content remains visible near the top of the screen.
+  call assert_equal('A', g:system_term_row1)
+
+  %bwipe!
+  delfunc s:CheckScroll
+  let &guioptions = save_guioptions
+endfunc
+
 func Test_gui_recursive_mapping()
   nmap ' <C-W>
   nmap <C-W>a :let didit = 1<CR>
index 7482aa8b7199525c64ac76a58646c1b30a1bf469..bd95e9e3c45a151b9c0248fb903fce25bc510c89 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    208,
 /**/
     207,
 /**/