From fd8e0ae62d42df766147b18a711c30e6b3dd0ce4 Mon Sep 17 00:00:00 2001 From: Artem Date: Fri, 9 May 2025 05:37:43 -0500 Subject: [PATCH] fix(decor): extmark highlight not applied (#33858) Problem: If the only highlight present in the buffer is an extmark, and its end position is outside the screen, redraws that start on lines after the first line of the mark will consider the buffer as not having any highlights, and skip drawing the mark's highlight. Solution: Check the updated number of decor ranges. (cherry picked from commit 6adf48b66d52ba82b71af59383ef09ee9ad7e20e) --- src/nvim/decoration.c | 9 +++++++-- test/functional/ui/decorations_spec.lua | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 07f2bfb676..8dbdb7eddc 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -493,7 +493,7 @@ bool decor_redraw_start(win_T *wp, int top_row, DecorState *state) return true; // TODO(bfredl): check if available in the region } -bool decor_redraw_line(win_T *wp, int row, DecorState *state) +static void decor_state_pack(DecorState *state) { int count = (int)kv_size(state->ranges_i); int const cur_end = state->current_end; @@ -513,6 +513,11 @@ bool decor_redraw_line(win_T *wp, int row, DecorState *state) kv_size(state->ranges_i) = (size_t)count; state->future_begin = fut_beg; +} + +bool decor_redraw_line(win_T *wp, int row, DecorState *state) +{ + decor_state_pack(state); if (state->row == -1) { decor_redraw_start(wp, row, state); @@ -525,7 +530,7 @@ bool decor_redraw_line(win_T *wp, int row, DecorState *state) state->col_until = -1; state->eol_col = -1; - if (cur_end != 0 || fut_beg != count) { + if (state->current_end != 0 || state->future_begin != (int)kv_size(state->ranges_i)) { return true; } diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index f222f115f3..e794334919 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -3066,6 +3066,28 @@ describe('extmark decorations', function() | ]]) end) + + it('redraws extmark that starts and ends outisde the screen', function() + local lines = vim.split(('1'):rep(20), '', { plain = true }) + api.nvim_buf_set_lines(0, 0, -1, true, lines) + api.nvim_buf_set_extmark(0, ns, 0, 0, { hl_group = 'ErrorMsg', end_row = 19, end_col = 0 }) + screen:expect({ + grid = [[ + {4:^1} | + {4:1} |*13 + | + ]] + }) + feed('') + -- Newly visible line should also have the highlight. + screen:expect({ + grid = [[ + {4:^1} | + {4:1} |*13 + | + ]] + }) + end) end) describe('decorations: inline virtual text', function()