Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T02:52:59.362Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

syntax_map.rs

2221 lines · 77.6 KB · rust
1#[cfg(test)]
2mod syntax_map_tests;
3
4use crate::{
5    Grammar, InjectionConfig, Language, LanguageId, LanguageRegistry, QUERY_CURSORS, with_parser,
6};
7use collections::HashMap;
8use futures::FutureExt;
9use gpui::SharedString;
10use std::{
11    borrow::Cow,
12    cmp::{self, Ordering, Reverse},
13    collections::BinaryHeap,
14    fmt, iter,
15    ops::{ControlFlow, Deref, DerefMut, Range},
16    sync::{Arc, LazyLock},
17    time::{Duration, Instant},
18};
19use streaming_iterator::StreamingIterator;
20use sum_tree::{Bias, Dimensions, SeekTarget, SumTree};
21use text::{Anchor, BufferId, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint};
22use tree_sitter::{
23    Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatch, QueryMatches,
24    QueryPredicateArg,
25};
26
27pub const MAX_BYTES_TO_QUERY: usize = 16 * 1024;
28
29pub struct SyntaxMap {
30    snapshot: SyntaxSnapshot,
31    language_registry: Option<Arc<LanguageRegistry>>,
32}
33
34#[derive(Clone)]
35pub struct SyntaxSnapshot {
36    layers: SumTree<SyntaxLayerEntry>,
37    parsed_version: clock::Global,
38    interpolated_version: clock::Global,
39    language_registry_version: usize,
40    update_count: usize,
41}
42
43// Dropping deep treesitter Trees can be quite slow due to deallocating lots of memory.
44// To avoid blocking the main thread, we offload the drop operation to a background thread.
45impl Drop for SyntaxSnapshot {
46    fn drop(&mut self) {
47        static DROP_TX: LazyLock<std::sync::mpsc::Sender<SumTree<SyntaxLayerEntry>>> =
48            LazyLock::new(|| {
49                let (tx, rx) = std::sync::mpsc::channel();
50                std::thread::Builder::new()
51                    .name("SyntaxSnapshot::drop".into())
52                    .spawn(move || while let Ok(_) = rx.recv() {})
53                    .expect("failed to spawn drop thread");
54                tx
55            });
56        // This does allocate a new Arc, but it's cheap and avoids blocking the main thread without needing to use an `Option` or `MaybeUninit`.
57        let _ = DROP_TX.send(std::mem::replace(
58            &mut self.layers,
59            SumTree::from_summary(SyntaxLayerSummary {
60                min_depth: Default::default(),
61                max_depth: Default::default(),
62                // Deliberately bogus anchors, doesn't matter in this context
63                range: Anchor::min_min_range_for_buffer(BufferId::new(1).unwrap()),
64                last_layer_range: Anchor::min_min_range_for_buffer(BufferId::new(1).unwrap()),
65                last_layer_language: Default::default(),
66                contains_unknown_injections: Default::default(),
67            }),
68        ));
69    }
70}
71
72#[derive(Default)]
73pub struct SyntaxMapCaptures<'a> {
74    layers: Vec<SyntaxMapCapturesLayer<'a>>,
75    active_layer_count: usize,
76    grammars: Vec<&'a Grammar>,
77}
78
79#[derive(Default)]
80pub struct SyntaxMapMatches<'a> {
81    layers: Vec<SyntaxMapMatchesLayer<'a>>,
82    active_layer_count: usize,
83    grammars: Vec<&'a Grammar>,
84}
85
86#[derive(Debug)]
87pub struct SyntaxMapCapture<'a> {
88    pub node: Node<'a>,
89    pub index: u32,
90    pub grammar_index: usize,
91}
92
93#[derive(Debug)]
94pub struct SyntaxMapMatch<'a> {
95    pub language: Arc<Language>,
96    pub depth: usize,
97    pub pattern_index: usize,
98    pub captures: &'a [QueryCapture<'a>],
99    pub grammar_index: usize,
100}
101
102struct SyntaxMapCapturesLayer<'a> {
103    depth: usize,
104    captures: QueryCaptures<'a, 'a, TextProvider<'a>, &'a [u8]>,
105    next_capture: Option<QueryCapture<'a>>,
106    grammar_index: usize,
107    _query_cursor: QueryCursorHandle,
108}
109
110struct SyntaxMapMatchesLayer<'a> {
111    language: Arc<Language>,
112    depth: usize,
113    next_pattern_index: usize,
114    next_captures: Vec<QueryCapture<'a>>,
115    has_next: bool,
116    matches: QueryMatches<'a, 'a, TextProvider<'a>, &'a [u8]>,
117    query: &'a Query,
118    grammar_index: usize,
119    _query_cursor: QueryCursorHandle,
120}
121
122#[derive(Clone)]
123struct SyntaxLayerEntry {
124    depth: usize,
125    range: Range<Anchor>,
126    content: SyntaxLayerContent,
127}
128
129#[derive(Clone)]
130enum SyntaxLayerContent {
131    Parsed {
132        tree: tree_sitter::Tree,
133        language: Arc<Language>,
134        included_sub_ranges: Option<Vec<Range<Anchor>>>,
135    },
136    Pending {
137        language_name: Arc<str>,
138    },
139}
140
141impl SyntaxLayerContent {
142    fn language_id(&self) -> Option<LanguageId> {
143        match self {
144            SyntaxLayerContent::Parsed { language, .. } => Some(language.id),
145            SyntaxLayerContent::Pending { .. } => None,
146        }
147    }
148
149    fn tree(&self) -> Option<&tree_sitter::Tree> {
150        match self {
151            SyntaxLayerContent::Parsed { tree, .. } => Some(tree),
152            SyntaxLayerContent::Pending { .. } => None,
153        }
154    }
155}
156
157/// A layer of syntax highlighting, corresponding to a single syntax
158/// tree in a particular language.
159#[derive(Debug)]
160pub struct SyntaxLayer<'a> {
161    /// The language for this layer.
162    pub language: &'a Arc<Language>,
163    pub included_sub_ranges: Option<&'a [Range<Anchor>]>,
164    pub(crate) depth: usize,
165    tree: &'a tree_sitter::Tree,
166    pub(crate) offset: (usize, tree_sitter::Point),
167}
168
169/// A layer of syntax highlighting. Like [SyntaxLayer], but holding
170/// owned data instead of references.
171#[derive(Clone)]
172pub struct OwnedSyntaxLayer {
173    /// The language for this layer.
174    pub language: Arc<Language>,
175    tree: tree_sitter::Tree,
176    pub offset: (usize, tree_sitter::Point),
177}
178
179#[derive(Debug, Clone)]
180struct SyntaxLayerSummary {
181    min_depth: usize,
182    max_depth: usize,
183    range: Range<Anchor>,
184    last_layer_range: Range<Anchor>,
185    last_layer_language: Option<LanguageId>,
186    contains_unknown_injections: bool,
187}
188
189#[derive(Clone, Debug)]
190struct SyntaxLayerPosition {
191    depth: usize,
192    range: Range<Anchor>,
193    language: Option<LanguageId>,
194}
195
196#[derive(Clone, Debug)]
197struct ChangeStartPosition {
198    depth: usize,
199    position: Anchor,
200}
201
202#[derive(Clone, Debug)]
203struct SyntaxLayerPositionBeforeChange {
204    position: SyntaxLayerPosition,
205    change: ChangeStartPosition,
206}
207
208struct ParseStep {
209    depth: usize,
210    language: ParseStepLanguage,
211    range: Range<Anchor>,
212    included_ranges: Vec<tree_sitter::Range>,
213    mode: ParseMode,
214}
215
216#[derive(Debug)]
217enum ParseStepLanguage {
218    Loaded { language: Arc<Language> },
219    Pending { name: Arc<str> },
220}
221
222impl ParseStepLanguage {
223    fn name(&self) -> SharedString {
224        match self {
225            ParseStepLanguage::Loaded { language } => language.name().0,
226            ParseStepLanguage::Pending { name } => name.clone().into(),
227        }
228    }
229
230    fn id(&self) -> Option<LanguageId> {
231        match self {
232            ParseStepLanguage::Loaded { language } => Some(language.id),
233            ParseStepLanguage::Pending { .. } => None,
234        }
235    }
236}
237
238enum ParseMode {
239    Single,
240    Combined {
241        parent_layer_range: Range<usize>,
242        parent_layer_changed_ranges: Vec<Range<usize>>,
243    },
244}
245
246#[derive(Debug, PartialEq, Eq)]
247struct ChangedRegion {
248    depth: usize,
249    range: Range<Anchor>,
250}
251
252#[derive(Default)]
253struct ChangeRegionSet(Vec<ChangedRegion>);
254
255struct TextProvider<'a>(&'a Rope);
256
257struct ByteChunks<'a>(text::Chunks<'a>);
258
259pub(crate) struct QueryCursorHandle(Option<QueryCursor>);
260
261impl SyntaxMap {
262    pub fn new(text: &BufferSnapshot) -> Self {
263        Self {
264            snapshot: SyntaxSnapshot::new(text),
265            language_registry: None,
266        }
267    }
268
269    pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) {
270        self.language_registry = Some(registry);
271    }
272
273    pub fn snapshot(&self) -> SyntaxSnapshot {
274        self.snapshot.clone()
275    }
276
277    pub fn language_registry(&self) -> Option<Arc<LanguageRegistry>> {
278        self.language_registry.clone()
279    }
280
281    pub fn interpolate(&mut self, text: &BufferSnapshot) {
282        self.snapshot.interpolate(text);
283    }
284
285    #[cfg(test)]
286    pub fn reparse(&mut self, language: Arc<Language>, text: &BufferSnapshot) {
287        self.snapshot
288            .reparse(text, self.language_registry.clone(), language);
289    }
290
291    pub fn did_parse(&mut self, snapshot: SyntaxSnapshot) {
292        self.snapshot = snapshot;
293    }
294
295    pub fn clear(&mut self, text: &BufferSnapshot) {
296        let update_count = self.snapshot.update_count + 1;
297        self.snapshot = SyntaxSnapshot::new(text);
298        self.snapshot.update_count = update_count;
299    }
300}
301
302impl SyntaxSnapshot {
303    fn new(text: &BufferSnapshot) -> Self {
304        Self {
305            layers: SumTree::new(text),
306            parsed_version: clock::Global::default(),
307            interpolated_version: clock::Global::default(),
308            language_registry_version: 0,
309            update_count: 0,
310        }
311    }
312
313    pub fn is_empty(&self) -> bool {
314        self.layers.is_empty()
315    }
316
317    pub fn root_language(&self) -> Option<Arc<Language>> {
318        match &self.layers.first()?.content {
319            SyntaxLayerContent::Parsed { language, .. } => Some(language.clone()),
320            SyntaxLayerContent::Pending { .. } => None,
321        }
322    }
323
324    pub fn update_count(&self) -> usize {
325        self.update_count
326    }
327
328    #[ztracing::instrument(skip_all)]
329    pub fn interpolate(&mut self, text: &BufferSnapshot) {
330        let edits = text
331            .anchored_edits_since::<Dimensions<usize, Point>>(&self.interpolated_version)
332            .collect::<Vec<_>>();
333        self.interpolated_version = text.version().clone();
334
335        if edits.is_empty() {
336            return;
337        }
338
339        let mut layers = SumTree::new(text);
340        let mut first_edit_ix_for_depth = 0;
341        let mut prev_depth = 0;
342        let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(text);
343        cursor.next();
344
345        'outer: loop {
346            let depth = cursor.end().max_depth;
347            if depth > prev_depth {
348                first_edit_ix_for_depth = 0;
349                prev_depth = depth;
350            }
351
352            // Preserve any layers at this depth that precede the first edit.
353            if let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) {
354                let target = ChangeStartPosition {
355                    depth,
356                    position: edit_range.start,
357                };
358                if target.cmp(cursor.start(), text).is_gt() {
359                    let slice = cursor.slice(&target, Bias::Left);
360                    layers.append(slice, text);
361                }
362            }
363            // If this layer follows all of the edits, then preserve it and any
364            // subsequent layers at this same depth.
365            else if cursor.item().is_some() {
366                let slice = cursor.slice(
367                    &SyntaxLayerPosition {
368                        depth: depth + 1,
369                        range: Anchor::min_max_range_for_buffer(text.remote_id()),
370                        language: None,
371                    },
372                    Bias::Left,
373                );
374                layers.append(slice, text);
375                continue;
376            };
377
378            let Some(layer) = cursor.item() else { break };
379            let Dimensions(start_byte, start_point, _) =
380                layer.range.start.summary::<Dimensions<usize, Point>>(text);
381
382            // Ignore edits that end before the start of this layer, and don't consider them
383            // for any subsequent layers at this same depth.
384            loop {
385                let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) else {
386                    continue 'outer;
387                };
388                if edit_range.end.cmp(&layer.range.start, text).is_le() {
389                    first_edit_ix_for_depth += 1;
390                } else {
391                    break;
392                }
393            }
394
395            let mut layer = layer.clone();
396            if let SyntaxLayerContent::Parsed { tree, .. } = &mut layer.content {
397                for (edit, edit_range) in &edits[first_edit_ix_for_depth..] {
398                    // Ignore any edits that follow this layer.
399                    if edit_range.start.cmp(&layer.range.end, text).is_ge() {
400                        break;
401                    }
402
403                    // Apply any edits that intersect this layer to the layer's syntax tree.
404                    let tree_edit = if edit_range.start.cmp(&layer.range.start, text).is_ge() {
405                        tree_sitter::InputEdit {
406                            start_byte: edit.new.start.0 - start_byte,
407                            old_end_byte: edit.new.start.0 - start_byte
408                                + (edit.old.end.0 - edit.old.start.0),
409                            new_end_byte: edit.new.end.0 - start_byte,
410                            start_position: (edit.new.start.1 - start_point).to_ts_point(),
411                            old_end_position: (edit.new.start.1 - start_point
412                                + (edit.old.end.1 - edit.old.start.1))
413                                .to_ts_point(),
414                            new_end_position: (edit.new.end.1 - start_point).to_ts_point(),
415                        }
416                    } else {
417                        let node = tree.root_node();
418                        tree_sitter::InputEdit {
419                            start_byte: 0,
420                            old_end_byte: node.end_byte(),
421                            new_end_byte: 0,
422                            start_position: Default::default(),
423                            old_end_position: node.end_position(),
424                            new_end_position: Default::default(),
425                        }
426                    };
427
428                    tree.edit(&tree_edit);
429                }
430
431                debug_assert!(
432                    tree.root_node().end_byte() <= text.len(),
433                    "tree's size {}, is larger than text size {}",
434                    tree.root_node().end_byte(),
435                    text.len(),
436                );
437            }
438
439            layers.push(layer, text);
440            cursor.next();
441        }
442
443        layers.append(cursor.suffix(), text);
444        drop(cursor);
445        self.layers = layers;
446    }
447
448    #[ztracing::instrument(skip_all)]
449    pub fn reparse(
450        &mut self,
451        text: &BufferSnapshot,
452        registry: Option<Arc<LanguageRegistry>>,
453        root_language: Arc<Language>,
454    ) {
455        self.reparse_(text, registry, root_language, None).ok();
456    }
457
458    #[ztracing::instrument(skip_all)]
459    pub fn reparse_with_timeout(
460        &mut self,
461        text: &BufferSnapshot,
462        registry: Option<Arc<LanguageRegistry>>,
463        root_language: Arc<Language>,
464        budget: Duration,
465    ) -> Result<(), ParseTimeout> {
466        self.reparse_(text, registry, root_language, Some(budget))
467    }
468
469    #[ztracing::instrument(skip_all, fields(lang = root_language.config.name.0.as_str()))]
470    fn reparse_(
471        &mut self,
472        text: &BufferSnapshot,
473        registry: Option<Arc<LanguageRegistry>>,
474        root_language: Arc<Language>,
475        mut budget: Option<Duration>,
476    ) -> Result<(), ParseTimeout> {
477        let budget = &mut budget;
478        let edit_ranges = text
479            .edits_since::<usize>(&self.parsed_version)
480            .map(|edit| edit.new)
481            .collect::<Vec<_>>();
482        self.reparse_with_ranges(
483            text,
484            root_language.clone(),
485            edit_ranges,
486            registry.as_ref(),
487            budget,
488        )?;
489
490        if let Some(registry) = registry
491            && registry.version() != self.language_registry_version
492        {
493            let mut resolved_injection_ranges = Vec::new();
494            let mut cursor = self
495                .layers
496                .filter::<_, ()>(text, |summary| summary.contains_unknown_injections);
497            cursor.next();
498            while let Some(layer) = cursor.item() {
499                let SyntaxLayerContent::Pending { language_name } = &layer.content else {
500                    unreachable!()
501                };
502                if registry
503                    .language_for_name_or_extension(language_name)
504                    .now_or_never()
505                    .and_then(|language| language.ok())
506                    .is_some()
507                {
508                    let range = layer.range.to_offset(text);
509                    log::trace!("reparse range {range:?} for language {language_name:?}");
510                    resolved_injection_ranges.push(range);
511                }
512
513                cursor.next();
514            }
515            drop(cursor);
516
517            if !resolved_injection_ranges.is_empty() {
518                self.reparse_with_ranges(
519                    text,
520                    root_language,
521                    resolved_injection_ranges,
522                    Some(&registry),
523                    budget,
524                )?;
525            }
526            self.language_registry_version = registry.version();
527        }
528
529        self.update_count += 1;
530        Ok(())
531    }
532
533    #[ztracing::instrument(skip_all)]
534    fn reparse_with_ranges(
535        &mut self,
536        text: &BufferSnapshot,
537        root_language: Arc<Language>,
538        invalidated_ranges: Vec<Range<usize>>,
539        registry: Option<&Arc<LanguageRegistry>>,
540        budget: &mut Option<Duration>,
541    ) -> Result<(), ParseTimeout> {
542        log::trace!(
543            "reparse. invalidated ranges:{:?}",
544            LogOffsetRanges(&invalidated_ranges, text),
545        );
546
547        let max_depth = self.layers.summary().max_depth;
548        let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(text);
549        cursor.next();
550        let mut layers = SumTree::new(text);
551
552        let mut changed_regions = ChangeRegionSet::default();
553        let mut queue = BinaryHeap::new();
554        let mut combined_injection_ranges = HashMap::default();
555        queue.push(ParseStep {
556            depth: 0,
557            language: ParseStepLanguage::Loaded {
558                language: root_language,
559            },
560            included_ranges: vec![tree_sitter::Range {
561                start_byte: 0,
562                end_byte: text.len(),
563                start_point: Point::zero().to_ts_point(),
564                end_point: text.max_point().to_ts_point(),
565            }],
566            range: Anchor::min_max_range_for_buffer(text.remote_id()),
567            mode: ParseMode::Single,
568        });
569
570        loop {
571            let step = queue.pop();
572            let position = if let Some(step) = &step {
573                log::trace!(
574                    "parse step depth:{}, range:{:?}, language:{} ({:?})",
575                    step.depth,
576                    LogAnchorRange(&step.range, text),
577                    step.language.name(),
578                    step.language.id(),
579                );
580                SyntaxLayerPosition {
581                    depth: step.depth,
582                    range: step.range.clone(),
583                    language: step.language.id(),
584                }
585            } else {
586                SyntaxLayerPosition {
587                    depth: max_depth + 1,
588                    range: Anchor::min_max_range_for_buffer(text.remote_id()),
589                    language: None,
590                }
591            };
592
593            let mut done = cursor.item().is_none();
594            while !done && position.cmp(&cursor.end(), text).is_gt() {
595                done = true;
596
597                let bounded_position = SyntaxLayerPositionBeforeChange {
598                    position: position.clone(),
599                    change: changed_regions.start_position(text.remote_id()),
600                };
601                if bounded_position.cmp(cursor.start(), text).is_gt() {
602                    let slice = cursor.slice(&bounded_position, Bias::Left);
603                    if !slice.is_empty() {
604                        layers.append(slice, text);
605                        if changed_regions.prune(cursor.end(), text) {
606                            done = false;
607                        }
608                    }
609                }
610
611                while position.cmp(&cursor.end(), text).is_gt() {
612                    let Some(layer) = cursor.item() else { break };
613
614                    if changed_regions.intersects(layer, text) {
615                        if let SyntaxLayerContent::Parsed { language, .. } = &layer.content {
616                            log::trace!(
617                                "discard layer. language:{}, range:{:?}. changed_regions:{:?}",
618                                language.name(),
619                                LogAnchorRange(&layer.range, text),
620                                LogChangedRegions(&changed_regions, text),
621                            );
622                        }
623
624                        changed_regions.insert(
625                            ChangedRegion {
626                                depth: layer.depth + 1,
627                                range: layer.range.clone(),
628                            },
629                            text,
630                        );
631                    } else {
632                        layers.push(layer.clone(), text);
633                    }
634
635                    cursor.next();
636                    if changed_regions.prune(cursor.end(), text) {
637                        done = false;
638                    }
639                }
640            }
641
642            let Some(step) = step else { break };
643            let Dimensions(step_start_byte, step_start_point, _) =
644                step.range.start.summary::<Dimensions<usize, Point>>(text);
645            let step_end_byte = step.range.end.to_offset(text);
646
647            let mut old_layer = cursor.item();
648            if let Some(layer) = old_layer {
649                if layer.range.to_offset(text) == (step_start_byte..step_end_byte)
650                    && layer.content.language_id() == step.language.id()
651                {
652                    cursor.next();
653                } else {
654                    old_layer = None;
655                }
656            }
657
658            let content = match step.language {
659                ParseStepLanguage::Loaded { language } => {
660                    let Some(grammar) = language.grammar() else {
661                        continue;
662                    };
663                    let tree;
664                    let changed_ranges;
665
666                    let mut included_ranges = step.included_ranges;
667                    let is_combined = matches!(step.mode, ParseMode::Combined { .. });
668
669                    for range in &mut included_ranges {
670                        range.start_byte -= step_start_byte;
671                        range.end_byte -= step_start_byte;
672                        range.start_point = (Point::from_ts_point(range.start_point)
673                            - step_start_point)
674                            .to_ts_point();
675                        range.end_point = (Point::from_ts_point(range.end_point)
676                            - step_start_point)
677                            .to_ts_point();
678                    }
679
680                    if let Some((SyntaxLayerContent::Parsed { tree: old_tree, .. }, layer_range)) =
681                        old_layer.map(|layer| (&layer.content, layer.range.clone()))
682                    {
683                        log::trace!(
684                            "existing layer. language:{}, range:{:?}, included_ranges:{:?}",
685                            language.name(),
686                            LogAnchorRange(&layer_range, text),
687                            LogIncludedRanges(&old_tree.included_ranges())
688                        );
689
690                        if let ParseMode::Combined {
691                            mut parent_layer_changed_ranges,
692                            ..
693                        } = step.mode
694                        {
695                            for range in &mut parent_layer_changed_ranges {
696                                range.start = range.start.saturating_sub(step_start_byte);
697                                range.end = range.end.saturating_sub(step_start_byte);
698                            }
699
700                            let changed_indices;
701                            (included_ranges, changed_indices) = splice_included_ranges(
702                                old_tree.included_ranges(),
703                                &parent_layer_changed_ranges,
704                                &included_ranges,
705                            );
706                            insert_newlines_between_ranges(
707                                changed_indices,
708                                &mut included_ranges,
709                                text,
710                                step_start_byte,
711                                step_start_point,
712                            );
713                        }
714
715                        if included_ranges.is_empty() {
716                            included_ranges.push(tree_sitter::Range {
717                                start_byte: 0,
718                                end_byte: 0,
719                                start_point: Default::default(),
720                                end_point: Default::default(),
721                            });
722                        }
723
724                        log::trace!(
725                            "update layer. language:{}, range:{:?}, included_ranges:{:?}",
726                            language.name(),
727                            LogAnchorRange(&step.range, text),
728                            LogIncludedRanges(&included_ranges),
729                        );
730
731                        let result = parse_text(
732                            grammar,
733                            text.as_rope(),
734                            step_start_byte,
735                            &included_ranges,
736                            Some(old_tree),
737                            budget,
738                        );
739                        match result {
740                            Ok(t) => tree = t,
741                            Err(e) if e.downcast_ref::<ParseTimeout>().is_some() => {
742                                return Err(ParseTimeout);
743                            }
744                            Err(e) => {
745                                log::error!("error parsing text: {e:?}");
746                                continue;
747                            }
748                        };
749
750                        changed_ranges = join_ranges(
751                            invalidated_ranges
752                                .iter()
753                                .filter(|&range| {
754                                    range.start <= step_end_byte && range.end >= step_start_byte
755                                })
756                                .cloned(),
757                            old_tree.changed_ranges(&tree).map(|r| {
758                                step_start_byte + r.start_byte..step_start_byte + r.end_byte
759                            }),
760                        );
761                    } else {
762                        if matches!(step.mode, ParseMode::Combined { .. }) {
763                            insert_newlines_between_ranges(
764                                0..included_ranges.len(),
765                                &mut included_ranges,
766                                text,
767                                step_start_byte,
768                                step_start_point,
769                            );
770                        }
771
772                        if included_ranges.is_empty() {
773                            included_ranges.push(tree_sitter::Range {
774                                start_byte: 0,
775                                end_byte: 0,
776                                start_point: Default::default(),
777                                end_point: Default::default(),
778                            });
779                        }
780
781                        log::trace!(
782                            "create layer. language:{}, range:{:?}, included_ranges:{:?}",
783                            language.name(),
784                            LogAnchorRange(&step.range, text),
785                            LogIncludedRanges(&included_ranges),
786                        );
787
788                        let result = parse_text(
789                            grammar,
790                            text.as_rope(),
791                            step_start_byte,
792                            &included_ranges,
793                            None,
794                            budget,
795                        );
796                        match result {
797                            Ok(t) => tree = t,
798                            Err(e) if e.downcast_ref::<ParseTimeout>().is_some() => {
799                                return Err(ParseTimeout);
800                            }
801                            Err(e) => {
802                                log::error!("error parsing text: {e:?}");
803                                continue;
804                            }
805                        };
806                        changed_ranges = vec![step_start_byte..step_end_byte];
807                    }
808
809                    if let (Some((config, registry)), false) = (
810                        grammar.injection_config.as_ref().zip(registry.as_ref()),
811                        changed_ranges.is_empty(),
812                    ) {
813                        // Handle invalidation and reactivation of injections on comment update
814                        let mut expanded_ranges: Vec<_> = changed_ranges
815                            .iter()
816                            .map(|range| {
817                                let start_row = range.start.to_point(text).row.saturating_sub(1);
818                                let end_row = range.end.to_point(text).row.saturating_add(2);
819                                text.point_to_offset(Point::new(start_row, 0))
820                                    ..text.point_to_offset(Point::new(end_row, 0)).min(text.len())
821                            })
822                            .collect();
823                        expanded_ranges.sort_unstable_by_key(|r| r.start);
824                        expanded_ranges.dedup_by(|b, a| {
825                            let overlaps = b.start <= a.end;
826                            if overlaps {
827                                a.end = a.end.max(b.end);
828                            }
829                            overlaps
830                        });
831
832                        for range in &expanded_ranges {
833                            changed_regions.insert(
834                                ChangedRegion {
835                                    depth: step.depth + 1,
836                                    range: text.anchor_before(range.start)
837                                        ..text.anchor_after(range.end),
838                                },
839                                text,
840                            );
841                        }
842                        get_injections(
843                            config,
844                            text,
845                            step.range.clone(),
846                            tree.root_node_with_offset(
847                                step_start_byte,
848                                step_start_point.to_ts_point(),
849                            ),
850                            registry,
851                            step.depth + 1,
852                            &expanded_ranges,
853                            &mut combined_injection_ranges,
854                            &mut queue,
855                        );
856                    }
857
858                    let included_sub_ranges: Option<Vec<Range<Anchor>>> = if is_combined {
859                        Some(
860                            included_ranges
861                                .into_iter()
862                                .filter(|r| r.start_byte < r.end_byte)
863                                .map(|r| {
864                                    text.anchor_before(r.start_byte + step_start_byte)
865                                        ..text.anchor_after(r.end_byte + step_start_byte)
866                                })
867                                .collect(),
868                        )
869                    } else {
870                        None
871                    };
872                    SyntaxLayerContent::Parsed {
873                        tree,
874                        language,
875                        included_sub_ranges,
876                    }
877                }
878                ParseStepLanguage::Pending { name } => SyntaxLayerContent::Pending {
879                    language_name: name,
880                },
881            };
882
883            layers.push(
884                SyntaxLayerEntry {
885                    depth: step.depth,
886                    range: step.range,
887                    content,
888                },
889                text,
890            );
891        }
892
893        drop(cursor);
894        self.layers = layers;
895        self.interpolated_version = text.version.clone();
896        self.parsed_version = text.version.clone();
897        #[cfg(debug_assertions)]
898        self.check_invariants(text);
899        Ok(())
900    }
901
902    #[cfg(debug_assertions)]
903    fn check_invariants(&self, text: &BufferSnapshot) {
904        let mut max_depth = 0;
905        let mut prev_layer: Option<(Range<Anchor>, Option<LanguageId>)> = None;
906        for layer in self.layers.iter() {
907            match Ord::cmp(&layer.depth, &max_depth) {
908                Ordering::Less => {
909                    panic!("layers out of order")
910                }
911                Ordering::Equal => {
912                    if let Some((prev_range, prev_language_id)) = prev_layer {
913                        match layer.range.start.cmp(&prev_range.start, text) {
914                            Ordering::Less => panic!("layers out of order"),
915                            Ordering::Equal => match layer.range.end.cmp(&prev_range.end, text) {
916                                Ordering::Less => panic!("layers out of order"),
917                                Ordering::Equal => {
918                                    if layer.content.language_id() < prev_language_id {
919                                        panic!("layers out of order")
920                                    }
921                                }
922                                Ordering::Greater => {}
923                            },
924                            Ordering::Greater => {}
925                        }
926                    }
927                    prev_layer = Some((layer.range.clone(), layer.content.language_id()));
928                }
929                Ordering::Greater => {
930                    prev_layer = None;
931                }
932            }
933
934            max_depth = layer.depth;
935        }
936    }
937
938    pub fn single_tree_captures<'a>(
939        range: Range<usize>,
940        text: &'a Rope,
941        tree: &'a tree_sitter::Tree,
942        language: &'a Arc<Language>,
943        query: fn(&Grammar) -> Option<&Query>,
944    ) -> SyntaxMapCaptures<'a> {
945        SyntaxMapCaptures::new(
946            range,
947            text,
948            [SyntaxLayer {
949                language,
950                tree,
951                included_sub_ranges: None,
952                depth: 0,
953                offset: (0, tree_sitter::Point::new(0, 0)),
954            }]
955            .into_iter(),
956            query,
957        )
958    }
959
960    pub fn captures<'a>(
961        &'a self,
962        range: Range<usize>,
963        buffer: &'a BufferSnapshot,
964        query: fn(&Grammar) -> Option<&Query>,
965    ) -> SyntaxMapCaptures<'a> {
966        SyntaxMapCaptures::new(
967            range.clone(),
968            buffer.as_rope(),
969            self.layers_for_range(range, buffer, true),
970            query,
971        )
972    }
973
974    pub fn matches<'a>(
975        &'a self,
976        range: Range<usize>,
977        buffer: &'a BufferSnapshot,
978        query: fn(&Grammar) -> Option<&Query>,
979    ) -> SyntaxMapMatches<'a> {
980        SyntaxMapMatches::new(
981            range.clone(),
982            buffer.as_rope(),
983            self.layers_for_range(range, buffer, true),
984            query,
985            TreeSitterOptions::default(),
986        )
987    }
988
989    pub fn matches_with_options<'a>(
990        &'a self,
991        range: Range<usize>,
992        buffer: &'a BufferSnapshot,
993        options: TreeSitterOptions,
994        query: fn(&Grammar) -> Option<&Query>,
995    ) -> SyntaxMapMatches<'a> {
996        SyntaxMapMatches::new(
997            range.clone(),
998            buffer.as_rope(),
999            self.layers_for_range(range, buffer, true),
1000            query,
1001            options,
1002        )
1003    }
1004
1005    pub fn languages<'a>(
1006        &'a self,
1007        buffer: &'a BufferSnapshot,
1008        include_hidden: bool,
1009    ) -> impl Iterator<Item = &'a Arc<Language>> {
1010        let mut cursor = self.layers.cursor::<()>(buffer);
1011        cursor.next();
1012        iter::from_fn(move || {
1013            while let Some(layer) = cursor.item() {
1014                let mut info = None;
1015                if let SyntaxLayerContent::Parsed { language, .. } = &layer.content {
1016                    if include_hidden || !language.config.hidden {
1017                        info = Some(language);
1018                    }
1019                }
1020                cursor.next();
1021                if info.is_some() {
1022                    return info;
1023                }
1024            }
1025            None
1026        })
1027    }
1028
1029    #[cfg(test)]
1030    pub fn layers<'a>(&'a self, buffer: &'a BufferSnapshot) -> Vec<SyntaxLayer<'a>> {
1031        self.layers_for_range(0..buffer.len(), buffer, true)
1032            .collect()
1033    }
1034
1035    pub fn layers_for_range<'a, T: ToOffset>(
1036        &'a self,
1037        range: Range<T>,
1038        buffer: &'a BufferSnapshot,
1039        include_hidden: bool,
1040    ) -> impl 'a + Iterator<Item = SyntaxLayer<'a>> {
1041        let start_offset = range.start.to_offset(buffer);
1042        let end_offset = range.end.to_offset(buffer);
1043        let start = buffer.anchor_before(start_offset);
1044        let end = buffer.anchor_after(end_offset);
1045
1046        let mut cursor = self.layers.filter::<_, ()>(buffer, move |summary| {
1047            if summary.max_depth > summary.min_depth {
1048                true
1049            } else {
1050                let is_before_start = summary.range.end.cmp(&start, buffer).is_lt();
1051                let is_after_end = summary.range.start.cmp(&end, buffer).is_gt();
1052                !is_before_start && !is_after_end
1053            }
1054        });
1055
1056        cursor.next();
1057        iter::from_fn(move || {
1058            while let Some(layer) = cursor.item() {
1059                let mut info = None;
1060                if let SyntaxLayerContent::Parsed {
1061                    tree,
1062                    language,
1063                    included_sub_ranges,
1064                } = &layer.content
1065                {
1066                    let layer_start_offset = layer.range.start.to_offset(buffer);
1067                    let layer_start_point = layer.range.start.to_point(buffer).to_ts_point();
1068                    if include_hidden || !language.config.hidden {
1069                        info = Some(SyntaxLayer {
1070                            tree,
1071                            language,
1072                            included_sub_ranges: included_sub_ranges.as_deref(),
1073                            depth: layer.depth,
1074                            offset: (layer_start_offset, layer_start_point),
1075                        });
1076                    }
1077                }
1078                cursor.next();
1079                if info.is_some() {
1080                    return info;
1081                }
1082            }
1083            None
1084        })
1085    }
1086
1087    pub fn contains_unknown_injections(&self) -> bool {
1088        self.layers.summary().contains_unknown_injections
1089    }
1090
1091    pub fn language_registry_version(&self) -> usize {
1092        self.language_registry_version
1093    }
1094}
1095
1096impl<'a> SyntaxMapCaptures<'a> {
1097    fn new(
1098        range: Range<usize>,
1099        text: &'a Rope,
1100        layers: impl Iterator<Item = SyntaxLayer<'a>>,
1101        query: fn(&Grammar) -> Option<&Query>,
1102    ) -> Self {
1103        let mut result = Self {
1104            layers: Vec::new(),
1105            grammars: Vec::new(),
1106            active_layer_count: 0,
1107        };
1108        for layer in layers {
1109            let grammar = match &layer.language.grammar {
1110                Some(grammar) => grammar,
1111                None => continue,
1112            };
1113            let query = match query(grammar) {
1114                Some(query) => query,
1115                None => continue,
1116            };
1117
1118            let mut query_cursor = QueryCursorHandle::new();
1119
1120            // TODO - add a Tree-sitter API to remove the need for this.
1121            let cursor = unsafe {
1122                std::mem::transmute::<&mut tree_sitter::QueryCursor, &'static mut QueryCursor>(
1123                    query_cursor.deref_mut(),
1124                )
1125            };
1126
1127            cursor.set_byte_range(range.clone());
1128            let captures = cursor.captures(query, layer.node(), TextProvider(text));
1129            let grammar_index = result
1130                .grammars
1131                .iter()
1132                .position(|g| g.id() == grammar.id())
1133                .unwrap_or_else(|| {
1134                    result.grammars.push(grammar);
1135                    result.grammars.len() - 1
1136                });
1137            let mut layer = SyntaxMapCapturesLayer {
1138                depth: layer.depth,
1139                grammar_index,
1140                next_capture: None,
1141                captures,
1142                _query_cursor: query_cursor,
1143            };
1144
1145            layer.advance();
1146            if layer.next_capture.is_some() {
1147                let key = layer.sort_key();
1148                let ix = match result.layers[..result.active_layer_count]
1149                    .binary_search_by_key(&key, |layer| layer.sort_key())
1150                {
1151                    Ok(ix) | Err(ix) => ix,
1152                };
1153                result.layers.insert(ix, layer);
1154                result.active_layer_count += 1;
1155            } else {
1156                result.layers.push(layer);
1157            }
1158        }
1159
1160        result
1161    }
1162
1163    pub fn grammars(&self) -> &[&'a Grammar] {
1164        &self.grammars
1165    }
1166
1167    pub fn peek(&self) -> Option<SyntaxMapCapture<'a>> {
1168        let layer = self.layers[..self.active_layer_count].first()?;
1169        let capture = layer.next_capture?;
1170        Some(SyntaxMapCapture {
1171            grammar_index: layer.grammar_index,
1172            index: capture.index,
1173            node: capture.node,
1174        })
1175    }
1176
1177    pub fn advance(&mut self) -> bool {
1178        let layer = if let Some(layer) = self.layers[..self.active_layer_count].first_mut() {
1179            layer
1180        } else {
1181            return false;
1182        };
1183
1184        layer.advance();
1185        if layer.next_capture.is_some() {
1186            let key = layer.sort_key();
1187            let i = 1 + self.layers[1..self.active_layer_count]
1188                .iter()
1189                .position(|later_layer| key < later_layer.sort_key())
1190                .unwrap_or(self.active_layer_count - 1);
1191            self.layers[0..i].rotate_left(1);
1192        } else {
1193            self.layers[0..self.active_layer_count].rotate_left(1);
1194            self.active_layer_count -= 1;
1195        }
1196
1197        true
1198    }
1199
1200    pub fn set_byte_range(&mut self, range: Range<usize>) {
1201        for layer in &mut self.layers {
1202            layer.captures.set_byte_range(range.clone());
1203            if let Some(capture) = &layer.next_capture
1204                && capture.node.end_byte() > range.start
1205            {
1206                continue;
1207            }
1208            layer.advance();
1209        }
1210        self.layers.sort_unstable_by_key(|layer| layer.sort_key());
1211        self.active_layer_count = self
1212            .layers
1213            .iter()
1214            .position(|layer| layer.next_capture.is_none())
1215            .unwrap_or(self.layers.len());
1216    }
1217}
1218
1219#[derive(Default)]
1220pub struct TreeSitterOptions {
1221    pub max_start_depth: Option<u32>,
1222    pub max_bytes_to_query: Option<usize>,
1223}
1224
1225impl TreeSitterOptions {
1226    pub fn max_start_depth(max_start_depth: u32) -> Self {
1227        Self {
1228            max_start_depth: Some(max_start_depth),
1229            max_bytes_to_query: None,
1230        }
1231    }
1232}
1233
1234impl<'a> SyntaxMapMatches<'a> {
1235    fn new(
1236        range: Range<usize>,
1237        text: &'a Rope,
1238        layers: impl Iterator<Item = SyntaxLayer<'a>>,
1239        query: fn(&Grammar) -> Option<&Query>,
1240        options: TreeSitterOptions,
1241    ) -> Self {
1242        let mut result = Self::default();
1243        for layer in layers {
1244            let grammar = match &layer.language.grammar {
1245                Some(grammar) => grammar,
1246                None => continue,
1247            };
1248            let query = match query(grammar) {
1249                Some(query) => query,
1250                None => continue,
1251            };
1252
1253            let mut query_cursor = QueryCursorHandle::new();
1254
1255            // TODO - add a Tree-sitter API to remove the need for this.
1256            let cursor = unsafe {
1257                std::mem::transmute::<&mut tree_sitter::QueryCursor, &'static mut QueryCursor>(
1258                    query_cursor.deref_mut(),
1259                )
1260            };
1261            cursor.set_max_start_depth(options.max_start_depth);
1262
1263            if let Some(max_bytes_to_query) = options.max_bytes_to_query {
1264                let midpoint = (range.start + range.end) / 2;
1265                let containing_range_start = midpoint.saturating_sub(max_bytes_to_query / 2);
1266                let containing_range_end =
1267                    containing_range_start.saturating_add(max_bytes_to_query);
1268                cursor.set_containing_byte_range(containing_range_start..containing_range_end);
1269            }
1270
1271            cursor.set_byte_range(range.clone());
1272            let matches = cursor.matches(query, layer.node(), TextProvider(text));
1273            let grammar_index = result
1274                .grammars
1275                .iter()
1276                .position(|g| g.id() == grammar.id())
1277                .unwrap_or_else(|| {
1278                    result.grammars.push(grammar);
1279                    result.grammars.len() - 1
1280                });
1281            let mut layer = SyntaxMapMatchesLayer {
1282                language: layer.language.clone(),
1283                depth: layer.depth,
1284                grammar_index,
1285                matches,
1286                query,
1287                next_pattern_index: 0,
1288                next_captures: Vec::new(),
1289                has_next: false,
1290                _query_cursor: query_cursor,
1291            };
1292
1293            layer.advance();
1294            if layer.has_next {
1295                let key = layer.sort_key();
1296                let ix = match result.layers[..result.active_layer_count]
1297                    .binary_search_by_key(&key, |layer| layer.sort_key())
1298                {
1299                    Ok(ix) | Err(ix) => ix,
1300                };
1301                result.layers.insert(ix, layer);
1302                result.active_layer_count += 1;
1303            } else {
1304                result.layers.push(layer);
1305            }
1306        }
1307        result
1308    }
1309
1310    pub fn grammars(&self) -> &[&'a Grammar] {
1311        &self.grammars
1312    }
1313
1314    pub fn peek(&self) -> Option<SyntaxMapMatch<'_>> {
1315        let layer = self.layers.first()?;
1316
1317        if !layer.has_next {
1318            return None;
1319        }
1320
1321        Some(SyntaxMapMatch {
1322            language: layer.language.clone(),
1323            depth: layer.depth,
1324            grammar_index: layer.grammar_index,
1325            pattern_index: layer.next_pattern_index,
1326            captures: &layer.next_captures,
1327        })
1328    }
1329
1330    pub fn advance(&mut self) -> bool {
1331        let layer = if let Some(layer) = self.layers.first_mut() {
1332            layer
1333        } else {
1334            return false;
1335        };
1336
1337        layer.advance();
1338        if layer.has_next {
1339            let key = layer.sort_key();
1340            let i = 1 + self.layers[1..self.active_layer_count]
1341                .iter()
1342                .position(|later_layer| key < later_layer.sort_key())
1343                .unwrap_or(self.active_layer_count - 1);
1344            self.layers[0..i].rotate_left(1);
1345        } else if self.active_layer_count != 0 {
1346            self.layers[0..self.active_layer_count].rotate_left(1);
1347            self.active_layer_count -= 1;
1348        }
1349
1350        true
1351    }
1352
1353    // pub fn set_byte_range(&mut self, range: Range<usize>) {
1354    //     for layer in &mut self.layers {
1355    //         layer.matches.set_byte_range(range.clone());
1356    //         layer.advance();
1357    //     }
1358    //     self.layers.sort_unstable_by_key(|layer| layer.sort_key());
1359    //     self.active_layer_count = self
1360    //         .layers
1361    //         .iter()
1362    //         .position(|layer| !layer.has_next)
1363    //         .unwrap_or(self.layers.len());
1364    // }
1365}
1366
1367impl SyntaxMapCapturesLayer<'_> {
1368    fn advance(&mut self) {
1369        self.next_capture = self.captures.next().map(|(mat, ix)| mat.captures[*ix]);
1370    }
1371
1372    fn sort_key(&self) -> (usize, Reverse<usize>, usize) {
1373        if let Some(capture) = &self.next_capture {
1374            let range = capture.node.byte_range();
1375            (range.start, Reverse(range.end), self.depth)
1376        } else {
1377            (usize::MAX, Reverse(0), usize::MAX)
1378        }
1379    }
1380}
1381
1382impl SyntaxMapMatchesLayer<'_> {
1383    fn advance(&mut self) {
1384        loop {
1385            if let Some(mat) = self.matches.next() {
1386                if !satisfies_custom_predicates(self.query, mat) {
1387                    continue;
1388                }
1389                self.next_captures.clear();
1390                self.next_captures.extend_from_slice(mat.captures);
1391                self.next_pattern_index = mat.pattern_index;
1392                self.has_next = true;
1393                return;
1394            } else {
1395                self.has_next = false;
1396                return;
1397            }
1398        }
1399    }
1400
1401    fn sort_key(&self) -> (usize, Reverse<usize>, usize) {
1402        if self.has_next {
1403            let captures = &self.next_captures;
1404            if let Some((first, last)) = captures.first().zip(captures.last()) {
1405                return (
1406                    first.node.start_byte(),
1407                    Reverse(last.node.end_byte()),
1408                    self.depth,
1409                );
1410            }
1411        }
1412        (usize::MAX, Reverse(0), usize::MAX)
1413    }
1414}
1415
1416impl<'a> Iterator for SyntaxMapCaptures<'a> {
1417    type Item = SyntaxMapCapture<'a>;
1418
1419    fn next(&mut self) -> Option<Self::Item> {
1420        let result = self.peek();
1421        self.advance();
1422        result
1423    }
1424}
1425
1426fn satisfies_custom_predicates(query: &Query, mat: &QueryMatch) -> bool {
1427    for predicate in query.general_predicates(mat.pattern_index) {
1428        let satisfied = match predicate.operator.as_ref() {
1429            "has-parent?" => has_parent(&predicate.args, mat),
1430            "not-has-parent?" => !has_parent(&predicate.args, mat),
1431            _ => true,
1432        };
1433        if !satisfied {
1434            return false;
1435        }
1436    }
1437    true
1438}
1439
1440fn has_parent(args: &[QueryPredicateArg], mat: &QueryMatch) -> bool {
1441    let (
1442        Some(QueryPredicateArg::Capture(capture_ix)),
1443        Some(QueryPredicateArg::String(parent_kind)),
1444    ) = (args.first(), args.get(1))
1445    else {
1446        return false;
1447    };
1448
1449    let Some(capture) = mat.captures.iter().find(|c| c.index == *capture_ix) else {
1450        return false;
1451    };
1452
1453    capture
1454        .node
1455        .parent()
1456        .is_some_and(|p| p.kind() == parent_kind.as_ref())
1457}
1458
1459fn join_ranges(
1460    a: impl Iterator<Item = Range<usize>>,
1461    b: impl Iterator<Item = Range<usize>>,
1462) -> Vec<Range<usize>> {
1463    let mut result = Vec::<Range<usize>>::new();
1464    let mut a = a.peekable();
1465    let mut b = b.peekable();
1466    loop {
1467        let range = match (a.peek(), b.peek()) {
1468            (Some(range_a), Some(range_b)) => {
1469                if range_a.start < range_b.start {
1470                    a.next().unwrap()
1471                } else {
1472                    b.next().unwrap()
1473                }
1474            }
1475            (None, Some(_)) => b.next().unwrap(),
1476            (Some(_), None) => a.next().unwrap(),
1477            (None, None) => break,
1478        };
1479
1480        if let Some(last) = result.last_mut()
1481            && range.start <= last.end
1482        {
1483            last.end = last.end.max(range.end);
1484            continue;
1485        }
1486        result.push(range);
1487    }
1488    result
1489}
1490
1491#[derive(Copy, Clone, Debug)]
1492pub struct ParseTimeout;
1493
1494impl std::error::Error for ParseTimeout {}
1495
1496impl std::fmt::Display for ParseTimeout {
1497    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1498        write!(f, "parse timeout")
1499    }
1500}
1501
1502#[ztracing::instrument(skip_all)]
1503fn parse_text(
1504    grammar: &Grammar,
1505    text: &Rope,
1506    start_byte: usize,
1507    ranges: &[tree_sitter::Range],
1508    old_tree: Option<&tree_sitter::Tree>,
1509    parse_budget: &mut Option<Duration>,
1510) -> anyhow::Result<tree_sitter::Tree> {
1511    with_parser(|parser| {
1512        let mut timed_out = false;
1513        let now = Instant::now();
1514        let mut progress_callback = parse_budget.map(|budget| {
1515            let timed_out = &mut timed_out;
1516            move |_: &_| {
1517                let elapsed = now.elapsed();
1518                if elapsed > budget {
1519                    *timed_out = true;
1520                    ControlFlow::Break(())
1521                } else {
1522                    ControlFlow::Continue(())
1523                }
1524            }
1525        });
1526
1527        let mut chunks = text.chunks_in_range(start_byte..text.len());
1528        parser.set_included_ranges(ranges)?;
1529        parser.set_language(&grammar.ts_language)?;
1530        parser
1531            .parse_with_options(
1532                &mut move |offset, _| {
1533                    chunks.seek(start_byte + offset);
1534                    chunks.next().unwrap_or("").as_bytes()
1535                },
1536                old_tree,
1537                progress_callback
1538                    .as_mut()
1539                    .map(|progress_callback| tree_sitter::ParseOptions {
1540                        progress_callback: Some(progress_callback),
1541                    }),
1542            )
1543            .inspect(|_| {
1544                if let Some(parse_budget) = parse_budget {
1545                    *parse_budget = parse_budget.saturating_sub(now.elapsed());
1546                }
1547            })
1548            .ok_or_else(|| match timed_out {
1549                true => anyhow::anyhow!(ParseTimeout),
1550                false => anyhow::anyhow!("parsing failed"),
1551            })
1552    })
1553}
1554
1555#[ztracing::instrument(skip_all)]
1556fn get_injections(
1557    config: &InjectionConfig,
1558    text: &BufferSnapshot,
1559    outer_range: Range<Anchor>,
1560    node: Node,
1561    language_registry: &Arc<LanguageRegistry>,
1562    depth: usize,
1563    changed_ranges: &[Range<usize>],
1564    combined_injection_ranges: &mut HashMap<LanguageId, (Arc<Language>, Vec<tree_sitter::Range>)>,
1565    queue: &mut BinaryHeap<ParseStep>,
1566) {
1567    let mut query_cursor = QueryCursorHandle::new();
1568    let mut prev_match = None;
1569
1570    // Ensure that a `ParseStep` is created for every combined injection language, even
1571    // if there currently no matches for that injection.
1572    combined_injection_ranges.clear();
1573    for pattern in &config.patterns {
1574        if let (Some(language_name), true) = (pattern.language.as_ref(), pattern.combined)
1575            && let Some(language) = language_registry
1576                .language_for_name_or_extension(language_name)
1577                .now_or_never()
1578                .and_then(|language| language.ok())
1579        {
1580            combined_injection_ranges.insert(language.id, (language, Vec::new()));
1581        }
1582    }
1583
1584    for query_range in changed_ranges {
1585        query_cursor.set_byte_range(query_range.start.saturating_sub(1)..query_range.end + 1);
1586        let mut matches = query_cursor.matches(&config.query, node, TextProvider(text.as_rope()));
1587        while let Some(mat) = matches.next() {
1588            let content_ranges = mat
1589                .nodes_for_capture_index(config.content_capture_ix)
1590                .map(|node| node.range())
1591                .collect::<Vec<_>>();
1592            if content_ranges.is_empty() {
1593                continue;
1594            }
1595
1596            let content_range =
1597                content_ranges.first().unwrap().start_byte..content_ranges.last().unwrap().end_byte;
1598
1599            // Avoid duplicate matches if two changed ranges intersect the same injection.
1600            if let Some((prev_pattern_ix, prev_range)) = &prev_match
1601                && mat.pattern_index == *prev_pattern_ix
1602                && content_range == *prev_range
1603            {
1604                continue;
1605            }
1606
1607            prev_match = Some((mat.pattern_index, content_range.clone()));
1608            let combined = config.patterns[mat.pattern_index].combined;
1609
1610            let mut step_range = content_range.clone();
1611            let language_name =
1612                if let Some(name) = config.patterns[mat.pattern_index].language.as_ref() {
1613                    Some(Cow::Borrowed(name.as_ref()))
1614                } else if let Some(language_node) = config
1615                    .language_capture_ix
1616                    .and_then(|ix| mat.nodes_for_capture_index(ix).next())
1617                {
1618                    step_range.start = cmp::min(content_range.start, language_node.start_byte());
1619                    step_range.end = cmp::max(content_range.end, language_node.end_byte());
1620                    let language_name: String =
1621                        text.text_for_range(language_node.byte_range()).collect();
1622
1623                    // Enable paths ending in a language extension to represent a language name: e.g. "foo/bar/baz.rs"
1624                    if let Some(last_dot_pos) = language_name.rfind('.') {
1625                        Some(Cow::Owned(language_name[last_dot_pos + 1..].to_string()))
1626                    } else {
1627                        Some(Cow::Owned(language_name))
1628                    }
1629                } else {
1630                    None
1631                };
1632
1633            if let Some(language_name) = language_name {
1634                let language = language_registry
1635                    .language_for_name_or_extension(&language_name)
1636                    .now_or_never()
1637                    .and_then(|language| language.ok());
1638                let range = text.anchor_before(step_range.start)..text.anchor_after(step_range.end);
1639                if let Some(language) = language {
1640                    if combined {
1641                        combined_injection_ranges
1642                            .entry(language.id)
1643                            .or_insert_with(|| (language.clone(), vec![]))
1644                            .1
1645                            .extend(content_ranges);
1646                    } else {
1647                        queue.push(ParseStep {
1648                            depth,
1649                            language: ParseStepLanguage::Loaded { language },
1650                            included_ranges: content_ranges,
1651                            range,
1652                            mode: ParseMode::Single,
1653                        });
1654                    }
1655                } else {
1656                    queue.push(ParseStep {
1657                        depth,
1658                        language: ParseStepLanguage::Pending {
1659                            name: language_name.into(),
1660                        },
1661                        included_ranges: content_ranges,
1662                        range,
1663                        mode: ParseMode::Single,
1664                    });
1665                }
1666            }
1667        }
1668    }
1669
1670    for (_, (language, mut included_ranges)) in combined_injection_ranges.drain() {
1671        included_ranges.sort_unstable_by(|a, b| {
1672            Ord::cmp(&a.start_byte, &b.start_byte).then_with(|| Ord::cmp(&a.end_byte, &b.end_byte))
1673        });
1674        queue.push(ParseStep {
1675            depth,
1676            language: ParseStepLanguage::Loaded { language },
1677            range: outer_range.clone(),
1678            included_ranges,
1679            mode: ParseMode::Combined {
1680                parent_layer_range: node.start_byte()..node.end_byte(),
1681                parent_layer_changed_ranges: changed_ranges.to_vec(),
1682            },
1683        })
1684    }
1685}
1686
1687/// Updates the given list of included `ranges`, removing any ranges that intersect
1688/// `removed_ranges`, and inserting the given `new_ranges`.
1689///
1690/// Returns a new vector of ranges, and the range of the vector that was changed,
1691/// from the previous `ranges` vector.
1692pub(crate) fn splice_included_ranges(
1693    mut ranges: Vec<tree_sitter::Range>,
1694    removed_ranges: &[Range<usize>],
1695    new_ranges: &[tree_sitter::Range],
1696) -> (Vec<tree_sitter::Range>, Range<usize>) {
1697    let mut removed_ranges = removed_ranges.iter().cloned().peekable();
1698    let mut new_ranges = new_ranges.iter().cloned().peekable();
1699    let mut ranges_ix = 0;
1700    let mut changed_portion: Option<Range<usize>> = None;
1701    loop {
1702        let next_new_range = new_ranges.peek();
1703        let next_removed_range = removed_ranges.peek();
1704
1705        let (remove, insert) = match (next_removed_range, next_new_range) {
1706            (None, None) => break,
1707            (Some(_), None) => (removed_ranges.next().unwrap(), None),
1708            (Some(next_removed_range), Some(next_new_range)) => {
1709                if next_removed_range.end < next_new_range.start_byte {
1710                    (removed_ranges.next().unwrap(), None)
1711                } else {
1712                    let mut start = next_new_range.start_byte;
1713                    let mut end = next_new_range.end_byte;
1714
1715                    while let Some(next_removed_range) = removed_ranges.peek() {
1716                        if next_removed_range.start > next_new_range.end_byte {
1717                            break;
1718                        }
1719                        let next_removed_range = removed_ranges.next().unwrap();
1720                        start = cmp::min(start, next_removed_range.start);
1721                        end = cmp::max(end, next_removed_range.end);
1722                    }
1723
1724                    (start..end, Some(new_ranges.next().unwrap()))
1725                }
1726            }
1727            (None, Some(next_new_range)) => (
1728                next_new_range.start_byte..next_new_range.end_byte,
1729                Some(new_ranges.next().unwrap()),
1730            ),
1731        };
1732
1733        let mut start_ix = ranges_ix
1734            + match ranges[ranges_ix..].binary_search_by_key(&remove.start, |r| r.end_byte) {
1735                Ok(ix) => ix,
1736                Err(ix) => ix,
1737            };
1738        let mut end_ix = ranges_ix
1739            + match ranges[ranges_ix..].binary_search_by_key(&remove.end, |r| r.start_byte) {
1740                Ok(ix) => ix + 1,
1741                Err(ix) => ix,
1742            };
1743
1744        // If there are empty ranges, then there may be multiple ranges with the same
1745        // start or end. Expand the splice to include any adjacent ranges that touch
1746        // the changed range.
1747        while start_ix > 0 {
1748            if ranges[start_ix - 1].end_byte == remove.start {
1749                start_ix -= 1;
1750            } else {
1751                break;
1752            }
1753        }
1754        while let Some(range) = ranges.get(end_ix) {
1755            if range.start_byte == remove.end {
1756                end_ix += 1;
1757            } else {
1758                break;
1759            }
1760        }
1761        let changed_start = changed_portion
1762            .as_ref()
1763            .map_or(usize::MAX, |range| range.start)
1764            .min(start_ix);
1765        let changed_end =
1766            changed_portion
1767                .as_ref()
1768                .map_or(0, |range| range.end)
1769                .max(if insert.is_some() {
1770                    start_ix + 1
1771                } else {
1772                    start_ix
1773                });
1774        changed_portion = Some(changed_start..changed_end);
1775
1776        ranges.splice(start_ix..end_ix, insert);
1777        ranges_ix = start_ix;
1778    }
1779
1780    (ranges, changed_portion.unwrap_or(0..0))
1781}
1782
1783/// Ensure there are newline ranges in between content range that appear on
1784/// different lines. For performance, only iterate through the given range of
1785/// indices. All of the ranges in the array are relative to a given start byte
1786/// and point.
1787#[ztracing::instrument(skip_all)]
1788fn insert_newlines_between_ranges(
1789    indices: Range<usize>,
1790    ranges: &mut Vec<tree_sitter::Range>,
1791    text: &text::BufferSnapshot,
1792    start_byte: usize,
1793    start_point: Point,
1794) {
1795    let mut ix = indices.end + 1;
1796    while ix > indices.start {
1797        ix -= 1;
1798        if 0 == ix || ix == ranges.len() {
1799            continue;
1800        }
1801
1802        let range_b = ranges[ix];
1803        let range_a = &mut ranges[ix - 1];
1804        if range_a.end_point.column == 0 {
1805            continue;
1806        }
1807
1808        if range_a.end_point.row < range_b.start_point.row {
1809            let end_point = start_point + Point::from_ts_point(range_a.end_point);
1810            let line_end = Point::new(end_point.row, text.line_len(end_point.row));
1811            if end_point.column >= line_end.column {
1812                range_a.end_byte += 1;
1813                range_a.end_point.row += 1;
1814                range_a.end_point.column = 0;
1815            } else {
1816                let newline_offset = text.point_to_offset(line_end);
1817                ranges.insert(
1818                    ix,
1819                    tree_sitter::Range {
1820                        start_byte: newline_offset - start_byte,
1821                        end_byte: newline_offset - start_byte + 1,
1822                        start_point: (line_end - start_point).to_ts_point(),
1823                        end_point: ((line_end - start_point) + Point::new(1, 0)).to_ts_point(),
1824                    },
1825                )
1826            }
1827        }
1828    }
1829}
1830
1831impl OwnedSyntaxLayer {
1832    /// Returns the root syntax node for this layer.
1833    pub fn node(&self) -> Node<'_> {
1834        self.tree
1835            .root_node_with_offset(self.offset.0, self.offset.1)
1836    }
1837}
1838
1839impl<'a> SyntaxLayer<'a> {
1840    /// Returns an owned version of this layer.
1841    pub fn to_owned(&self) -> OwnedSyntaxLayer {
1842        OwnedSyntaxLayer {
1843            tree: self.tree.clone(),
1844            offset: self.offset,
1845            language: self.language.clone(),
1846        }
1847    }
1848
1849    /// Returns the root node for this layer.
1850    pub fn node(&self) -> Node<'a> {
1851        self.tree
1852            .root_node_with_offset(self.offset.0, self.offset.1)
1853    }
1854
1855    pub(crate) fn override_id(&self, offset: usize, text: &text::BufferSnapshot) -> Option<u32> {
1856        let text = TextProvider(text.as_rope());
1857        let config = self.language.grammar.as_ref()?.override_config.as_ref()?;
1858
1859        let mut query_cursor = QueryCursorHandle::new();
1860        query_cursor.set_byte_range(offset.saturating_sub(1)..offset.saturating_add(1));
1861        query_cursor.set_containing_byte_range(
1862            offset.saturating_sub(MAX_BYTES_TO_QUERY / 2)
1863                ..offset.saturating_add(MAX_BYTES_TO_QUERY / 2),
1864        );
1865
1866        let mut smallest_match: Option<(u32, Range<usize>)> = None;
1867        let mut matches = query_cursor.matches(&config.query, self.node(), text);
1868        while let Some(mat) = matches.next() {
1869            for capture in mat.captures {
1870                let Some(override_entry) = config.values.get(&capture.index) else {
1871                    continue;
1872                };
1873
1874                let range = capture.node.byte_range();
1875                if override_entry.range_is_inclusive {
1876                    if offset < range.start || offset > range.end {
1877                        continue;
1878                    }
1879                } else if offset <= range.start || offset >= range.end {
1880                    continue;
1881                }
1882
1883                if let Some((_, smallest_range)) = &smallest_match {
1884                    if range.len() < smallest_range.len() {
1885                        smallest_match = Some((capture.index, range))
1886                    }
1887                    continue;
1888                }
1889
1890                smallest_match = Some((capture.index, range));
1891            }
1892        }
1893
1894        smallest_match.map(|(index, _)| index)
1895    }
1896}
1897
1898impl std::ops::Deref for SyntaxMap {
1899    type Target = SyntaxSnapshot;
1900
1901    fn deref(&self) -> &Self::Target {
1902        &self.snapshot
1903    }
1904}
1905
1906impl PartialEq for ParseStep {
1907    fn eq(&self, _: &Self) -> bool {
1908        false
1909    }
1910}
1911
1912impl Eq for ParseStep {}
1913
1914impl PartialOrd for ParseStep {
1915    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1916        Some(self.cmp(other))
1917    }
1918}
1919
1920impl Ord for ParseStep {
1921    fn cmp(&self, other: &Self) -> Ordering {
1922        let range_a = self.range();
1923        let range_b = other.range();
1924        Ord::cmp(&other.depth, &self.depth)
1925            .then_with(|| Ord::cmp(&range_b.start, &range_a.start))
1926            .then_with(|| Ord::cmp(&range_a.end, &range_b.end))
1927            .then_with(|| other.language.id().cmp(&self.language.id()))
1928    }
1929}
1930
1931impl ParseStep {
1932    fn range(&self) -> Range<usize> {
1933        if let ParseMode::Combined {
1934            parent_layer_range, ..
1935        } = &self.mode
1936        {
1937            parent_layer_range.clone()
1938        } else {
1939            let start = self.included_ranges.first().map_or(0, |r| r.start_byte);
1940            let end = self.included_ranges.last().map_or(0, |r| r.end_byte);
1941            start..end
1942        }
1943    }
1944}
1945
1946impl ChangedRegion {
1947    fn cmp(&self, other: &Self, buffer: &BufferSnapshot) -> Ordering {
1948        let range_a = &self.range;
1949        let range_b = &other.range;
1950        Ord::cmp(&self.depth, &other.depth)
1951            .then_with(|| range_a.start.cmp(&range_b.start, buffer))
1952            .then_with(|| range_b.end.cmp(&range_a.end, buffer))
1953    }
1954}
1955
1956impl ChangeRegionSet {
1957    fn start_position(&self, buffer_id: BufferId) -> ChangeStartPosition {
1958        self.0.first().map_or(
1959            ChangeStartPosition {
1960                depth: usize::MAX,
1961                position: Anchor::max_for_buffer(buffer_id),
1962            },
1963            |region| ChangeStartPosition {
1964                depth: region.depth,
1965                position: region.range.start,
1966            },
1967        )
1968    }
1969
1970    fn intersects(&self, layer: &SyntaxLayerEntry, text: &BufferSnapshot) -> bool {
1971        for region in &self.0 {
1972            if region.depth < layer.depth {
1973                continue;
1974            }
1975            if region.depth > layer.depth {
1976                break;
1977            }
1978            if region.range.end.cmp(&layer.range.start, text).is_le() {
1979                continue;
1980            }
1981            if region.range.start.cmp(&layer.range.end, text).is_ge() {
1982                break;
1983            }
1984            return true;
1985        }
1986        false
1987    }
1988
1989    fn insert(&mut self, region: ChangedRegion, text: &BufferSnapshot) {
1990        if let Err(ix) = self.0.binary_search_by(|probe| probe.cmp(&region, text)) {
1991            self.0.insert(ix, region);
1992        }
1993    }
1994
1995    fn prune(&mut self, summary: SyntaxLayerSummary, text: &BufferSnapshot) -> bool {
1996        let prev_len = self.0.len();
1997        self.0.retain(|region| {
1998            region.depth > summary.max_depth
1999                || (region.depth == summary.max_depth
2000                    && region
2001                        .range
2002                        .end
2003                        .cmp(&summary.last_layer_range.start, text)
2004                        .is_gt())
2005        });
2006        self.0.len() < prev_len
2007    }
2008}
2009
2010impl sum_tree::Summary for SyntaxLayerSummary {
2011    type Context<'a> = &'a BufferSnapshot;
2012
2013    fn zero(buffer: &BufferSnapshot) -> Self {
2014        Self {
2015            max_depth: 0,
2016            min_depth: 0,
2017            range: Anchor::max_for_buffer(buffer.remote_id())
2018                ..Anchor::min_for_buffer(buffer.remote_id()),
2019            last_layer_range: Anchor::min_for_buffer(buffer.remote_id())
2020                ..Anchor::max_for_buffer(buffer.remote_id()),
2021            last_layer_language: None,
2022            contains_unknown_injections: false,
2023        }
2024    }
2025
2026    fn add_summary(&mut self, other: &Self, buffer: Self::Context<'_>) {
2027        if other.max_depth > self.max_depth {
2028            self.max_depth = other.max_depth;
2029            self.range = other.range.clone();
2030        } else {
2031            if self.range.start.is_max() && self.range.end.is_max() {
2032                self.range.start = other.range.start;
2033            }
2034            if other.range.end.cmp(&self.range.end, buffer).is_gt() {
2035                self.range.end = other.range.end;
2036            }
2037        }
2038        self.last_layer_range = other.last_layer_range.clone();
2039        self.last_layer_language = other.last_layer_language;
2040        self.contains_unknown_injections |= other.contains_unknown_injections;
2041    }
2042}
2043
2044impl SeekTarget<'_, SyntaxLayerSummary, SyntaxLayerSummary> for SyntaxLayerPosition {
2045    fn cmp(&self, cursor_location: &SyntaxLayerSummary, buffer: &BufferSnapshot) -> Ordering {
2046        Ord::cmp(&self.depth, &cursor_location.max_depth)
2047            .then_with(|| {
2048                self.range
2049                    .start
2050                    .cmp(&cursor_location.last_layer_range.start, buffer)
2051            })
2052            .then_with(|| {
2053                cursor_location
2054                    .last_layer_range
2055                    .end
2056                    .cmp(&self.range.end, buffer)
2057            })
2058            .then_with(|| self.language.cmp(&cursor_location.last_layer_language))
2059    }
2060}
2061
2062impl SeekTarget<'_, SyntaxLayerSummary, SyntaxLayerSummary> for ChangeStartPosition {
2063    fn cmp(&self, cursor_location: &SyntaxLayerSummary, text: &BufferSnapshot) -> Ordering {
2064        Ord::cmp(&self.depth, &cursor_location.max_depth)
2065            .then_with(|| self.position.cmp(&cursor_location.range.end, text))
2066    }
2067}
2068
2069impl SeekTarget<'_, SyntaxLayerSummary, SyntaxLayerSummary> for SyntaxLayerPositionBeforeChange {
2070    fn cmp(&self, cursor_location: &SyntaxLayerSummary, buffer: &BufferSnapshot) -> Ordering {
2071        if self.change.cmp(cursor_location, buffer).is_le() {
2072            Ordering::Less
2073        } else {
2074            self.position.cmp(cursor_location, buffer)
2075        }
2076    }
2077}
2078
2079impl sum_tree::Item for SyntaxLayerEntry {
2080    type Summary = SyntaxLayerSummary;
2081
2082    fn summary(&self, _cx: &BufferSnapshot) -> Self::Summary {
2083        SyntaxLayerSummary {
2084            min_depth: self.depth,
2085            max_depth: self.depth,
2086            range: self.range.clone(),
2087            last_layer_range: self.range.clone(),
2088            last_layer_language: self.content.language_id(),
2089            contains_unknown_injections: matches!(self.content, SyntaxLayerContent::Pending { .. }),
2090        }
2091    }
2092}
2093
2094impl std::fmt::Debug for SyntaxLayerEntry {
2095    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2096        f.debug_struct("SyntaxLayer")
2097            .field("depth", &self.depth)
2098            .field("range", &self.range)
2099            .field("tree", &self.content.tree())
2100            .finish()
2101    }
2102}
2103
2104impl<'a> tree_sitter::TextProvider<&'a [u8]> for TextProvider<'a> {
2105    type I = ByteChunks<'a>;
2106
2107    fn text(&mut self, node: tree_sitter::Node) -> Self::I {
2108        ByteChunks(self.0.chunks_in_range(node.byte_range()))
2109    }
2110}
2111
2112impl<'a> Iterator for ByteChunks<'a> {
2113    type Item = &'a [u8];
2114
2115    fn next(&mut self) -> Option<Self::Item> {
2116        self.0.next().map(str::as_bytes)
2117    }
2118}
2119
2120impl QueryCursorHandle {
2121    pub fn new() -> Self {
2122        let mut cursor = QUERY_CURSORS.lock().pop().unwrap_or_default();
2123        cursor.set_match_limit(64);
2124        QueryCursorHandle(Some(cursor))
2125    }
2126}
2127
2128impl Deref for QueryCursorHandle {
2129    type Target = QueryCursor;
2130
2131    fn deref(&self) -> &Self::Target {
2132        self.0.as_ref().unwrap()
2133    }
2134}
2135
2136impl DerefMut for QueryCursorHandle {
2137    fn deref_mut(&mut self) -> &mut Self::Target {
2138        self.0.as_mut().unwrap()
2139    }
2140}
2141
2142impl Drop for QueryCursorHandle {
2143    fn drop(&mut self) {
2144        let mut cursor = self.0.take().unwrap();
2145        cursor.set_byte_range(0..usize::MAX);
2146        cursor.set_point_range(Point::zero().to_ts_point()..Point::MAX.to_ts_point());
2147        cursor.set_containing_byte_range(0..usize::MAX);
2148        cursor.set_containing_point_range(Point::zero().to_ts_point()..Point::MAX.to_ts_point());
2149        QUERY_CURSORS.lock().push(cursor)
2150    }
2151}
2152
2153pub trait ToTreeSitterPoint {
2154    fn to_ts_point(self) -> tree_sitter::Point;
2155    fn from_ts_point(point: tree_sitter::Point) -> Self;
2156}
2157
2158impl ToTreeSitterPoint for Point {
2159    fn to_ts_point(self) -> tree_sitter::Point {
2160        tree_sitter::Point::new(self.row as usize, self.column as usize)
2161    }
2162
2163    fn from_ts_point(point: tree_sitter::Point) -> Self {
2164        Point::new(point.row as u32, point.column as u32)
2165    }
2166}
2167
2168struct LogIncludedRanges<'a>(&'a [tree_sitter::Range]);
2169struct LogPoint(Point);
2170struct LogAnchorRange<'a>(&'a Range<Anchor>, &'a text::BufferSnapshot);
2171struct LogOffsetRanges<'a>(&'a [Range<usize>], &'a text::BufferSnapshot);
2172struct LogChangedRegions<'a>(&'a ChangeRegionSet, &'a text::BufferSnapshot);
2173
2174impl fmt::Debug for LogIncludedRanges<'_> {
2175    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2176        f.debug_list()
2177            .entries(self.0.iter().map(|range| {
2178                let start = range.start_point;
2179                let end = range.end_point;
2180                (start.row, start.column)..(end.row, end.column)
2181            }))
2182            .finish()
2183    }
2184}
2185
2186impl fmt::Debug for LogAnchorRange<'_> {
2187    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2188        let range = self.0.to_point(self.1);
2189        (LogPoint(range.start)..LogPoint(range.end)).fmt(f)
2190    }
2191}
2192
2193impl fmt::Debug for LogOffsetRanges<'_> {
2194    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2195        f.debug_list()
2196            .entries(self.0.iter().map(|range| {
2197                LogPoint(range.start.to_point(self.1))..LogPoint(range.end.to_point(self.1))
2198            }))
2199            .finish()
2200    }
2201}
2202
2203impl fmt::Debug for LogChangedRegions<'_> {
2204    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2205        f.debug_list()
2206            .entries(
2207                self.0
2208                    .0
2209                    .iter()
2210                    .map(|region| LogAnchorRange(&region.range, self.1)),
2211            )
2212            .finish()
2213    }
2214}
2215
2216impl fmt::Debug for LogPoint {
2217    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2218        (self.0.row, self.0.column).fmt(f)
2219    }
2220}
2221
Served at tenant.openagents/omega Member data and write actions are omitted.