aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/decoration.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/decoration.c')
-rw-r--r--src/nvim/decoration.c90
1 files changed, 29 insertions, 61 deletions
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 5224a07fd9..d3517c077f 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -8,6 +8,7 @@
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/ascii_defs.h"
+#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
#include "nvim/decoration.h"
#include "nvim/drawscreen.h"
@@ -170,12 +171,6 @@ DecorSignHighlight decor_sh_from_inline(DecorHighlightInline item)
void buf_put_decor(buf_T *buf, DecorInline decor, int row, int row2)
{
if (decor.ext) {
- DecorVirtText *vt = decor.data.ext.vt;
- while (vt) {
- buf_put_decor_virt(buf, vt);
- vt = vt->next;
- }
-
uint32_t idx = decor.data.ext.sh_idx;
while (idx != DECOR_ID_INVALID) {
DecorSignHighlight *sh = &kv_A(decor_items, idx);
@@ -185,28 +180,12 @@ void buf_put_decor(buf_T *buf, DecorInline decor, int row, int row2)
}
}
-void buf_put_decor_virt(buf_T *buf, DecorVirtText *vt)
-{
- if (vt->flags &kVTIsLines) {
- buf->b_virt_line_blocks++;
- } else {
- if (vt->pos == kVPosInline) {
- buf->b_virt_text_inline++;
- }
- }
- if (vt->next) {
- buf_put_decor_virt(buf, vt->next);
- }
-}
-
static int sign_add_id = 0;
void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row1, int row2)
{
if (sh->flags & kSHIsSign) {
sh->sign_add_id = sign_add_id++;
- buf->b_signs++;
if (sh->text[0]) {
- buf->b_signs_with_text++;
buf_signcols_count_range(buf, row1, row2, 1, kFalse);
}
}
@@ -216,11 +195,6 @@ void buf_decor_remove(buf_T *buf, int row1, int row2, DecorInline decor, bool fr
{
decor_redraw(buf, row1, row2, decor);
if (decor.ext) {
- DecorVirtText *vt = decor.data.ext.vt;
- while (vt) {
- buf_remove_decor_virt(buf, vt);
- vt = vt->next;
- }
uint32_t idx = decor.data.ext.sh_idx;
while (idx != DECOR_ID_INVALID) {
DecorSignHighlight *sh = &kv_A(decor_items, idx);
@@ -233,28 +207,11 @@ void buf_decor_remove(buf_T *buf, int row1, int row2, DecorInline decor, bool fr
}
}
-void buf_remove_decor_virt(buf_T *buf, DecorVirtText *vt)
-{
- if (vt->flags &kVTIsLines) {
- assert(buf->b_virt_line_blocks > 0);
- buf->b_virt_line_blocks--;
- } else {
- if (vt->pos == kVPosInline) {
- assert(buf->b_virt_text_inline > 0);
- buf->b_virt_text_inline--;
- }
- }
-}
-
void buf_remove_decor_sh(buf_T *buf, int row1, int row2, DecorSignHighlight *sh)
{
if (sh->flags & kSHIsSign) {
- assert(buf->b_signs > 0);
- buf->b_signs--;
if (sh->text[0]) {
- assert(buf->b_signs_with_text > 0);
- buf->b_signs_with_text--;
- if (buf->b_signs_with_text) {
+ if (buf_meta_total(buf, kMTMetaSignText)) {
buf_signcols_count_range(buf, row1, row2, -1, kFalse);
} else {
buf->b_signcols.resized = true;
@@ -395,10 +352,10 @@ DecorVirtText *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
MTKey mark = marktree_itr_current(itr);
if (mark.pos.row < 0 || mark.pos.row > row) {
break;
- } else if (mt_invalid(mark) || !(mark.flags & MT_FLAG_DECOR_EXT)) {
+ } else if (mt_invalid(mark)) {
goto next_mark;
}
- DecorVirtText *decor = mark.decor_data.ext.vt;
+ DecorVirtText *decor = mt_decor_virt(mark);
while (decor && (decor->flags & kVTIsLines)) {
decor = decor->next;
}
@@ -705,6 +662,9 @@ int sign_item_cmp(const void *p1, const void *p2)
? n : (s2->sh->sign_add_id - s1->sh->sign_add_id);
}
+const uint32_t sign_filter[4] = {[kMTMetaSignText] = kMTFilterSelect,
+ [kMTMetaSignHL] = kMTFilterSelect };
+
/// Return the sign attributes on the currently refreshed row.
///
/// @param[out] sattrs Output array for sign text and texthl id
@@ -731,6 +691,8 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
}
}
+ marktree_itr_step_out_filter(buf->b_marktree, itr, sign_filter);
+
while (itr->x) {
MTKey mark = marktree_itr_current(itr);
if (mark.pos.row != row) {
@@ -742,7 +704,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
kv_push(signs, ((SignItem){ sh, mark.id }));
}
- marktree_itr_next(buf->b_marktree, itr);
+ marktree_itr_next_filter(buf->b_marktree, itr, row + 1, 0, sign_filter);
}
if (kv_size(signs)) {
@@ -788,6 +750,8 @@ DecorSignHighlight *decor_find_sign(DecorInline decor)
}
}
+const uint32_t signtext_filter[4] = {[kMTMetaSignText] = kMTFilterSelect };
+
/// Count the number of signs in a range after adding/removing a sign, or to
/// (re-)initialize a range in "b_signcols.count".
///
@@ -795,7 +759,7 @@ DecorSignHighlight *decor_find_sign(DecorInline decor)
/// @param clear kFalse, kTrue or kNone for an, added/deleted, cleared, or initialized range.
void buf_signcols_count_range(buf_T *buf, int row1, int row2, int add, TriState clear)
{
- if (!buf->b_signcols.autom || !buf->b_signs_with_text) {
+ if (!buf->b_signcols.autom || !buf_meta_total(buf, kMTMetaSignText)) {
return;
}
@@ -821,6 +785,8 @@ void buf_signcols_count_range(buf_T *buf, int row1, int row2, int add, TriState
}
}
+ marktree_itr_step_out_filter(buf->b_marktree, itr, signtext_filter);
+
// Continue traversing the marktree until beyond "row2".
while (itr->x) {
MTKey mark = marktree_itr_current(itr);
@@ -835,7 +801,7 @@ void buf_signcols_count_range(buf_T *buf, int row1, int row2, int add, TriState
}
}
- marktree_itr_next(buf->b_marktree, itr);
+ marktree_itr_next_filter(buf->b_marktree, itr, row2 + 1, 0, signtext_filter);
}
// For each row increment "b_signcols.count" at the number of counted signs,
@@ -884,11 +850,13 @@ bool decor_redraw_eol(win_T *wp, DecorState *state, int *eol_attr, int eol_col)
return has_virt_pos;
}
+uint32_t lines_filter[4] = {[kMTMetaLines] = kMTFilterSelect };
+
/// @param has_fold whether line "lnum" has a fold, or kNone when not calculated yet
int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines, TriState has_fold)
{
buf_T *buf = wp->w_buffer;
- if (!buf->b_virt_line_blocks) {
+ if (!buf_meta_total(buf, kMTMetaLines)) {
// Only pay for what you use: in case virt_lines feature is not active
// in a buffer, plines do not need to access the marktree at all
return 0;
@@ -907,17 +875,15 @@ int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines, TriState has_fo
return 0;
}
- int virt_lines = 0;
MarkTreeIter itr[1] = { 0 };
- marktree_itr_get(buf->b_marktree, start_row, 0, itr);
+ if (!marktree_itr_get_filter(buf->b_marktree, start_row, 0, end_row, 0, lines_filter, itr)) {
+ return 0;
+ }
+
+ int virt_lines = 0;
while (true) {
MTKey mark = marktree_itr_current(itr);
- if (mark.pos.row < 0 || mark.pos.row >= end_row) {
- break;
- } else if (mt_end(mark) || !(mark.flags & MT_FLAG_DECOR_VIRT_LINES)) {
- goto next_mark;
- }
- DecorVirtText *vt = mark.decor_data.ext.vt;
+ DecorVirtText *vt = mt_decor_virt(mark);
while (vt) {
if (vt->flags & kVTIsLines) {
bool above = vt->flags & kVTLinesAbove;
@@ -931,8 +897,10 @@ int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines, TriState has_fo
}
vt = vt->next;
}
-next_mark:
- marktree_itr_next(buf->b_marktree, itr);
+
+ if (!marktree_itr_next_filter(buf->b_marktree, itr, end_row, 0, lines_filter)) {
+ break;
+ }
}
return virt_lines;