From ce0c0c31a08975dd2e34207afb1a2cd544775bad Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Thu, 27 Mar 2025 12:51:57 +0100 Subject: fix(display): scroll logic does not take into account concealed topline (#33054) --- src/nvim/drawscreen.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 4c1b756ea1..2905d51657 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1700,6 +1700,16 @@ static void win_update(win_T *wp) } } + // Below logic compares wp->w_topline against wp->w_lines[0].wl_lnum, + // which may point to a line below wp->w_topline if it is concealed; + // incurring scrolling even though wp->w_topline is still the same. + // Compare against an adjusted topline instead: + linenr_T topline_conceal = wp->w_topline; + while (decor_conceal_line(wp, topline_conceal - 1, false)) { + topline_conceal++; + hasFolding(wp, topline_conceal, NULL, &topline_conceal); + } + // If there are no changes on the screen that require a complete redraw, // handle three cases: // 1: we are off the top of the screen by a few lines: scroll down @@ -1712,12 +1722,12 @@ static void win_update(win_T *wp) if (mod_top != 0 && wp->w_topline == mod_top && (!wp->w_lines[0].wl_valid - || wp->w_topline == wp->w_lines[0].wl_lnum)) { + || topline_conceal == wp->w_lines[0].wl_lnum)) { // w_topline is the first changed line and window is not scrolled, // the scrolling from changed lines will be done further down. } else if (wp->w_lines[0].wl_valid - && (wp->w_topline < wp->w_lines[0].wl_lnum - || (wp->w_topline == wp->w_lines[0].wl_lnum + && (topline_conceal < wp->w_lines[0].wl_lnum + || (topline_conceal == wp->w_lines[0].wl_lnum && wp->w_topfill > wp->w_old_topfill))) { // New topline is above old topline: May scroll down. int j; -- cgit