patch 9.1.1958: Wrong display with sign_unplace() and setline() in CursorMoved
Commit: https://github.com/vim/vim/commit/2da433cff7a7fff965a1e14dbee3dc4160d0ed74 Author: zeertzjq <[email protected]> Date: Sun Dec 7 18:45:19 2025 +0100 patch 9.1.1958: Wrong display with sign_unplace() and setline() in CursorMoved Problem: Wrong display when scrolling with 'scrolloff' and calling sign_unplace() and setline() in CursorMoved (after 8.2.3204). Solution: Still scroll for changed lines below the top area when the top is scrolled down (zeertzjq) closes: #18878 Signed-off-by: zeertzjq <[email protected]> Signed-off-by: Christian Brabandt <[email protected]> diff --git a/src/drawscreen.c b/src/drawscreen.c index 46832302c..c6baf0ca8 100644 --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -1426,7 +1426,7 @@ fold_line( * - continue redrawing when syntax status is invalid. * 4. if scrolled up, update lines at the bottom. * This results in three areas that may need updating: - * top: from first row to top_end (when scrolled down) + * top: from first row to top_end (when scrolled down) * mid: from mid_start to mid_end (update inversion or changed text) * bot: from bot_start to last row (when scrolled up) */ @@ -1445,6 +1445,8 @@ win_update(win_T *wp) // updating. 999 when no bot area updating int scrolled_down = FALSE; // TRUE when scrolled down when // w_topline got smaller a bit + int scrolled_for_mod = FALSE; // TRUE after scrolling for changed + // lines #ifdef FEAT_SEARCH_EXTRA int top_to_mod = FALSE; // redraw above mod_top #endif @@ -2280,11 +2282,14 @@ 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 when redrawing the top, scrolled already above. - if (lnum == mod_top - && mod_bot != MAXLNUM + // Don't scroll the top area which was already scrolled 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_for_mod = TRUE; + int old_cline_height = 0; int old_rows = 0; int new_rows = 0; diff --git a/src/testdir/dumps/Test_display_scroll_setline_1.dump b/src/testdir/dumps/Test_display_scroll_setline_1.dump new file mode 100644 index 000000000..3ea65e49d --- /dev/null +++ b/src/testdir/dumps/Test_display_scroll_setline_1.dump @@ -0,0 +1,15 @@ +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|7| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0@1| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|9| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|0| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|1| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|2| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|3| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|4| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|5| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|6| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|7| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0|8| @15 +| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0@1| @15 +| +0#0000e05#a8a8a8255@1>1+0#0000000#ffffff0|0@1| @14 +@10|1|0@1|,|1| |B|o|t| diff --git a/src/testdir/dumps/Test_display_scroll_setline_2.dump b/src/testdir/dumps/Test_display_scroll_setline_2.dump new file mode 100644 index 000000000..29e0742c4 --- /dev/null +++ b/src/testdir/dumps/Test_display_scroll_setline_2.dump @@ -0,0 +1,15 @@ +|>+0&#ffffff0| |7|5| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|6| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0@1| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|8| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|9| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|0| @15 +| +0#0000e05#a8a8a8255@1>8+0#0000000#ffffff0|1| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|2| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|3| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|4| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|5| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|6| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|7| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0@1| @15 +@10|8|1|,|1| @1|8|6|%| diff --git a/src/testdir/dumps/Test_display_scroll_setline_3.dump b/src/testdir/dumps/Test_display_scroll_setline_3.dump new file mode 100644 index 000000000..f70dfa7aa --- /dev/null +++ b/src/testdir/dumps/Test_display_scroll_setline_3.dump @@ -0,0 +1,15 @@ +|>+0&#ffffff0| |7|5| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|6| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0@1| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|8| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|9| @15 +| +0#0000e05#a8a8a8255@1>8+0#0000000#ffffff0|0| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|1| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|2| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|3| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|4| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|5| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|6| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|7| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0@1| @15 +@10|8|0|,|1| @1|8|6|%| diff --git a/src/testdir/dumps/Test_display_scroll_setline_4.dump b/src/testdir/dumps/Test_display_scroll_setline_4.dump new file mode 100644 index 000000000..201c07dd2 --- /dev/null +++ b/src/testdir/dumps/Test_display_scroll_setline_4.dump @@ -0,0 +1,15 @@ +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|4| @15 +|>| |7|5| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|6| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0@1| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|8| @15 +| +0#0000e05#a8a8a8255@1>7+0#0000000#ffffff0|9| @15 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o@1|f|o@1|f|o@1|f|o@1|f|o@1|f|o@1 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o@1|f|o@1|f|o@1|f|o@1|f|o@1|f|o@1 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o@1|f|o@1|f|o@1| @8 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|1| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|2| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|3| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|4| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|5| @15 +@10|7|9|,|1| @1|8|2|%| diff --git a/src/testdir/dumps/Test_display_scroll_setline_5.dump b/src/testdir/dumps/Test_display_scroll_setline_5.dump new file mode 100644 index 000000000..a528ed1f7 --- /dev/null +++ b/src/testdir/dumps/Test_display_scroll_setline_5.dump @@ -0,0 +1,15 @@ +|>+0&#ffffff0| |7|3| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|4| @15 +|>| |7|5| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|6| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0@1| @15 +| +0#0000e05#a8a8a8255@1>7+0#0000000#ffffff0|8| @15 +| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0|9| @15 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o@1|f|o@1|f|o@1|f|o@1|f|o@1|f|o@1 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o@1|f|o@1|f|o@1|f|o@1|f|o@1|f|o@1 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o@1|f|o@1|f|o@1| @8 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|1| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|2| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|3| @15 +| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0|4| @15 +@10|7|8|,|1| @1|8|1|%| diff --git a/src/testdir/test_display.vim b/src/testdir/test_display.vim index 3a3632a19..3eca1765c 100644 --- a/src/testdir/test_display.vim +++ b/src/testdir/test_display.vim @@ -265,6 +265,38 @@ func Test_display_scroll_update_visual() call StopVimInTerminal(buf) endfunc +func Test_display_scroll_setline() + CheckScreendump + + let lines =<< trim END + 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}) + normal! G + autocmd CursorMoved * if line('.') == 79 + \ | call sign_unplace('bar', #{id: 2}) + \ | call setline(80, repeat('foo', 15)) + \ | endif + END + call writefile(lines, 'XscrollSetline.vim', 'D') + + let buf = RunVimInTerminal('-S XscrollSetline.vim', #{rows: 15, cols: 20}) + call VerifyScreenDump(buf, 'Test_display_scroll_setline_1', {}) + call term_sendkeys(buf, '19k') + call VerifyScreenDump(buf, 'Test_display_scroll_setline_2', {}) + call term_sendkeys(buf, 'k') + call VerifyScreenDump(buf, 'Test_display_scroll_setline_3', {}) + call term_sendkeys(buf, 'k') + call VerifyScreenDump(buf, 'Test_display_scroll_setline_4', {}) + call term_sendkeys(buf, 'k') + call VerifyScreenDump(buf, 'Test_display_scroll_setline_5', {}) + + call StopVimInTerminal(buf) +endfunc + " Test for 'eob' (EndOfBuffer) item in 'fillchars' func Test_eob_fillchars() " default value diff --git a/src/version.c b/src/version.c index ea874bc9b..7b208128c 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1958, /**/ 1957, /**/ -- -- 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/E1vSJ3K-003ZVn-2r%40256bit.org.
