# HG changeset patch # User Bram Moolenaar # Date 1683829803 -7200 # Node ID 667d85c09e9cd58496489eef3c4fd042f4003d29 # Parent c4d65b5da13a306e1d2be7daeb9545b4486bec23 patch 9.0.1543: display errors when making topline shorter Commit: https://github.com/vim/vim/commit/5d01f86d99bc3a3fd92d4f4e9338a9e78e9ebe16 Author: Luuk van Baal Date: Thu May 11 19:24:20 2023 +0100 patch 9.0.1543: display errors when making topline shorter Problem: Display errors when making topline shorter and 'smoothscroll' is set. Solution: Reset w_skipcol when the topline becomes shorter than its current value. (Luuk van Baal, closes #12367) diff --git a/src/change.c b/src/change.c --- a/src/change.c +++ b/src/change.c @@ -553,13 +553,25 @@ changed_common( { if (wp->w_buffer == curbuf) { -#ifdef FEAT_FOLDING linenr_T last = lnume + xtra - 1; // last line after the change -#endif + // Mark this window to be redrawn later. if (!redraw_not_allowed && wp->w_redr_type < UPD_VALID) wp->w_redr_type = UPD_VALID; + // Reset "w_skipcol" if the topline length has become smaller to + // such a degree that nothing will be visible anymore, accounting + // for 'smoothscroll' <<< or 'listchars' "precedes" marker. + if (wp->w_skipcol > 0 + && (last < wp->w_topline + || (wp->w_topline >= lnum + && wp->w_topline < lnume + && win_linetabsize(wp, wp->w_topline, + ml_get(wp->w_topline), (colnr_T)MAXCOL) + <= wp->w_skipcol + (wp->w_p_list + && wp->w_lcs_chars.prec ? 1 : 3)))) + wp->w_skipcol = 0; + // Check if a change in the buffer has invalidated the cached // values for the cursor. #ifdef FEAT_FOLDING diff --git a/src/testdir/dumps/Test_display_long_line_1.dump b/src/testdir/dumps/Test_display_long_line_1.dump --- a/src/testdir/dumps/Test_display_long_line_1.dump +++ b/src/testdir/dumps/Test_display_long_line_1.dump @@ -9,6 +9,6 @@ @35 @35 @35 -@26>a@8 -@10| @24 -@18|1|,|4|8|2| @7|T|o|p| +@35 +>a@14| @19 +@18|1|,|7|3|6| @7|T|o|p| diff --git a/src/testdir/dumps/Test_display_long_line_2.dump b/src/testdir/dumps/Test_display_long_line_2.dump --- a/src/testdir/dumps/Test_display_long_line_2.dump +++ b/src/testdir/dumps/Test_display_long_line_2.dump @@ -9,6 +9,6 @@ @35 @35 @35 -@25>a| @8 +@34>a |b@4| |b@4| |b@4| |b@4| |b@4| |b@1|@+0#4040ff13&@2 -| +0#0000000&@17|1|,|4|8|1| @7|T|o|p| +| +0#0000000&@17|1|,|7|3|5| @7|T|o|p| diff --git a/src/testdir/dumps/Test_display_long_line_3.dump b/src/testdir/dumps/Test_display_long_line_3.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_display_long_line_3.dump @@ -0,0 +1,14 @@ +|<+0#4040ff13#ffffff0@2>a+0#0000000&| @30 +|b@4| |b@4| |b@4| |b@4| |b@4| |b@4 +| |b@4| |c@4| |c@4| |c@4| |c@4| |c@3 +@1| |c@4| |c@4| |d@4| |d@4| |d@4| |d@2 +@2| |d@4| |d@4| |d@4| @14 +|~+0#4040ff13&| @33 +|~| @33 +|~| @33 +|~| @33 +|~| @33 +|~| @33 +|~| @33 +|~| @33 +| +0#0000000&@17|1|,|3|1|9| @7|A|l@1| diff --git a/src/testdir/dumps/Test_display_long_line_4.dump b/src/testdir/dumps/Test_display_long_line_4.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_display_long_line_4.dump @@ -0,0 +1,14 @@ +|a+0&#ffffff0@34 +@35 +@35 +@35 +@35 +@35 +@35 +@35 +@35 +@2>a| @31 +|b@4| |b@4| |b@4| |b@4| |b@4| |b@4 +| |b@4| |c@4| |c@4| |c@4| |c@4| |c@3 +@1| |c@4| |c@4| |d@4| |d@4| |d@4| |@+0#4040ff13&@2 +| +0#0000000&@17|1|,|3|1|8| @7|T|o|p| diff --git a/src/testdir/dumps/Test_smooth_long_15.dump b/src/testdir/dumps/Test_smooth_long_15.dump --- a/src/testdir/dumps/Test_smooth_long_15.dump +++ b/src/testdir/dumps/Test_smooth_long_15.dump @@ -2,5 +2,5 @@ |h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o |t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o |f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |e|n|d| @11 -|f|o|u>r| @35 -@22|4|,|4| @10|B|o|t| +>f|o|u|r| @35 +@22|4|,|1| @10|B|o|t| diff --git a/src/testdir/dumps/Test_smooth_long_16.dump b/src/testdir/dumps/Test_smooth_long_16.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_smooth_long_16.dump @@ -0,0 +1,6 @@ +|<+0#4040ff13#ffffff0@2|t+0#0000000&|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t +|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o +|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o +|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |e|n|d| @11 +|f|o|u>r| @35 +@22|4|,|4| @10|B|o|t| diff --git a/src/testdir/test_display.vim b/src/testdir/test_display.vim --- a/src/testdir/test_display.vim +++ b/src/testdir/test_display.vim @@ -471,9 +471,9 @@ func Test_display_long_lastline() CheckScreendump let lines =<< trim END - set display=lastline + set display=lastline smoothscroll scrolloff=0 call setline(1, [ - \'aaaaa'->repeat(100), + \'aaaaa'->repeat(150), \'bbbbb '->repeat(7) .. 'ccccc '->repeat(7) .. 'ddddd '->repeat(7) \]) END @@ -481,11 +481,23 @@ func Test_display_long_lastline() call writefile(lines, 'XdispLongline', 'D') let buf = RunVimInTerminal('-S XdispLongline', #{rows: 14, cols: 35}) - call term_sendkeys(buf, "482|") + call term_sendkeys(buf, "736|") call VerifyScreenDump(buf, 'Test_display_long_line_1', {}) + + " The correct part of the last line is moved into view. call term_sendkeys(buf, "D") call VerifyScreenDump(buf, 'Test_display_long_line_2', {}) + " "w_skipcol" does not change because the topline is still long enough + " to maintain the current skipcol. + call term_sendkeys(buf, "g04l11gkD") + call VerifyScreenDump(buf, 'Test_display_long_line_3', {}) + + " "w_skipcol" is reset to bring the entire topline into view because + " the line length is now smaller than the current skipcol + marker. + call term_sendkeys(buf, "x") + call VerifyScreenDump(buf, 'Test_display_long_line_4', {}) + call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim --- a/src/testdir/test_scroll_opt.vim +++ b/src/testdir/test_scroll_opt.vim @@ -335,9 +335,12 @@ func Test_smoothscroll_wrap_long_line() " than one window. Note that the cursor is at the bottom this time because " Vim prefers to do so if we are scrolling a few lines only. call term_sendkeys(buf, ":call setline(1, ['one', 'two', 'Line' .. (' with lots of text'->repeat(10)) .. ' end', 'four'])\") + " Currently visible lines were replaced, test that the lines and cursor + " are correctly displayed. + call VerifyScreenDump(buf, 'Test_smooth_long_14', {}) call term_sendkeys(buf, "3Gzt") call term_sendkeys(buf, "j") - call VerifyScreenDump(buf, 'Test_smooth_long_14', {}) + call VerifyScreenDump(buf, 'Test_smooth_long_15', {}) " Repeat the step but this time start it when the line is smooth-scrolled by " one line. This tests that the offset calculation is still correct and @@ -345,7 +348,7 @@ func Test_smoothscroll_wrap_long_line() " screen. call term_sendkeys(buf, "3Gzt") call term_sendkeys(buf, "\j") - call VerifyScreenDump(buf, 'Test_smooth_long_15', {}) + call VerifyScreenDump(buf, 'Test_smooth_long_16', {}) call StopVimInTerminal(buf) endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1543, +/**/ 1542, /**/ 1541,