fix(decor): clamp last column by decor provider range

This commit is contained in:
vanaigr
2025-09-01 10:49:13 -05:00
committed by bfredl
parent 3449487a88
commit 20b2dd39cc
4 changed files with 24 additions and 19 deletions

View File

@@ -525,7 +525,7 @@ void decor_redraw_line(win_T *wp, int row, DecorState *state)
}
state->row = row;
state->col_until = -1;
state->col_last = -1;
state->eol_col = -1;
}
@@ -688,11 +688,12 @@ void decor_recheck_draw_col(int win_col, bool hidden, DecorState *state)
}
}
int decor_redraw_col_impl(win_T *wp, int col, int win_col, bool hidden, DecorState *state)
int decor_redraw_col_impl(win_T *wp, int col, int win_col, bool hidden, DecorState *state,
int max_col_last)
{
buf_T *const buf = wp->w_buffer;
int const row = state->row;
int col_until = MAXCOL;
int col_last = max_col_last;
while (true) {
// TODO(bfredl): check duplicate entry in "intersection"
@@ -701,7 +702,7 @@ int decor_redraw_col_impl(win_T *wp, int col, int win_col, bool hidden, DecorSta
if (mark.pos.row < 0 || mark.pos.row > row) {
break;
} else if (mark.pos.row == row && mark.pos.col > col) {
col_until = mark.pos.col - 1;
col_last = MIN(col_last, mark.pos.col - 1);
break;
}
@@ -757,7 +758,7 @@ next_mark:
if (fut_beg < count) {
DecorRange *r = &slots[indices[fut_beg]].range;
if (r->start_row == row) {
col_until = MIN(col_until, r->start_col - 1);
col_last = MIN(col_last, r->start_col - 1);
}
}
@@ -781,7 +782,7 @@ next_mark:
keep = true;
if (r->end_row == row && r->end_col > col) {
col_until = MIN(col_until, r->end_col - 1);
col_last = MIN(col_last, r->end_col - 1);
}
if (r->attr_id > 0) {
@@ -794,7 +795,7 @@ next_mark:
DecorSignHighlight *sh = &r->data.sh;
conceal = 2;
conceal_char = sh->text[0];
col_until = MIN(col_until, r->start_col);
col_last = MIN(col_last, r->start_col);
conceal_attr = r->attr_id;
}
}
@@ -842,7 +843,7 @@ next_mark:
kv_size(state->ranges_i) = (size_t)count;
state->future_begin = fut_beg;
state->current_end = cur_end;
state->col_until = col_until;
state->col_last = col_last;
state->current = attr;
state->conceal = conceal;
@@ -1096,7 +1097,7 @@ void decor_redraw_end(DecorState *state)
bool decor_redraw_eol(win_T *wp, DecorState *state, int *eol_attr, int eol_col)
{
decor_redraw_col(wp, MAXCOL, MAXCOL, false, state);
decor_redraw_col(wp, MAXCOL, MAXCOL, false, state, MAXCOL);
state->eol_col = eol_col;
int const count = state->current_end;

View File

@@ -85,7 +85,7 @@ typedef struct {
win_T *win;
int top_row;
int row;
int col_until;
int col_last;
int current;
int eol_col;
@@ -107,11 +107,12 @@ EXTERN kvec_t(DecorSignHighlight) decor_items INIT( = KV_INITIAL_VALUE);
#include "decoration.h.generated.h"
#include "decoration.h.inline.generated.h"
static inline int decor_redraw_col(win_T *wp, int col, int win_col, bool hidden, DecorState *state)
static inline int decor_redraw_col(win_T *wp, int col, int win_col, bool hidden, DecorState *state,
int max_col_last)
FUNC_ATTR_ALWAYS_INLINE
{
if (col <= state->col_until) {
if (col <= state->col_last) {
return state->current;
}
return decor_redraw_col_impl(wp, col, win_col, hidden, state);
return decor_redraw_col_impl(wp, col, win_col, hidden, state, max_col_last);
}

View File

@@ -1787,7 +1787,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
}
if (has_decor && wlv.row == startrow + wlv.filler_lines) {
// hide virt_text on text hidden by 'nowrap' or 'smoothscroll'
decor_redraw_col(wp, (colnr_T)(ptr - line) - 1, wlv.off, true, &decor_state);
decor_redraw_col(wp, (colnr_T)(ptr - line) - 1, wlv.off, true, &decor_state,
decor_provider_end_col - 1);
}
if (wlv.col >= view_width) {
wlv.col = wlv.off = view_width;
@@ -1856,7 +1857,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
}
extmark_attr = decor_redraw_col(wp, (colnr_T)(ptr - line),
may_have_inline_virt ? -3 : wlv.off,
selected, &decor_state);
selected, &decor_state, decor_provider_end_col - 1);
if (may_have_inline_virt) {
handle_inline_virtual_text(wp, &wlv, ptr - line, selected);
if (wlv.n_extra > 0 && wlv.virt_inline_hl_mode <= kHlModeReplace) {
@@ -2900,7 +2901,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
&& !has_foldtext) {
if (has_decor && *ptr == NUL && lcs_eol == 0 && lcs_eol_todo) {
// Tricky: there might be a virtual text just _after_ the last char
decor_redraw_col(wp, (colnr_T)(ptr - line), -1, false, &decor_state);
decor_redraw_col(wp, (colnr_T)(ptr - line), -1, false, &decor_state,
decor_provider_end_col - 1);
}
if (*ptr != NUL
|| (lcs_eol > 0 && lcs_eol_todo)
@@ -3088,14 +3090,15 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
// At the end of screen line: might need to peek for decorations just after
// this position.
if (is_wrapped && wlv.n_extra == 0) {
decor_redraw_col(wp, (colnr_T)(ptr - line), -3, false, &decor_state);
decor_redraw_col(wp, (colnr_T)(ptr - line), -3, false, &decor_state,
decor_provider_end_col - 1);
// Check position/hiding of virtual text again on next screen line.
decor_need_recheck = true;
} else if (!is_wrapped) {
// Without wrapping, we might need to display right_align and win_col
// virt_text for the entire text line.
decor_recheck_draw_col(-1, true, &decor_state);
decor_redraw_col(wp, MAXCOL, -1, true, &decor_state);
decor_redraw_col(wp, MAXCOL, -1, true, &decor_state, decor_provider_end_col - 1);
}
}

View File

@@ -1268,7 +1268,7 @@ static TriState decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_ln
decor_redraw_line(wp, lnum - 1, &decor_state);
*decor_lnum = lnum;
}
decor_redraw_col(wp, col, 0, false, &decor_state);
decor_redraw_col(wp, col, 0, false, &decor_state, MAXCOL);
return decor_state.spell;
}