diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index f76fcbaf4c..bd972862a6 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -1860,16 +1860,17 @@ bool marktree_itr_step_overlap(MarkTree *b, MarkTreeIter *itr, MTPair *pair) static void swap_keys(MarkTree *b, MarkTreeIter *itr1, MarkTreeIter *itr2, DamageList *damage) { - if (itr1->x != itr2->x) { - if (mt_paired(rawkey(itr1))) { - kvi_push(*damage, ((Damage){ mt_lookup_key(rawkey(itr1)), itr1->x, itr2->x, - itr1->i, itr2->i })); - } - if (mt_paired(rawkey(itr2))) { - kvi_push(*damage, ((Damage){ mt_lookup_key(rawkey(itr2)), itr2->x, itr1->x, - itr2->i, itr1->i })); - } + // TODO(bfredl): redactor is planned, see TODO comment next to qsort in marktree_splice + if (mt_paired(rawkey(itr1))) { + kvi_push(*damage, ((Damage){ mt_lookup_key(rawkey(itr1)), itr1->x, itr2->x, + itr1->i, itr2->i })); + } + if (mt_paired(rawkey(itr2))) { + kvi_push(*damage, ((Damage){ mt_lookup_key(rawkey(itr2)), itr2->x, itr1->x, + itr2->i, itr1->i })); + } + if (itr1->x != itr2->x) { uint32_t meta_inc_1[kMTMetaCount]; meta_describe_key(meta_inc_1, rawkey(itr1)); uint32_t meta_inc_2[kMTMetaCount]; diff --git a/test/unit/marktree_spec.lua b/test/unit/marktree_spec.lua index cac99cd4ab..37ac501b89 100644 --- a/test/unit/marktree_spec.lua +++ b/test/unit/marktree_spec.lua @@ -645,4 +645,28 @@ describe('marktree', function() until not lib.marktree_itr_next_filter(tree, iter, 101, 0, filter) eq(tablelength(seen), tablelength(shadow)) end) + + itp('works with edge case splicing overlapping ranges #37867', function() + local tree = ffi.new('MarkTree[1]') -- zero initialized by luajit + put(tree, 190, 48, false) + put(tree, 48, 48, true) + put(tree, 190, 48, false) + put(tree, 166, 48, false, 166, 48, false) + put(tree, 48, 48, true, 48, 48, false) + put(tree, 48, 48, true, 48, 48, false) + put(tree, 48, 48, true, 255, 48, false) + put(tree, 131, 48, false, 48, 48, false) + put(tree, 131, 48, false, 48, 48, false) + put(tree, 48, 48, true, 131, 48, false) + put(tree, 48, 48, false, 216, 48, false) + put(tree, 172, 48, false, 51, 48, false) + put(tree, 131, 48, false, 131, 48, false) + put(tree, 156, 48, false, 131, 48, false) + put(tree, 135, 48, false, 166, 48, false) + put(tree, 172, 48, false, 250, 48, false) + put(tree, 48, 48, false, 143, 48, false) + ok(lib.marktree_check_intersections(tree)) + lib.marktree_splice(tree, 48, 0, 139, 0, 0, 0) + ok(lib.marktree_check_intersections(tree)) + end) end)