diff options
-rw-r--r-- | src/nvim/drawscreen.c | 16 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 22 |
2 files changed, 35 insertions, 3 deletions
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; diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 639d43b560..5ef1ef54bb 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -2956,6 +2956,28 @@ describe('extmark decorations', function() {1:~ }|*3 | ]]) + -- No scrolling for concealed topline #33033 + api.nvim_buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_lines_above = true, virt_lines = { { { "virt_above 2" } } } }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { conceal_lines = "" }) + feed('ggjj') + screen:expect([[ + {2: }virt_above 2 | + {2: 2 } local text, hl_id_cell, count = unpack(ite| + {2: }m) | + {2: 3 }^ if hl_id_cell ~= nil then | + {2: 4 } hl_id = hl_id_cell | + {2: 5 }conceal text | + {2: 6 } for _ = 1, (count or 1) do | + {2: 7 } local cell = line[colpos] | + {2: 8 } cell.text = text | + {2: 9 } cell.hl_id = hl_id | + {2: 10 } colpos = colpos+1 | + {2: 11 } end | + {2: 12 }end | + {1:~ }| + | + ]]) end) end) |