aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/drawscreen.c16
-rw-r--r--test/functional/ui/decorations_spec.lua22
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)