mirror of
https://github.com/neovim/neovim.git
synced 2025-10-15 06:16:08 +00:00
refactor(decorations): mark decorations directly on the marktree
This allows to more quickly skip though regions which has non-decorative marks when redrawing. This might seem like a gratuitous micro-optimization in isolation. But! Soon decorations are gonna crop into other hot inner-loop paths, including the plines.c code for calculating the horizontal and vertical space of text. Then we want to quickly skip over regions with "only" overlaying decorations (which do not affect text size)
This commit is contained in:
@@ -118,6 +118,8 @@ Decoration *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
|
||||
mtmark_t mark = marktree_itr_current(itr);
|
||||
if (mark.row < 0 || mark.row > row) {
|
||||
break;
|
||||
} else if (mt_decor_level(mark.id) < 1) {
|
||||
goto next_mark;
|
||||
}
|
||||
ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index,
|
||||
mark.id, false);
|
||||
@@ -125,6 +127,7 @@ Decoration *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
|
||||
&& item->decor && kv_size(item->decor->virt_text)) {
|
||||
return item->decor;
|
||||
}
|
||||
next_mark:
|
||||
marktree_itr_next(buf->b_marktree, itr);
|
||||
}
|
||||
return NULL;
|
||||
@@ -158,21 +161,22 @@ bool decor_redraw_start(buf_T *buf, int top_row, DecorState *state)
|
||||
if (mark.row < 0) { // || mark.row > end_row
|
||||
break;
|
||||
}
|
||||
if ((mark.row < top_row && mark.id&MARKTREE_END_FLAG)) {
|
||||
if ((mark.row < top_row && mark.id&MARKTREE_END_FLAG)
|
||||
|| mt_decor_level(mark.id) < 1) {
|
||||
goto next_mark;
|
||||
}
|
||||
mtpos_t altpos = marktree_lookup(buf->b_marktree,
|
||||
mark.id^MARKTREE_END_FLAG, NULL);
|
||||
|
||||
uint64_t start_id = mark.id & ~MARKTREE_END_FLAG;
|
||||
ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index,
|
||||
start_id, false);
|
||||
if (!item || !item->decor) {
|
||||
// TODO(bfredl): dedicated flag for being a decoration?
|
||||
goto next_mark;
|
||||
}
|
||||
Decoration *decor = item->decor;
|
||||
|
||||
mtpos_t altpos = marktree_lookup(buf->b_marktree,
|
||||
mark.id^MARKTREE_END_FLAG, NULL);
|
||||
|
||||
if ((!(mark.id&MARKTREE_END_FLAG) && altpos.row < top_row
|
||||
&& !kv_size(decor->virt_text))
|
||||
|| ((mark.id&MARKTREE_END_FLAG) && altpos.row >= top_row)) {
|
||||
@@ -251,21 +255,20 @@ int decor_redraw_col(buf_T *buf, int col, int win_col, bool hidden, DecorState *
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mark.id&MARKTREE_END_FLAG)) {
|
||||
// TODO(bfredl): check decoration flag
|
||||
if ((mark.id&MARKTREE_END_FLAG) || mt_decor_level(mark.id) < 1) {
|
||||
goto next_mark;
|
||||
}
|
||||
mtpos_t endpos = marktree_lookup(buf->b_marktree,
|
||||
mark.id|MARKTREE_END_FLAG, NULL);
|
||||
|
||||
ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index,
|
||||
mark.id, false);
|
||||
if (!item || !item->decor) {
|
||||
// TODO(bfredl): dedicated flag for being a decoration?
|
||||
goto next_mark;
|
||||
}
|
||||
Decoration *decor = item->decor;
|
||||
|
||||
mtpos_t endpos = marktree_lookup(buf->b_marktree,
|
||||
mark.id|MARKTREE_END_FLAG, NULL);
|
||||
|
||||
if (endpos.row == -1) {
|
||||
endpos.row = mark.row;
|
||||
endpos.col = mark.col;
|
||||
|
Reference in New Issue
Block a user