pub struct Brackets { /* private fields */ }Expand description
Every bracket in a document, riding one augmented SumTree that is the sole
owner of position. Queries are O(log) descents; an edit is a
SumTree::replace of the edited byte range.
Default is an EMPTY tree — valid both for the read-only query surface
(movement’s fold-free helper pairs it with an empty FoldSet) and as a base
for Brackets::apply_edit, since the tree needs no scaffold to seed: the
first edit simply replaces an empty range.
Implementations§
Source§impl Brackets
impl Brackets
Sourcepub fn match_text(text: &str) -> Self
pub fn match_text(text: &str) -> Self
Match every ()/[]/{} bracket in text (LF-only — the buffer
contract) — the O(n) from-scratch constructor (document load; the tests’
oracle). Per-edit maintenance goes through Brackets::apply_edit.
Sourcepub fn match_text_with(text: &str, cfg: &BracketConfig) -> Self
pub fn match_text_with(text: &str, cfg: &BracketConfig) -> Self
Self::match_text, but skipping brackets inside comments / strings / char
literals per cfg. An inactive (Default) config takes the exact
zero-overhead structural path — the two are byte-identical then.
Sourcepub fn all(&self) -> Vec<Bracket>
pub fn all(&self) -> Vec<Bracket>
All brackets, in document order — the O(n) cold path (fold-source scans, the
capture-folds harness, tests). Hot paths use Self::in_range.
Sourcepub fn at(&self, offset: u32) -> Option<Bracket>
pub fn at(&self, offset: u32) -> Option<Bracket>
The bracket at exactly offset, if any. O(log).
Sourcepub fn foldable_partner(&self, offset: u32) -> Option<u32>
pub fn foldable_partner(&self, offset: u32) -> Option<u32>
The matched partner of the OPEN bracket at offset, or None if it is not a
live opener or is unmatched — the fold hot-path lookup (fold reconcile,
expand-on-hidden-edit, block/inline resolution). Unlike Self::at it never
resolves depth, so it costs O(log + partner fold) with no ShapeSummary
allocation — the difference between a fold-heavy keystroke being O(folds·log)
and an allocation storm. Callers that only need “is this opener’s pair still
there, and where does it close?” must use this, never at().partner.
Sourcepub fn in_range(&self, range: Range<u32>) -> Vec<Bracket>
pub fn in_range(&self, range: Range<u32>) -> Vec<Bracket>
The brackets whose offset lies in range (half-open: start inclusive, end
exclusive), in order, collected — the cold/slice callers (fold-pair
derivation, tests). An inverted range is empty, not a panic. Per-frame hot
paths iterate Self::in_range_iter instead, which allocates nothing.
Sourcepub fn in_range_iter(
&self,
range: Range<u32>,
) -> impl Iterator<Item = Bracket> + '_
pub fn in_range_iter( &self, range: Range<u32>, ) -> impl Iterator<Item = Bracket> + '_
Self::in_range as a lazy iterator — the per-visible-row colorization
loop iterates this directly, so a frame’s bracket colouring allocates no
Vec (one per visible row × every frame otherwise). An inverted range
yields nothing (the count bounds cross), matching Self::in_range.
Sourcepub fn active_pair(&self, caret: u32) -> Option<(u32, u32)>
pub fn active_pair(&self, caret: u32) -> Option<(u32, u32)>
The matched bracket pair to highlight for a caret at caret, as
(bracket_offset, partner_offset). The bracket directly left of the
caret is preferred (the one you just typed past); the one directly right
is the fallback. None if the caret isn’t adjacent to a matched bracket.
Sourcepub fn enclosing_pair(&self, caret: u32) -> Option<(u32, u32)>
pub fn enclosing_pair(&self, caret: u32) -> Option<(u32, u32)>
The innermost matched pair whose interior contains caret (opener offset
< caret <= closer offset), as (open_offset, close_offset) — the active
indent guide. None if the caret is inside no matched pair.
Sourcepub fn innermost_enclosing_where(
&self,
caret: u32,
pred: impl Fn(u32, u32) -> bool,
) -> Option<u32>
pub fn innermost_enclosing_where( &self, caret: u32, pred: impl Fn(u32, u32) -> bool, ) -> Option<u32>
The opener of the innermost pair strictly enclosing caret
(open < caret <= close) that satisfies pred. None if none matches.
Sourcepub fn enclosing_pair_of_range(
&self,
start: u32,
end: u32,
) -> Option<(u32, u32)>
pub fn enclosing_pair_of_range( &self, start: u32, end: u32, ) -> Option<(u32, u32)>
The innermost matched pair whose CONTENTS contain the whole range —
open + 1 <= start && end <= close — as (open, close). The
expand-selection ladder’s next rung. None outside every pair.
Sourcepub fn enclosing_or_touching(&self, caret: u32) -> Vec<(u32, u32)>
pub fn enclosing_or_touching(&self, caret: u32) -> Vec<(u32, u32)>
Every matched pair (open, close) with open <= caret <= close + 1 —
the pairs enclosing the caret PLUS the ones it touches at either bracket
(caret AT an opener, or just past a closer) — the fold-at-caret candidate
set. Unordered; the caller picks the innermost.
Sourcepub fn apply_edit(
&mut self,
patch: &Patch,
buffer: &Buffer,
cfg: &BracketConfig,
) -> Range<u32>
pub fn apply_edit( &mut self, patch: &Patch, buffer: &Buffer, cfg: &BracketConfig, ) -> Range<u32>
Splice this structure through one committed patch — the incremental twin
of Brackets::match_text. buffer is the POST-edit buffer and patch
the committed transaction’s old→new byte ranges (new in final
coordinates) — exactly what rebase_views holds, on the forward path and on
every undo/redo step alike.
Returns the reconcile window [seed_lo, re) in post-edit coordinates: the
re-matched span extended left to the outermost opener enclosing the first
edit (so a fold whose partner the edit deletes is covered), or 0..0 when
no bracket structure changed. Document::reconcile_folds re-checks only the
folds in that window.
§Why the result deep-equals a from-scratch rebuild
The tree stores only each bracket’s char and delta-gap position; open,
depth, and partner are DERIVED per query from the always-current tree.
So an edit need only make the stored primary facts correct: rescan the
edited byte range into brackets, SumTree::replace them in, and — because
the encoding is delta-gap — re-anchor just the FIRST suffix bracket’s gap
(the rest are relative and do not move). No cross-boundary partner pointer
is stored, so none can be left stale by the splice; the
incremental≡match_text oracle enforces the equivalence.