commit 8f1c161d9d11a79442b3496fb042c10d6b1ad9f6
parent 3a4a7a7efb2769d386d780aa79b1f625a0e83ce9
Author: bfredl <bjorn.linse@gmail.com>
Date: Thu, 26 Feb 2026 12:49:29 +0100
Merge pull request #38040 from bfredl/seenfix
fix(marktree): fix edge case bug regarding changing intersections
Diffstat:
2 files changed, 34 insertions(+), 9 deletions(-)
diff --git 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
@@ -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)