vim-patch:9.1.1964: Wrong display when using setline() at hit-enter prompt (#36878)

Problem:  Wrong display when using setline() at hit-enter prompt
          (after 8.2.3204).
Solution: Only skip scrolling for changed lines in top area if it's
          scrolled down due to w_topline change. Also add more testing
          for what 8.2.3204 fixed (zeertzjq).

closes: vim/vim#18887

e72eacceab
This commit is contained in:
zeertzjq
2025-12-09 22:25:34 +08:00
committed by GitHub
parent 3bc9a5b5d2
commit 5235f3663f
3 changed files with 101 additions and 11 deletions

View File

@@ -2039,11 +2039,11 @@ static void win_update(win_T *wp)
// When at start of changed lines: May scroll following lines
// up or down to minimize redrawing.
// Don't do this when the change continues until the end.
// Don't scroll the top area which was already scrolled above,
// but do scroll for changed lines below the top area.
// Don't scroll for changed lines in the top area if that's already
// done above, but do scroll for changed lines below the top area.
if (!scrolled_for_mod && mod_bot != MAXLNUM
&& lnum >= mod_top && lnum < MAX(mod_bot, mod_top + 1)
&& row >= top_end) {
&& (!scrolled_down || row >= top_end)) {
scrolled_for_mod = true;
int old_cline_height = 0;

View File

@@ -48,13 +48,19 @@ describe('display', function()
setlocal scrolloff=5 signcolumn=yes
call setline(1, range(1, 100))
call sign_define('foo', #{text: '>'})
call sign_place(1, 'bar', 'foo', bufnr(), #{lnum: 73})
call sign_place(2, 'bar', 'foo', bufnr(), #{lnum: 74})
call sign_place(3, 'bar', 'foo', bufnr(), #{lnum: 75})
call sign_place(1, 'bar', 'foo', bufnr(), #{lnum: 71})
call sign_place(2, 'bar', 'foo', bufnr(), #{lnum: 72})
call sign_place(3, 'bar', 'foo', bufnr(), #{lnum: 73})
call sign_place(4, 'bar', 'foo', bufnr(), #{lnum: 74})
call sign_place(5, 'bar', 'foo', bufnr(), #{lnum: 75})
normal! G
autocmd CursorMoved * if line('.') == 79
\ | call sign_unplace('bar', #{id: 2})
\ | call sign_unplace('bar', #{id: 4})
\ | call setline(80, repeat('foo', 15))
\ | elseif line('.') == 78
\ | call setline(72, repeat('bar', 10))
\ | elseif line('.') == 77
\ | call sign_unplace('bar', #{id: 2})
\ | endif
]])
screen:expect([[
@@ -144,6 +150,63 @@ describe('display', function()
{7: }84 |
|
]])
feed('k')
screen:expect([[
{7: }barbarbarbarbarbar|
{7: }barbarbarbar |
{7:> }73 |
{7: }74 |
{7:> }75 |
{7: }76 |
{7: }^77 |
{7: }78 |
{7: }79 |
{7: }foofoofoofoofoofoo|*2
{7: }foofoofoo |
{7: }81 |
{7: }82 |
|
]])
end)
-- oldtest: Test_display_hit_enter_setline()
it('using setline() at hit-enter prompt', function()
local screen = Screen.new(40, 8)
exec([[
call setline(1, range(1, 100))
]])
screen:expect([[
^1 |
2 |
3 |
4 |
5 |
6 |
7 |
|
]])
feed([[:echo "abc\ndef\nghi"<CR>]])
screen:expect([[
1 |
2 |
3 |
{3: }|
abc |
def |
ghi |
{6:Press ENTER or type command to continue}^ |
]])
feed([[:call setline(2, repeat('foo', 35))<CR>]])
screen:expect([[
^1 |
foofoofoofoofoofoofoofoofoofoofoofoofoof|
oofoofoofoofoofoofoofoofoofoofoofoofoofo|
ofoofoofoofoofoofoofoofoo |
3 |
4 |
5 |
|
]])
end)
local function run_test_display_lastline(euro)

View File

@@ -275,13 +275,19 @@ func Test_display_scroll_setline()
setlocal scrolloff=5 signcolumn=yes
call setline(1, range(1, 100))
call sign_define('foo', #{text: '>'})
call sign_place(1, 'bar', 'foo', bufnr(), #{lnum: 73})
call sign_place(2, 'bar', 'foo', bufnr(), #{lnum: 74})
call sign_place(3, 'bar', 'foo', bufnr(), #{lnum: 75})
call sign_place(1, 'bar', 'foo', bufnr(), #{lnum: 71})
call sign_place(2, 'bar', 'foo', bufnr(), #{lnum: 72})
call sign_place(3, 'bar', 'foo', bufnr(), #{lnum: 73})
call sign_place(4, 'bar', 'foo', bufnr(), #{lnum: 74})
call sign_place(5, 'bar', 'foo', bufnr(), #{lnum: 75})
normal! G
autocmd CursorMoved * if line('.') == 79
\ | call sign_unplace('bar', #{id: 2})
\ | call sign_unplace('bar', #{id: 4})
\ | call setline(80, repeat('foo', 15))
\ | elseif line('.') == 78
\ | call setline(72, repeat('bar', 10))
\ | elseif line('.') == 77
\ | call sign_unplace('bar', #{id: 2})
\ | endif
END
call writefile(lines, 'XscrollSetline.vim', 'D')
@@ -296,6 +302,27 @@ func Test_display_scroll_setline()
call VerifyScreenDump(buf, 'Test_display_scroll_setline_4', {})
call term_sendkeys(buf, 'k')
call VerifyScreenDump(buf, 'Test_display_scroll_setline_5', {})
call term_sendkeys(buf, 'k')
call VerifyScreenDump(buf, 'Test_display_scroll_setline_6', {})
call StopVimInTerminal(buf)
endfunc
func Test_display_hit_enter_setline()
CheckScreendump
let lines =<< trim END
call setline(1, range(1, 100))
END
call writefile(lines, 'XhitEnterSetline.vim', 'D')
let buf = RunVimInTerminal('-S XhitEnterSetline.vim', #{rows: 8, cols: 40})
call VerifyScreenDump(buf, 'Test_display_hit_enter_setline_1', {})
call term_sendkeys(buf, ':echo "abc\ndef\nghi"')
call term_sendkeys(buf, "\<CR>")
call VerifyScreenDump(buf, 'Test_display_hit_enter_setline_2', {})
call term_sendkeys(buf, ":call setline(2, repeat('foo', 35))\<CR>")
call VerifyScreenDump(buf, 'Test_display_hit_enter_setline_3', {})
call StopVimInTerminal(buf)
endfunc