]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1958: Wrong display with sign_unplace() and setline() in CursorMoved v9.1.1958
authorzeertzjq <zeertzjq@outlook.com>
Sun, 7 Dec 2025 17:45:19 +0000 (18:45 +0100)
committerChristian Brabandt <cb@256bit.org>
Sun, 7 Dec 2025 17:45:19 +0000 (18:45 +0100)
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 <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/drawscreen.c
src/testdir/dumps/Test_display_scroll_setline_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_display_scroll_setline_2.dump [new file with mode: 0644]
src/testdir/dumps/Test_display_scroll_setline_3.dump [new file with mode: 0644]
src/testdir/dumps/Test_display_scroll_setline_4.dump [new file with mode: 0644]
src/testdir/dumps/Test_display_scroll_setline_5.dump [new file with mode: 0644]
src/testdir/test_display.vim
src/version.c

index 46832302c2c1940e40b056e3b88aa8ecf105f065..c6baf0ca83a78e39a91c15d4f3aed0a38c654c88 100644 (file)
@@ -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 (file)
index 0000000..3ea65e4
--- /dev/null
@@ -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 (file)
index 0000000..29e0742
--- /dev/null
@@ -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 (file)
index 0000000..f70dfa7
--- /dev/null
@@ -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 (file)
index 0000000..201c07d
--- /dev/null
@@ -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 (file)
index 0000000..a528ed1
--- /dev/null
@@ -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|%| 
index 3a3632a1969a6ac63c1f59051d59307c0834e1ae..3eca1765ca32cd670dbfcad866083254759010ea 100644 (file)
@@ -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
index ea874bc9b2f6460b024872ee75ef55723edcb31b..7b208128cb2c52d0863615332d00065e3d2c308d 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1958,
 /**/
     1957,
 /**/