fix(move): consume skipcol before revealing filler lines (#34143)

Problem:  When scrolling (the text) down with 'smoothscroll', filler
          lines are revealed before the text skipped with `w_skipcol`.
Solution: Check `w_skipcol` before filler lines.

(cherry picked from commit 6ce2877327)
This commit is contained in:
luukvbaal
2025-05-24 01:14:18 +02:00
committed by GitHub
parent ff83c712cf
commit 334d8f506f
2 changed files with 69 additions and 43 deletions

View File

@@ -1331,56 +1331,55 @@ bool scrolldown(win_T *wp, linenr_T line_count, int byfold)
hasFolding(wp, wp->w_topline, &wp->w_topline, NULL); hasFolding(wp, wp->w_topline, &wp->w_topline, NULL);
validate_cursor(wp); // w_wrow needs to be valid validate_cursor(wp); // w_wrow needs to be valid
for (int todo = line_count; todo > 0; todo--) { for (int todo = line_count; todo > 0; todo--) {
if (wp->w_topfill < win_get_fill(wp, wp->w_topline) bool can_fill = wp->w_topfill < wp->w_height_inner - 1
&& wp->w_topfill < wp->w_height_inner - 1) { && wp->w_topfill < win_get_fill(wp, wp->w_topline);
// break when at the very top
if (wp->w_topline == 1 && !can_fill && (!do_sms || wp->w_skipcol < width1)) {
break;
}
if (do_sms && wp->w_skipcol >= width1) {
// scroll a screen line down
if (wp->w_skipcol >= width1 + width2) {
wp->w_skipcol -= width2;
} else {
wp->w_skipcol -= width1;
}
redraw_later(wp, UPD_NOT_VALID);
done++;
} else if (can_fill) {
wp->w_topfill++; wp->w_topfill++;
done++; done++;
} else { } else {
// break when at the very top // scroll a text line down
if (wp->w_topline == 1 && (!do_sms || wp->w_skipcol < width1)) { wp->w_topline--;
break; wp->w_skipcol = 0;
} wp->w_topfill = 0;
if (do_sms && wp->w_skipcol >= width1) { // A sequence of folded lines only counts for one logical line
// scroll a screen line down linenr_T first;
if (wp->w_skipcol >= width1 + width2) { if (hasFolding(wp, wp->w_topline, &first, NULL)) {
wp->w_skipcol -= width2; done += !decor_conceal_line(wp, first - 1, false);
} else { if (!byfold) {
wp->w_skipcol -= width1; todo -= wp->w_topline - first - 1;
} }
redraw_later(wp, UPD_NOT_VALID); wp->w_botline -= wp->w_topline - first;
done++; wp->w_topline = first;
} else if (decor_conceal_line(wp, wp->w_topline - 1, false)) {
todo++;
} else { } else {
// scroll a text line down if (do_sms) {
wp->w_topline--; int size = linetabsize_eol(wp, wp->w_topline);
wp->w_skipcol = 0; if (size > width1) {
wp->w_topfill = 0; wp->w_skipcol = width1;
// A sequence of folded lines only counts for one logical line size -= width1;
linenr_T first; redraw_later(wp, UPD_NOT_VALID);
if (hasFolding(wp, wp->w_topline, &first, NULL)) {
done += !decor_conceal_line(wp, first - 1, false);
if (!byfold) {
todo -= wp->w_topline - first - 1;
} }
wp->w_botline -= wp->w_topline - first; while (size > width2) {
wp->w_topline = first; wp->w_skipcol += width2;
} else if (decor_conceal_line(wp, wp->w_topline - 1, false)) { size -= width2;
todo++; }
done++;
} else { } else {
if (do_sms) { done += plines_win_nofill(wp, wp->w_topline, true);
int size = linetabsize_eol(wp, wp->w_topline);
if (size > width1) {
wp->w_skipcol = width1;
size -= width1;
redraw_later(wp, UPD_NOT_VALID);
}
while (size > width2) {
wp->w_skipcol += width2;
size -= width2;
}
done++;
} else {
done += plines_win_nofill(wp, wp->w_topline, true);
}
} }
} }
} }

View File

@@ -5951,6 +5951,33 @@ if (h->n_buckets < new_n_buckets) { // expand
]] ]]
}) })
end) end)
it("not revealed before skipcol scrolling up with 'smoothscroll'", function()
api.nvim_set_option_value('smoothscroll', true, {})
api.nvim_buf_set_lines(0, 0, -1, false, { ('x'):rep(screen._width * 2) })
api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_lines_above = true, virt_lines = { { { 'VIRT1' } } } } )
feed('<C-E>')
screen:expect([[
{1:<<<}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx^x|
{1:~ }|*10
|
]])
feed('<C-Y>')
screen:expect([[
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx^x|
{1:~ }|*9
|
]])
feed('<C-Y>')
screen:expect([[
VIRT1 |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx^x|
{1:~ }|*8
|
]])
end)
end) end)
describe('decorations: signs', function() describe('decorations: signs', function()