diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 5030c337aa..eda711e074 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -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; diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index 08586eb238..6ce7357d0f 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -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); } diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 97a741a57d..f87f7ab2fa 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -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); } } diff --git a/src/nvim/spell.c b/src/nvim/spell.c index cb3d9a8638..a5ac2d46dd 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -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; }