aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/marktree.c
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2024-02-15 19:05:01 +0100
committerbfredl <bjorn.linse@gmail.com>2024-02-17 18:22:35 +0100
commit2accf2480530c7df2120d8522103f5f1516268cf (patch)
treecd2a63aeaa043f48bd119ed8901c96a3e31f5052 /src/nvim/marktree.c
parent01c15a30c0ab56e14342f9996bea3ad86a68a343 (diff)
downloadrneovim-2accf2480530c7df2120d8522103f5f1516268cf.tar.gz
rneovim-2accf2480530c7df2120d8522103f5f1516268cf.tar.bz2
rneovim-2accf2480530c7df2120d8522103f5f1516268cf.zip
fix(decorations): crash with revised mark with changed decoration flags
fixes #27211
Diffstat (limited to 'src/nvim/marktree.c')
-rw-r--r--src/nvim/marktree.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c
index 9da7503524..1da75eb2af 100644
--- a/src/nvim/marktree.c
+++ b/src/nvim/marktree.c
@@ -774,6 +774,35 @@ uint64_t marktree_del_itr(MarkTree *b, MarkTreeIter *itr, bool rev)
return other;
}
+void marktree_revise_flags(MarkTree *b, MarkTreeIter *itr, uint16_t new_flags)
+{
+ uint32_t meta_old[4];
+ meta_describe_key(meta_old, rawkey(itr));
+ rawkey(itr).flags &= (uint16_t) ~MT_FLAG_EXTERNAL_MASK;
+ rawkey(itr).flags |= new_flags;
+
+ uint32_t meta_new[4];
+ meta_describe_key(meta_new, rawkey(itr));
+
+ if (!memcmp(meta_old, meta_new, sizeof(meta_old))) {
+ return;
+ }
+
+ MTNode *lnode = itr->x;
+ while (lnode->parent) {
+ uint32_t *meta_p = lnode->parent->meta[lnode->p_idx];
+ for (int m = 0; m < kMTMetaCount; m++) {
+ meta_p[m] += meta_new[m] - meta_old[m];
+ }
+
+ lnode = lnode->parent;
+ }
+
+ for (int m = 0; m < kMTMetaCount; m++) {
+ b->meta_root[m] += meta_new[m] - meta_old[m];
+ }
+}
+
/// similar to intersect_common but modify x and y in place to retain
/// only the items which are NOT in common
static void intersect_merge(Intersection *restrict m, Intersection *restrict x,