diff options
Diffstat (limited to 'src/nvim/decoration.c')
-rw-r--r-- | src/nvim/decoration.c | 159 |
1 files changed, 80 insertions, 79 deletions
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index d9d1417d2a..265bc11661 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -158,7 +158,7 @@ Decoration *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id) MarkTreeIter itr[1] = { 0 }; marktree_itr_get(buf->b_marktree, row, 0, itr); while (true) { - mtkey_t mark = marktree_itr_current(itr); + MTKey mark = marktree_itr_current(itr); if (mark.pos.row < 0 || mark.pos.row > row) { break; } else if (marktree_decor_level(mark) < kDecorLevelVisible) { @@ -189,7 +189,7 @@ bool decor_redraw_reset(win_T *wp, DecorState *state) return wp->w_buffer->b_marktree->n_keys; } -Decoration get_decor(mtkey_t mark) +Decoration get_decor(MTKey mark) { if (mark.decor_full) { return *mark.decor_full; @@ -211,50 +211,20 @@ bool decor_redraw_start(win_T *wp, int top_row, DecorState *state) { buf_T *buf = wp->w_buffer; state->top_row = top_row; - marktree_itr_get(buf->b_marktree, top_row, 0, state->itr); - if (!state->itr->node) { + if (!marktree_itr_get_overlap(buf->b_marktree, top_row, 0, state->itr)) { return false; } - marktree_itr_rewind(buf->b_marktree, state->itr); - while (true) { - mtkey_t mark = marktree_itr_current(state->itr); - if (mark.pos.row < 0) { // || mark.row > end_row - break; - } - if ((mark.pos.row < top_row && mt_end(mark)) - || marktree_decor_level(mark) < kDecorLevelVisible) { - goto next_mark; - } + MTPair pair; - Decoration decor = get_decor(mark); - - mtpos_t altpos = marktree_get_altpos(buf->b_marktree, mark, NULL); - - // Exclude start marks if the end mark position is above the top row - // Exclude end marks if we have already added the start mark - if ((mt_start(mark) && altpos.row < top_row && !decor_virt_pos(&decor)) - || (mt_end(mark) && altpos.row >= top_row)) { - goto next_mark; + while (marktree_itr_step_overlap(buf->b_marktree, state->itr, &pair)) { + if (marktree_decor_level(pair.start) < kDecorLevelVisible) { + continue; } - if (mt_end(mark)) { - decor_add(state, altpos.row, altpos.col, mark.pos.row, mark.pos.col, - &decor, false, mark.ns, mark.id); - } else { - if (altpos.row == -1) { - altpos.row = mark.pos.row; - altpos.col = mark.pos.col; - } - decor_add(state, mark.pos.row, mark.pos.col, altpos.row, altpos.col, - &decor, false, mark.ns, mark.id); - } + Decoration decor = get_decor(pair.start); -next_mark: - if (marktree_itr_node_done(state->itr)) { - marktree_itr_next(buf->b_marktree, state->itr); - break; - } - marktree_itr_next(buf->b_marktree, state->itr); + decor_add(state, pair.start.pos.row, pair.start.pos.col, pair.end_pos.row, pair.end_pos.col, + &decor, false, pair.start.ns, pair.start.id); } return true; // TODO(bfredl): check if available in the region @@ -268,7 +238,13 @@ bool decor_redraw_line(win_T *wp, int row, DecorState *state) state->row = row; state->col_until = -1; state->eol_col = -1; - return true; // TODO(bfredl): be more precise + + if (kv_size(state->active)) { + return true; + } + + MTKey k = marktree_itr_current(state->itr); + return (k.pos.row >= 0 && k.pos.row <= row); } static void decor_add(DecorState *state, int start_row, int start_col, int end_row, int end_col, @@ -302,7 +278,7 @@ int decor_redraw_col(win_T *wp, int col, int win_col, bool hidden, DecorState *s while (true) { // TODO(bfredl): check duplicate entry in "intersection" // branch - mtkey_t mark = marktree_itr_current(state->itr); + MTKey mark = marktree_itr_current(state->itr); if (mark.pos.row < 0 || mark.pos.row > state->row) { break; } else if (mark.pos.row == state->row && mark.pos.col > col) { @@ -317,8 +293,7 @@ int decor_redraw_col(win_T *wp, int col, int win_col, bool hidden, DecorState *s Decoration decor = get_decor(mark); - mtpos_t endpos = marktree_get_altpos(buf->b_marktree, mark, NULL); - + MTPos endpos = marktree_get_altpos(buf->b_marktree, mark, NULL); if (endpos.row == -1) { endpos = mark.pos; } @@ -412,8 +387,28 @@ void decor_redraw_signs(buf_T *buf, int row, int *num_signs, SignTextAttrs sattr MarkTreeIter itr[1] = { 0 }; marktree_itr_get(buf->b_marktree, row, 0, itr); + // TODO(bfredl): integrate with main decor loop. + if (!marktree_itr_get_overlap(buf->b_marktree, row, 0, itr)) { + return; + } + + MTPair pair; + while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) { + if (marktree_decor_level(pair.start) < kDecorLevelVisible) { + continue; + } + + Decoration *decor = pair.start.decor_full; + + if (!decor || !decor_has_sign(decor)) { + continue; + } + + decor_to_sign(decor, num_signs, sattrs, num_id, line_id, cul_id); + } + while (true) { - mtkey_t mark = marktree_itr_current(itr); + MTKey mark = marktree_itr_current(itr); if (mark.pos.row < 0 || mark.pos.row > row) { break; } @@ -428,43 +423,49 @@ void decor_redraw_signs(buf_T *buf, int row, int *num_signs, SignTextAttrs sattr goto next_mark; } - if (decor->sign_text) { - int j; - for (j = (*num_signs); j > 0; j--) { - if (sattrs[j - 1].priority >= decor->priority) { - break; - } - if (j < SIGN_SHOW_MAX) { - sattrs[j] = sattrs[j - 1]; - } + decor_to_sign(decor, num_signs, sattrs, num_id, line_id, cul_id); + +next_mark: + marktree_itr_next(buf->b_marktree, itr); + } +} + +static void decor_to_sign(Decoration *decor, int *num_signs, SignTextAttrs sattrs[], + HlPriId *num_id, HlPriId *line_id, HlPriId *cul_id) +{ + if (decor->sign_text) { + int j; + for (j = (*num_signs); j > 0; j--) { + if (sattrs[j - 1].priority >= decor->priority) { + break; } if (j < SIGN_SHOW_MAX) { - sattrs[j] = (SignTextAttrs) { - .text = decor->sign_text, - .hl_id = decor->sign_hl_id, - .priority = decor->priority - }; - (*num_signs)++; + sattrs[j] = sattrs[j - 1]; } } - - struct { HlPriId *dest; int hl; } cattrs[] = { - { line_id, decor->line_hl_id }, - { num_id, decor->number_hl_id }, - { cul_id, decor->cursorline_hl_id }, - { NULL, -1 }, - }; - for (int i = 0; cattrs[i].dest; i++) { - if (cattrs[i].hl != 0 && decor->priority >= cattrs[i].dest->priority) { - *cattrs[i].dest = (HlPriId) { - .hl_id = cattrs[i].hl, - .priority = decor->priority - }; - } + if (j < SIGN_SHOW_MAX) { + sattrs[j] = (SignTextAttrs) { + .text = decor->sign_text, + .hl_id = decor->sign_hl_id, + .priority = decor->priority + }; + (*num_signs)++; } + } -next_mark: - marktree_itr_next(buf->b_marktree, itr); + struct { HlPriId *dest; int hl; } cattrs[] = { + { line_id, decor->line_hl_id }, + { num_id, decor->number_hl_id }, + { cul_id, decor->cursorline_hl_id }, + { NULL, -1 }, + }; + for (int i = 0; cattrs[i].dest; i++) { + if (cattrs[i].hl != 0 && decor->priority >= cattrs[i].dest->priority) { + *cattrs[i].dest = (HlPriId) { + .hl_id = cattrs[i].hl, + .priority = decor->priority + }; + } } } @@ -488,7 +489,7 @@ int decor_signcols(buf_T *buf, DecorState *state, int row, int end_row, int max) MarkTreeIter itr[1] = { 0 }; marktree_itr_get(buf->b_marktree, 0, -1, itr); while (true) { - mtkey_t mark = marktree_itr_current(itr); + MTKey mark = marktree_itr_current(itr); if (mark.pos.row < 0 || mark.pos.row > end_row) { break; } @@ -525,7 +526,7 @@ int decor_signcols(buf_T *buf, DecorState *state, int row, int end_row, int max) goto next_mark; } - mtpos_t altpos = marktree_get_altpos(buf->b_marktree, mark, NULL); + MTPos altpos = marktree_get_altpos(buf->b_marktree, mark, NULL); if (mt_end(mark)) { if (mark.pos.row >= row && altpos.row <= end_row) { @@ -610,7 +611,7 @@ int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines, TriState has_fo MarkTreeIter itr[1] = { 0 }; marktree_itr_get(buf->b_marktree, start_row, 0, itr); while (true) { - mtkey_t mark = marktree_itr_current(itr); + MTKey mark = marktree_itr_current(itr); if (mark.pos.row < 0 || mark.pos.row >= end_row) { break; } else if (mt_end(mark) |