neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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:
Msrc/nvim/marktree.c | 19++++++++++---------
Mtest/unit/marktree_spec.lua | 24++++++++++++++++++++++++
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)