From: Yasuhiro Matsumoto Date: Thu, 19 Mar 2026 21:48:57 +0000 (+0000) Subject: patch 9.2.0208: MS-Windows: excessive scroll-behaviour with go+=! X-Git-Tag: v9.2.0208^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=67ae763557122ad957d68e8dca2a1b12688e2572;p=thirdparty%2Fvim.git patch 9.2.0208: MS-Windows: excessive scroll-behaviour with go+=! 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 Signed-off-by: Christian Brabandt --- diff --git a/src/terminal.c b/src/terminal.c index aaf30a1832..734282c825 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -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; diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim index 67b0500aa6..0b0eb02715 100644 --- a/src/testdir/test_gui.vim +++ b/src/testdir/test_gui.vim @@ -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 ' nmap a :let didit = 1 diff --git a/src/version.c b/src/version.c index 7482aa8b71..bd95e9e3c4 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 208, /**/ 207, /**/