1use crate::{Grammar, InjectionConfig, Language, LanguageRegistry};
2use collections::HashMap;
3use lazy_static::lazy_static;
4use parking_lot::Mutex;
5use std::{
6 borrow::Cow,
7 cell::RefCell,
8 cmp::{self, Ordering, Reverse},
9 collections::BinaryHeap,
10 iter,
11 ops::{Deref, DerefMut, Range},
12 sync::Arc,
13};
14use sum_tree::{Bias, SeekTarget, SumTree};
15use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint};
16use tree_sitter::{
17 Node, Parser, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree,
18};
19
20thread_local! {
21 static PARSER: RefCell<Parser> = RefCell::new(Parser::new());
22}
23
24lazy_static! {
25 static ref QUERY_CURSORS: Mutex<Vec<QueryCursor>> = Default::default();
26}
27
28#[derive(Default)]
29pub struct SyntaxMap {
30 snapshot: SyntaxSnapshot,
31 language_registry: Option<Arc<LanguageRegistry>>,
32}
33
34#[derive(Clone, Default)]
35pub struct SyntaxSnapshot {
36 layers: SumTree<SyntaxLayer>,
37 parsed_version: clock::Global,
38 interpolated_version: clock::Global,
39 language_registry_version: usize,
40}
41
42#[derive(Default)]
43pub struct SyntaxMapCaptures<'a> {
44 layers: Vec<SyntaxMapCapturesLayer<'a>>,
45 active_layer_count: usize,
46 grammars: Vec<&'a Grammar>,
47}
48
49#[derive(Default)]
50pub struct SyntaxMapMatches<'a> {
51 layers: Vec<SyntaxMapMatchesLayer<'a>>,
52 active_layer_count: usize,
53 grammars: Vec<&'a Grammar>,
54}
55
56#[derive(Debug)]
57pub struct SyntaxMapCapture<'a> {
58 pub depth: usize,
59 pub node: Node<'a>,
60 pub index: u32,
61 pub grammar_index: usize,
62}
63
64#[derive(Debug)]
65pub struct SyntaxMapMatch<'a> {
66 pub depth: usize,
67 pub pattern_index: usize,
68 pub captures: &'a [QueryCapture<'a>],
69 pub grammar_index: usize,
70}
71
72struct SyntaxMapCapturesLayer<'a> {
73 depth: usize,
74 captures: QueryCaptures<'a, 'a, TextProvider<'a>>,
75 next_capture: Option<QueryCapture<'a>>,
76 grammar_index: usize,
77 _query_cursor: QueryCursorHandle,
78}
79
80struct SyntaxMapMatchesLayer<'a> {
81 depth: usize,
82 next_pattern_index: usize,
83 next_captures: Vec<QueryCapture<'a>>,
84 has_next: bool,
85 matches: QueryMatches<'a, 'a, TextProvider<'a>>,
86 grammar_index: usize,
87 _query_cursor: QueryCursorHandle,
88}
89
90#[derive(Clone)]
91struct SyntaxLayer {
92 depth: usize,
93 range: Range<Anchor>,
94 content: SyntaxLayerContent,
95}
96
97#[derive(Clone)]
98enum SyntaxLayerContent {
99 Parsed {
100 tree: tree_sitter::Tree,
101 language: Arc<Language>,
102 },
103 Pending {
104 language_name: Arc<str>,
105 },
106}
107
108impl SyntaxLayerContent {
109 fn language_id(&self) -> Option<usize> {
110 match self {
111 SyntaxLayerContent::Parsed { language, .. } => language.id(),
112 SyntaxLayerContent::Pending { .. } => None,
113 }
114 }
115
116 fn tree(&self) -> Option<&Tree> {
117 match self {
118 SyntaxLayerContent::Parsed { tree, .. } => Some(tree),
119 SyntaxLayerContent::Pending { .. } => None,
120 }
121 }
122}
123
124#[derive(Debug)]
125pub struct SyntaxLayerInfo<'a> {
126 pub depth: usize,
127 pub node: Node<'a>,
128 pub language: &'a Arc<Language>,
129}
130
131#[derive(Debug, Clone)]
132struct SyntaxLayerSummary {
133 min_depth: usize,
134 max_depth: usize,
135 range: Range<Anchor>,
136 last_layer_range: Range<Anchor>,
137 last_layer_language: Option<usize>,
138 contains_unknown_injections: bool,
139}
140
141#[derive(Clone, Debug)]
142struct SyntaxLayerPosition {
143 depth: usize,
144 range: Range<Anchor>,
145 language: Option<usize>,
146}
147
148#[derive(Clone, Debug)]
149struct ChangeStartPosition {
150 depth: usize,
151 position: Anchor,
152}
153
154#[derive(Clone, Debug)]
155struct SyntaxLayerPositionBeforeChange {
156 position: SyntaxLayerPosition,
157 change: ChangeStartPosition,
158}
159
160struct ParseStep {
161 depth: usize,
162 language: ParseStepLanguage,
163 range: Range<Anchor>,
164 included_ranges: Vec<tree_sitter::Range>,
165 mode: ParseMode,
166}
167
168enum ParseStepLanguage {
169 Loaded { language: Arc<Language> },
170 Pending { name: Arc<str> },
171}
172
173impl ParseStepLanguage {
174 fn id(&self) -> Option<usize> {
175 match self {
176 ParseStepLanguage::Loaded { language } => language.id(),
177 ParseStepLanguage::Pending { .. } => None,
178 }
179 }
180}
181
182enum ParseMode {
183 Single,
184 Combined {
185 parent_layer_range: Range<usize>,
186 parent_layer_changed_ranges: Vec<Range<usize>>,
187 },
188}
189
190#[derive(Debug, PartialEq, Eq)]
191struct ChangedRegion {
192 depth: usize,
193 range: Range<Anchor>,
194}
195
196#[derive(Default)]
197struct ChangeRegionSet(Vec<ChangedRegion>);
198
199struct TextProvider<'a>(&'a Rope);
200
201struct ByteChunks<'a>(text::Chunks<'a>);
202
203struct QueryCursorHandle(Option<QueryCursor>);
204
205impl SyntaxMap {
206 pub fn new() -> Self {
207 Self::default()
208 }
209
210 pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) {
211 self.language_registry = Some(registry);
212 }
213
214 pub fn snapshot(&self) -> SyntaxSnapshot {
215 self.snapshot.clone()
216 }
217
218 pub fn language_registry(&self) -> Option<Arc<LanguageRegistry>> {
219 self.language_registry.clone()
220 }
221
222 pub fn interpolate(&mut self, text: &BufferSnapshot) {
223 self.snapshot.interpolate(text);
224 }
225
226 #[cfg(test)]
227 pub fn reparse(&mut self, language: Arc<Language>, text: &BufferSnapshot) {
228 self.snapshot
229 .reparse(text, self.language_registry.clone(), language);
230 }
231
232 pub fn did_parse(&mut self, snapshot: SyntaxSnapshot) {
233 self.snapshot = snapshot;
234 }
235
236 pub fn clear(&mut self) {
237 self.snapshot = SyntaxSnapshot::default();
238 }
239}
240
241impl SyntaxSnapshot {
242 pub fn is_empty(&self) -> bool {
243 self.layers.is_empty()
244 }
245
246 fn interpolate(&mut self, text: &BufferSnapshot) {
247 let edits = text
248 .anchored_edits_since::<(usize, Point)>(&self.interpolated_version)
249 .collect::<Vec<_>>();
250 self.interpolated_version = text.version().clone();
251
252 if edits.is_empty() {
253 return;
254 }
255
256 let mut layers = SumTree::new();
257 let mut first_edit_ix_for_depth = 0;
258 let mut prev_depth = 0;
259 let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
260 cursor.next(text);
261
262 'outer: loop {
263 let depth = cursor.end(text).max_depth;
264 if depth > prev_depth {
265 first_edit_ix_for_depth = 0;
266 prev_depth = depth;
267 }
268
269 // Preserve any layers at this depth that precede the first edit.
270 if let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) {
271 let target = ChangeStartPosition {
272 depth,
273 position: edit_range.start,
274 };
275 if target.cmp(&cursor.start(), text).is_gt() {
276 let slice = cursor.slice(&target, Bias::Left, text);
277 layers.push_tree(slice, text);
278 }
279 }
280 // If this layer follows all of the edits, then preserve it and any
281 // subsequent layers at this same depth.
282 else if cursor.item().is_some() {
283 let slice = cursor.slice(
284 &SyntaxLayerPosition {
285 depth: depth + 1,
286 range: Anchor::MIN..Anchor::MAX,
287 language: None,
288 },
289 Bias::Left,
290 text,
291 );
292 layers.push_tree(slice, text);
293 continue;
294 };
295
296 let Some(layer) = cursor.item() else { break };
297 let (start_byte, start_point) = layer.range.start.summary::<(usize, Point)>(text);
298
299 // Ignore edits that end before the start of this layer, and don't consider them
300 // for any subsequent layers at this same depth.
301 loop {
302 let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) else { continue 'outer };
303 if edit_range.end.cmp(&layer.range.start, text).is_le() {
304 first_edit_ix_for_depth += 1;
305 } else {
306 break;
307 }
308 }
309
310 let mut layer = layer.clone();
311 if let SyntaxLayerContent::Parsed { tree, .. } = &mut layer.content {
312 for (edit, edit_range) in &edits[first_edit_ix_for_depth..] {
313 // Ignore any edits that follow this layer.
314 if edit_range.start.cmp(&layer.range.end, text).is_ge() {
315 break;
316 }
317
318 // Apply any edits that intersect this layer to the layer's syntax tree.
319 let tree_edit = if edit_range.start.cmp(&layer.range.start, text).is_ge() {
320 tree_sitter::InputEdit {
321 start_byte: edit.new.start.0 - start_byte,
322 old_end_byte: edit.new.start.0 - start_byte
323 + (edit.old.end.0 - edit.old.start.0),
324 new_end_byte: edit.new.end.0 - start_byte,
325 start_position: (edit.new.start.1 - start_point).to_ts_point(),
326 old_end_position: (edit.new.start.1 - start_point
327 + (edit.old.end.1 - edit.old.start.1))
328 .to_ts_point(),
329 new_end_position: (edit.new.end.1 - start_point).to_ts_point(),
330 }
331 } else {
332 let node = tree.root_node();
333 tree_sitter::InputEdit {
334 start_byte: 0,
335 old_end_byte: node.end_byte(),
336 new_end_byte: 0,
337 start_position: Default::default(),
338 old_end_position: node.end_position(),
339 new_end_position: Default::default(),
340 }
341 };
342
343 tree.edit(&tree_edit);
344 }
345
346 debug_assert!(
347 tree.root_node().end_byte() <= text.len(),
348 "tree's size {}, is larger than text size {}",
349 tree.root_node().end_byte(),
350 text.len(),
351 );
352 }
353
354 layers.push(layer, text);
355 cursor.next(text);
356 }
357
358 layers.push_tree(cursor.suffix(&text), &text);
359 drop(cursor);
360 self.layers = layers;
361 }
362
363 pub fn reparse(
364 &mut self,
365 text: &BufferSnapshot,
366 registry: Option<Arc<LanguageRegistry>>,
367 root_language: Arc<Language>,
368 ) {
369 let edit_ranges = text
370 .edits_since::<usize>(&self.parsed_version)
371 .map(|edit| edit.new)
372 .collect::<Vec<_>>();
373 self.reparse_with_ranges(text, root_language.clone(), edit_ranges, registry.as_ref());
374
375 if let Some(registry) = registry {
376 if registry.version() != self.language_registry_version {
377 let mut resolved_injection_ranges = Vec::new();
378 let mut cursor = self
379 .layers
380 .filter::<_, ()>(|summary| summary.contains_unknown_injections);
381 cursor.next(text);
382 while let Some(layer) = cursor.item() {
383 let SyntaxLayerContent::Pending { language_name } = &layer.content else { unreachable!() };
384 if {
385 let language_registry = ®istry;
386 language_registry.language_for_name_or_extension(language_name)
387 }
388 .is_some()
389 {
390 resolved_injection_ranges.push(layer.range.to_offset(text));
391 }
392
393 cursor.next(text);
394 }
395 drop(cursor);
396
397 if !resolved_injection_ranges.is_empty() {
398 self.reparse_with_ranges(
399 text,
400 root_language,
401 resolved_injection_ranges,
402 Some(®istry),
403 );
404 }
405 self.language_registry_version = registry.version();
406 }
407 }
408 }
409
410 fn reparse_with_ranges(
411 &mut self,
412 text: &BufferSnapshot,
413 root_language: Arc<Language>,
414 invalidated_ranges: Vec<Range<usize>>,
415 registry: Option<&Arc<LanguageRegistry>>,
416 ) {
417 let max_depth = self.layers.summary().max_depth;
418 let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
419 cursor.next(&text);
420 let mut layers = SumTree::new();
421
422 let mut changed_regions = ChangeRegionSet::default();
423 let mut queue = BinaryHeap::new();
424 let mut combined_injection_ranges = HashMap::default();
425 queue.push(ParseStep {
426 depth: 0,
427 language: ParseStepLanguage::Loaded {
428 language: root_language,
429 },
430 included_ranges: vec![tree_sitter::Range {
431 start_byte: 0,
432 end_byte: text.len(),
433 start_point: Point::zero().to_ts_point(),
434 end_point: text.max_point().to_ts_point(),
435 }],
436 range: Anchor::MIN..Anchor::MAX,
437 mode: ParseMode::Single,
438 });
439
440 loop {
441 let step = queue.pop();
442 let position = if let Some(step) = &step {
443 SyntaxLayerPosition {
444 depth: step.depth,
445 range: step.range.clone(),
446 language: step.language.id(),
447 }
448 } else {
449 SyntaxLayerPosition {
450 depth: max_depth + 1,
451 range: Anchor::MAX..Anchor::MAX,
452 language: None,
453 }
454 };
455
456 let mut done = cursor.item().is_none();
457 while !done && position.cmp(&cursor.end(text), &text).is_gt() {
458 done = true;
459
460 let bounded_position = SyntaxLayerPositionBeforeChange {
461 position: position.clone(),
462 change: changed_regions.start_position(),
463 };
464 if bounded_position.cmp(&cursor.start(), &text).is_gt() {
465 let slice = cursor.slice(&bounded_position, Bias::Left, text);
466 if !slice.is_empty() {
467 layers.push_tree(slice, &text);
468 if changed_regions.prune(cursor.end(text), text) {
469 done = false;
470 }
471 }
472 }
473
474 while position.cmp(&cursor.end(text), text).is_gt() {
475 let Some(layer) = cursor.item() else { break };
476
477 if changed_regions.intersects(&layer, text) {
478 changed_regions.insert(
479 ChangedRegion {
480 depth: layer.depth + 1,
481 range: layer.range.clone(),
482 },
483 text,
484 );
485 } else {
486 layers.push(layer.clone(), text);
487 }
488
489 cursor.next(text);
490 if changed_regions.prune(cursor.end(text), text) {
491 done = false;
492 }
493 }
494 }
495
496 let Some(step) = step else { break };
497 let (step_start_byte, step_start_point) =
498 step.range.start.summary::<(usize, Point)>(text);
499 let step_end_byte = step.range.end.to_offset(text);
500
501 let mut old_layer = cursor.item();
502 if let Some(layer) = old_layer {
503 if layer.range.to_offset(text) == (step_start_byte..step_end_byte)
504 && layer.content.language_id() == step.language.id()
505 {
506 cursor.next(&text);
507 } else {
508 old_layer = None;
509 }
510 }
511
512 let content = match step.language {
513 ParseStepLanguage::Loaded { language } => {
514 let Some(grammar) = language.grammar() else { continue };
515 let tree;
516 let changed_ranges;
517 let mut included_ranges = step.included_ranges;
518 if let Some(SyntaxLayerContent::Parsed { tree: old_tree, .. }) =
519 old_layer.map(|layer| &layer.content)
520 {
521 if let ParseMode::Combined {
522 parent_layer_changed_ranges,
523 ..
524 } = step.mode
525 {
526 included_ranges = splice_included_ranges(
527 old_tree.included_ranges(),
528 &parent_layer_changed_ranges,
529 &included_ranges,
530 );
531 }
532
533 tree = parse_text(
534 grammar,
535 text.as_rope(),
536 step_start_byte,
537 step_start_point,
538 included_ranges,
539 Some(old_tree.clone()),
540 );
541 changed_ranges = join_ranges(
542 invalidated_ranges.iter().cloned().filter(|range| {
543 range.start <= step_end_byte && range.end >= step_start_byte
544 }),
545 old_tree.changed_ranges(&tree).map(|r| {
546 step_start_byte + r.start_byte..step_start_byte + r.end_byte
547 }),
548 );
549 } else {
550 tree = parse_text(
551 grammar,
552 text.as_rope(),
553 step_start_byte,
554 step_start_point,
555 included_ranges,
556 None,
557 );
558 changed_ranges = vec![step_start_byte..step_end_byte];
559 }
560
561 if let (Some((config, registry)), false) = (
562 grammar.injection_config.as_ref().zip(registry.as_ref()),
563 changed_ranges.is_empty(),
564 ) {
565 for range in &changed_ranges {
566 changed_regions.insert(
567 ChangedRegion {
568 depth: step.depth + 1,
569 range: text.anchor_before(range.start)
570 ..text.anchor_after(range.end),
571 },
572 text,
573 );
574 }
575 get_injections(
576 config,
577 text,
578 tree.root_node_with_offset(
579 step_start_byte,
580 step_start_point.to_ts_point(),
581 ),
582 registry,
583 step.depth + 1,
584 &changed_ranges,
585 &mut combined_injection_ranges,
586 &mut queue,
587 );
588 }
589
590 SyntaxLayerContent::Parsed { tree, language }
591 }
592 ParseStepLanguage::Pending { name } => SyntaxLayerContent::Pending {
593 language_name: name,
594 },
595 };
596
597 layers.push(
598 SyntaxLayer {
599 depth: step.depth,
600 range: step.range,
601 content,
602 },
603 &text,
604 );
605 }
606
607 drop(cursor);
608 self.layers = layers;
609 self.interpolated_version = text.version.clone();
610 self.parsed_version = text.version.clone();
611 }
612
613 pub fn single_tree_captures<'a>(
614 range: Range<usize>,
615 text: &'a Rope,
616 tree: &'a Tree,
617 language: &'a Arc<Language>,
618 query: fn(&Grammar) -> Option<&Query>,
619 ) -> SyntaxMapCaptures<'a> {
620 SyntaxMapCaptures::new(
621 range.clone(),
622 text,
623 [SyntaxLayerInfo {
624 language,
625 depth: 0,
626 node: tree.root_node(),
627 }]
628 .into_iter(),
629 query,
630 )
631 }
632
633 pub fn captures<'a>(
634 &'a self,
635 range: Range<usize>,
636 buffer: &'a BufferSnapshot,
637 query: fn(&Grammar) -> Option<&Query>,
638 ) -> SyntaxMapCaptures {
639 SyntaxMapCaptures::new(
640 range.clone(),
641 buffer.as_rope(),
642 self.layers_for_range(range, buffer).into_iter(),
643 query,
644 )
645 }
646
647 pub fn matches<'a>(
648 &'a self,
649 range: Range<usize>,
650 buffer: &'a BufferSnapshot,
651 query: fn(&Grammar) -> Option<&Query>,
652 ) -> SyntaxMapMatches {
653 SyntaxMapMatches::new(
654 range.clone(),
655 buffer.as_rope(),
656 self.layers_for_range(range, buffer).into_iter(),
657 query,
658 )
659 }
660
661 #[cfg(test)]
662 pub fn layers<'a>(&'a self, buffer: &'a BufferSnapshot) -> Vec<SyntaxLayerInfo> {
663 self.layers_for_range(0..buffer.len(), buffer).collect()
664 }
665
666 pub fn layers_for_range<'a, T: ToOffset>(
667 &'a self,
668 range: Range<T>,
669 buffer: &'a BufferSnapshot,
670 ) -> impl 'a + Iterator<Item = SyntaxLayerInfo> {
671 let start = buffer.anchor_before(range.start.to_offset(buffer));
672 let end = buffer.anchor_after(range.end.to_offset(buffer));
673
674 let mut cursor = self.layers.filter::<_, ()>(move |summary| {
675 if summary.max_depth > summary.min_depth {
676 true
677 } else {
678 let is_before_start = summary.range.end.cmp(&start, buffer).is_lt();
679 let is_after_end = summary.range.start.cmp(&end, buffer).is_gt();
680 !is_before_start && !is_after_end
681 }
682 });
683
684 cursor.next(buffer);
685 iter::from_fn(move || {
686 while let Some(layer) = cursor.item() {
687 if let SyntaxLayerContent::Parsed { tree, language } = &layer.content {
688 let info = SyntaxLayerInfo {
689 language,
690 depth: layer.depth,
691 node: tree.root_node_with_offset(
692 layer.range.start.to_offset(buffer),
693 layer.range.start.to_point(buffer).to_ts_point(),
694 ),
695 };
696 cursor.next(buffer);
697 return Some(info);
698 } else {
699 cursor.next(buffer);
700 }
701 }
702 None
703 })
704 }
705
706 pub fn contains_unknown_injections(&self) -> bool {
707 self.layers.summary().contains_unknown_injections
708 }
709
710 pub fn language_registry_version(&self) -> usize {
711 self.language_registry_version
712 }
713}
714
715impl<'a> SyntaxMapCaptures<'a> {
716 fn new(
717 range: Range<usize>,
718 text: &'a Rope,
719 layers: impl Iterator<Item = SyntaxLayerInfo<'a>>,
720 query: fn(&Grammar) -> Option<&Query>,
721 ) -> Self {
722 let mut result = Self {
723 layers: Vec::new(),
724 grammars: Vec::new(),
725 active_layer_count: 0,
726 };
727 for SyntaxLayerInfo {
728 language,
729 depth,
730 node,
731 } in layers
732 {
733 let grammar = match &language.grammar {
734 Some(grammer) => grammer,
735 None => continue,
736 };
737 let query = match query(&grammar) {
738 Some(query) => query,
739 None => continue,
740 };
741
742 let mut query_cursor = QueryCursorHandle::new();
743
744 // TODO - add a Tree-sitter API to remove the need for this.
745 let cursor = unsafe {
746 std::mem::transmute::<_, &'static mut QueryCursor>(query_cursor.deref_mut())
747 };
748
749 cursor.set_byte_range(range.clone());
750 let captures = cursor.captures(query, node, TextProvider(text));
751 let grammar_index = result
752 .grammars
753 .iter()
754 .position(|g| g.id == grammar.id())
755 .unwrap_or_else(|| {
756 result.grammars.push(grammar);
757 result.grammars.len() - 1
758 });
759 let mut layer = SyntaxMapCapturesLayer {
760 depth,
761 grammar_index,
762 next_capture: None,
763 captures,
764 _query_cursor: query_cursor,
765 };
766
767 layer.advance();
768 if layer.next_capture.is_some() {
769 let key = layer.sort_key();
770 let ix = match result.layers[..result.active_layer_count]
771 .binary_search_by_key(&key, |layer| layer.sort_key())
772 {
773 Ok(ix) | Err(ix) => ix,
774 };
775 result.layers.insert(ix, layer);
776 result.active_layer_count += 1;
777 } else {
778 result.layers.push(layer);
779 }
780 }
781
782 result
783 }
784
785 pub fn grammars(&self) -> &[&'a Grammar] {
786 &self.grammars
787 }
788
789 pub fn peek(&self) -> Option<SyntaxMapCapture<'a>> {
790 let layer = self.layers[..self.active_layer_count].first()?;
791 let capture = layer.next_capture?;
792 Some(SyntaxMapCapture {
793 depth: layer.depth,
794 grammar_index: layer.grammar_index,
795 index: capture.index,
796 node: capture.node,
797 })
798 }
799
800 pub fn advance(&mut self) -> bool {
801 let layer = if let Some(layer) = self.layers[..self.active_layer_count].first_mut() {
802 layer
803 } else {
804 return false;
805 };
806
807 layer.advance();
808 if layer.next_capture.is_some() {
809 let key = layer.sort_key();
810 let i = 1 + self.layers[1..self.active_layer_count]
811 .iter()
812 .position(|later_layer| key < later_layer.sort_key())
813 .unwrap_or(self.active_layer_count - 1);
814 self.layers[0..i].rotate_left(1);
815 } else {
816 self.layers[0..self.active_layer_count].rotate_left(1);
817 self.active_layer_count -= 1;
818 }
819
820 true
821 }
822
823 pub fn set_byte_range(&mut self, range: Range<usize>) {
824 for layer in &mut self.layers {
825 layer.captures.set_byte_range(range.clone());
826 if let Some(capture) = &layer.next_capture {
827 if capture.node.end_byte() > range.start {
828 continue;
829 }
830 }
831 layer.advance();
832 }
833 self.layers.sort_unstable_by_key(|layer| layer.sort_key());
834 self.active_layer_count = self
835 .layers
836 .iter()
837 .position(|layer| layer.next_capture.is_none())
838 .unwrap_or(self.layers.len());
839 }
840}
841
842impl<'a> SyntaxMapMatches<'a> {
843 fn new(
844 range: Range<usize>,
845 text: &'a Rope,
846 layers: impl Iterator<Item = SyntaxLayerInfo<'a>>,
847 query: fn(&Grammar) -> Option<&Query>,
848 ) -> Self {
849 let mut result = Self::default();
850 for SyntaxLayerInfo {
851 language,
852 depth,
853 node,
854 } in layers
855 {
856 let grammar = match &language.grammar {
857 Some(grammer) => grammer,
858 None => continue,
859 };
860 let query = match query(&grammar) {
861 Some(query) => query,
862 None => continue,
863 };
864
865 let mut query_cursor = QueryCursorHandle::new();
866
867 // TODO - add a Tree-sitter API to remove the need for this.
868 let cursor = unsafe {
869 std::mem::transmute::<_, &'static mut QueryCursor>(query_cursor.deref_mut())
870 };
871
872 cursor.set_byte_range(range.clone());
873 let matches = cursor.matches(query, node, TextProvider(text));
874 let grammar_index = result
875 .grammars
876 .iter()
877 .position(|g| g.id == grammar.id())
878 .unwrap_or_else(|| {
879 result.grammars.push(grammar);
880 result.grammars.len() - 1
881 });
882 let mut layer = SyntaxMapMatchesLayer {
883 depth,
884 grammar_index,
885 matches,
886 next_pattern_index: 0,
887 next_captures: Vec::new(),
888 has_next: false,
889 _query_cursor: query_cursor,
890 };
891
892 layer.advance();
893 if layer.has_next {
894 let key = layer.sort_key();
895 let ix = match result.layers[..result.active_layer_count]
896 .binary_search_by_key(&key, |layer| layer.sort_key())
897 {
898 Ok(ix) | Err(ix) => ix,
899 };
900 result.layers.insert(ix, layer);
901 result.active_layer_count += 1;
902 } else {
903 result.layers.push(layer);
904 }
905 }
906 result
907 }
908
909 pub fn grammars(&self) -> &[&'a Grammar] {
910 &self.grammars
911 }
912
913 pub fn peek(&self) -> Option<SyntaxMapMatch> {
914 let layer = self.layers.first()?;
915 if !layer.has_next {
916 return None;
917 }
918 Some(SyntaxMapMatch {
919 depth: layer.depth,
920 grammar_index: layer.grammar_index,
921 pattern_index: layer.next_pattern_index,
922 captures: &layer.next_captures,
923 })
924 }
925
926 pub fn advance(&mut self) -> bool {
927 let layer = if let Some(layer) = self.layers.first_mut() {
928 layer
929 } else {
930 return false;
931 };
932
933 layer.advance();
934 if layer.has_next {
935 let key = layer.sort_key();
936 let i = 1 + self.layers[1..self.active_layer_count]
937 .iter()
938 .position(|later_layer| key < later_layer.sort_key())
939 .unwrap_or(self.active_layer_count - 1);
940 self.layers[0..i].rotate_left(1);
941 } else {
942 self.layers[0..self.active_layer_count].rotate_left(1);
943 self.active_layer_count -= 1;
944 }
945
946 true
947 }
948}
949
950impl<'a> SyntaxMapCapturesLayer<'a> {
951 fn advance(&mut self) {
952 self.next_capture = self.captures.next().map(|(mat, ix)| mat.captures[ix]);
953 }
954
955 fn sort_key(&self) -> (usize, Reverse<usize>, usize) {
956 if let Some(capture) = &self.next_capture {
957 let range = capture.node.byte_range();
958 (range.start, Reverse(range.end), self.depth)
959 } else {
960 (usize::MAX, Reverse(0), usize::MAX)
961 }
962 }
963}
964
965impl<'a> SyntaxMapMatchesLayer<'a> {
966 fn advance(&mut self) {
967 if let Some(mat) = self.matches.next() {
968 self.next_captures.clear();
969 self.next_captures.extend_from_slice(&mat.captures);
970 self.next_pattern_index = mat.pattern_index;
971 self.has_next = true;
972 } else {
973 self.has_next = false;
974 }
975 }
976
977 fn sort_key(&self) -> (usize, Reverse<usize>, usize) {
978 if self.has_next {
979 let captures = &self.next_captures;
980 if let Some((first, last)) = captures.first().zip(captures.last()) {
981 return (
982 first.node.start_byte(),
983 Reverse(last.node.end_byte()),
984 self.depth,
985 );
986 }
987 }
988 (usize::MAX, Reverse(0), usize::MAX)
989 }
990}
991
992impl<'a> Iterator for SyntaxMapCaptures<'a> {
993 type Item = SyntaxMapCapture<'a>;
994
995 fn next(&mut self) -> Option<Self::Item> {
996 let result = self.peek();
997 self.advance();
998 result
999 }
1000}
1001
1002fn join_ranges(
1003 a: impl Iterator<Item = Range<usize>>,
1004 b: impl Iterator<Item = Range<usize>>,
1005) -> Vec<Range<usize>> {
1006 let mut result = Vec::<Range<usize>>::new();
1007 let mut a = a.peekable();
1008 let mut b = b.peekable();
1009 loop {
1010 let range = match (a.peek(), b.peek()) {
1011 (Some(range_a), Some(range_b)) => {
1012 if range_a.start < range_b.start {
1013 a.next().unwrap()
1014 } else {
1015 b.next().unwrap()
1016 }
1017 }
1018 (None, Some(_)) => b.next().unwrap(),
1019 (Some(_), None) => a.next().unwrap(),
1020 (None, None) => break,
1021 };
1022
1023 if let Some(last) = result.last_mut() {
1024 if range.start <= last.end {
1025 last.end = last.end.max(range.end);
1026 continue;
1027 }
1028 }
1029 result.push(range);
1030 }
1031 result
1032}
1033
1034fn parse_text(
1035 grammar: &Grammar,
1036 text: &Rope,
1037 start_byte: usize,
1038 start_point: Point,
1039 mut ranges: Vec<tree_sitter::Range>,
1040 old_tree: Option<Tree>,
1041) -> Tree {
1042 for range in &mut ranges {
1043 range.start_byte -= start_byte;
1044 range.end_byte -= start_byte;
1045 range.start_point = (Point::from_ts_point(range.start_point) - start_point).to_ts_point();
1046 range.end_point = (Point::from_ts_point(range.end_point) - start_point).to_ts_point();
1047 }
1048
1049 PARSER.with(|parser| {
1050 let mut parser = parser.borrow_mut();
1051 let mut chunks = text.chunks_in_range(start_byte..text.len());
1052 parser
1053 .set_included_ranges(&ranges)
1054 .expect("overlapping ranges");
1055 parser
1056 .set_language(grammar.ts_language)
1057 .expect("incompatible grammar");
1058 parser
1059 .parse_with(
1060 &mut move |offset, _| {
1061 chunks.seek(start_byte + offset);
1062 chunks.next().unwrap_or("").as_bytes()
1063 },
1064 old_tree.as_ref(),
1065 )
1066 .expect("invalid language")
1067 })
1068}
1069
1070fn get_injections(
1071 config: &InjectionConfig,
1072 text: &BufferSnapshot,
1073 node: Node,
1074 language_registry: &Arc<LanguageRegistry>,
1075 depth: usize,
1076 changed_ranges: &[Range<usize>],
1077 combined_injection_ranges: &mut HashMap<Arc<Language>, Vec<tree_sitter::Range>>,
1078 queue: &mut BinaryHeap<ParseStep>,
1079) {
1080 let mut query_cursor = QueryCursorHandle::new();
1081 let mut prev_match = None;
1082
1083 combined_injection_ranges.clear();
1084 for pattern in &config.patterns {
1085 if let (Some(language_name), true) = (pattern.language.as_ref(), pattern.combined) {
1086 if let Some(language) = language_registry.language_for_name_or_extension(language_name)
1087 {
1088 combined_injection_ranges.insert(language, Vec::new());
1089 }
1090 }
1091 }
1092
1093 for query_range in changed_ranges {
1094 query_cursor.set_byte_range(query_range.start.saturating_sub(1)..query_range.end + 1);
1095 for mat in query_cursor.matches(&config.query, node, TextProvider(text.as_rope())) {
1096 let content_ranges = mat
1097 .nodes_for_capture_index(config.content_capture_ix)
1098 .map(|node| node.range())
1099 .collect::<Vec<_>>();
1100 if content_ranges.is_empty() {
1101 continue;
1102 }
1103
1104 // Avoid duplicate matches if two changed ranges intersect the same injection.
1105 let content_range =
1106 content_ranges.first().unwrap().start_byte..content_ranges.last().unwrap().end_byte;
1107 if let Some((last_pattern_ix, last_range)) = &prev_match {
1108 if mat.pattern_index == *last_pattern_ix && content_range == *last_range {
1109 continue;
1110 }
1111 }
1112 prev_match = Some((mat.pattern_index, content_range.clone()));
1113
1114 let combined = config.patterns[mat.pattern_index].combined;
1115
1116 let mut language_name = None;
1117 let mut step_range = content_range.clone();
1118 if let Some(name) = config.patterns[mat.pattern_index].language.as_ref() {
1119 language_name = Some(Cow::Borrowed(name.as_ref()))
1120 } else if let Some(language_node) = config
1121 .language_capture_ix
1122 .and_then(|ix| mat.nodes_for_capture_index(ix).next())
1123 {
1124 step_range.start = cmp::min(content_range.start, language_node.start_byte());
1125 step_range.end = cmp::max(content_range.end, language_node.end_byte());
1126 language_name = Some(Cow::Owned(
1127 text.text_for_range(language_node.byte_range()).collect(),
1128 ))
1129 };
1130
1131 if let Some(language_name) = language_name {
1132 let language = {
1133 let language_name: &str = &language_name;
1134 language_registry.language_for_name_or_extension(language_name)
1135 };
1136 let range = text.anchor_before(step_range.start)..text.anchor_after(step_range.end);
1137 if let Some(language) = language {
1138 if combined {
1139 combined_injection_ranges
1140 .get_mut(&language.clone())
1141 .unwrap()
1142 .extend(content_ranges);
1143 } else {
1144 queue.push(ParseStep {
1145 depth,
1146 language: ParseStepLanguage::Loaded { language },
1147 included_ranges: content_ranges,
1148 range,
1149 mode: ParseMode::Single,
1150 });
1151 }
1152 } else {
1153 queue.push(ParseStep {
1154 depth,
1155 language: ParseStepLanguage::Pending {
1156 name: language_name.into(),
1157 },
1158 included_ranges: content_ranges,
1159 range,
1160 mode: ParseMode::Single,
1161 });
1162 }
1163 }
1164 }
1165 }
1166
1167 for (language, mut included_ranges) in combined_injection_ranges.drain() {
1168 included_ranges.sort_unstable();
1169 let range = text.anchor_before(node.start_byte())..text.anchor_after(node.end_byte());
1170 queue.push(ParseStep {
1171 depth,
1172 language: ParseStepLanguage::Loaded { language },
1173 range,
1174 included_ranges,
1175 mode: ParseMode::Combined {
1176 parent_layer_range: node.start_byte()..node.end_byte(),
1177 parent_layer_changed_ranges: changed_ranges.to_vec(),
1178 },
1179 })
1180 }
1181}
1182
1183fn splice_included_ranges(
1184 mut ranges: Vec<tree_sitter::Range>,
1185 changed_ranges: &[Range<usize>],
1186 new_ranges: &[tree_sitter::Range],
1187) -> Vec<tree_sitter::Range> {
1188 let mut changed_ranges = changed_ranges.into_iter().peekable();
1189 let mut new_ranges = new_ranges.into_iter().peekable();
1190 let mut ranges_ix = 0;
1191 loop {
1192 let new_range = new_ranges.peek();
1193 let mut changed_range = changed_ranges.peek();
1194
1195 // Remove ranges that have changed before inserting any new ranges
1196 // into those ranges.
1197 if let Some((changed, new)) = changed_range.zip(new_range) {
1198 if new.end_byte < changed.start {
1199 changed_range = None;
1200 }
1201 }
1202
1203 if let Some(changed) = changed_range {
1204 let mut start_ix = ranges_ix
1205 + match ranges[ranges_ix..].binary_search_by_key(&changed.start, |r| r.end_byte) {
1206 Ok(ix) | Err(ix) => ix,
1207 };
1208 let mut end_ix = ranges_ix
1209 + match ranges[ranges_ix..].binary_search_by_key(&changed.end, |r| r.start_byte) {
1210 Ok(ix) => ix + 1,
1211 Err(ix) => ix,
1212 };
1213
1214 // If there are empty ranges, then there may be multiple ranges with the same
1215 // start or end. Expand the splice to include any adjacent ranges that touch
1216 // the changed range.
1217 while start_ix > 0 {
1218 if ranges[start_ix - 1].end_byte == changed.start {
1219 start_ix -= 1;
1220 } else {
1221 break;
1222 }
1223 }
1224 while let Some(range) = ranges.get(end_ix) {
1225 if range.start_byte == changed.end {
1226 end_ix += 1;
1227 } else {
1228 break;
1229 }
1230 }
1231
1232 if end_ix > start_ix {
1233 ranges.splice(start_ix..end_ix, []);
1234 }
1235 changed_ranges.next();
1236 ranges_ix = start_ix;
1237 } else if let Some(new_range) = new_range {
1238 let ix = ranges_ix
1239 + match ranges[ranges_ix..]
1240 .binary_search_by_key(&new_range.start_byte, |r| r.start_byte)
1241 {
1242 Ok(ix) | Err(ix) => ix,
1243 };
1244 ranges.insert(ix, **new_range);
1245 new_ranges.next();
1246 ranges_ix = ix + 1;
1247 } else {
1248 break;
1249 }
1250 }
1251 ranges
1252}
1253
1254impl<'a> SyntaxLayerInfo<'a> {
1255 pub(crate) fn override_id(&self, offset: usize, text: &text::BufferSnapshot) -> Option<u32> {
1256 let text = TextProvider(text.as_rope());
1257 let config = self.language.grammar.as_ref()?.override_config.as_ref()?;
1258
1259 let mut query_cursor = QueryCursorHandle::new();
1260 query_cursor.set_byte_range(offset..offset);
1261
1262 let mut smallest_match: Option<(u32, Range<usize>)> = None;
1263 for mat in query_cursor.matches(&config.query, self.node, text) {
1264 for capture in mat.captures {
1265 if !config.values.contains_key(&capture.index) {
1266 continue;
1267 }
1268
1269 let range = capture.node.byte_range();
1270 if offset <= range.start || offset >= range.end {
1271 continue;
1272 }
1273
1274 if let Some((_, smallest_range)) = &smallest_match {
1275 if range.len() < smallest_range.len() {
1276 smallest_match = Some((capture.index, range))
1277 }
1278 continue;
1279 }
1280
1281 smallest_match = Some((capture.index, range));
1282 }
1283 }
1284
1285 smallest_match.map(|(index, _)| index)
1286 }
1287}
1288
1289impl std::ops::Deref for SyntaxMap {
1290 type Target = SyntaxSnapshot;
1291
1292 fn deref(&self) -> &Self::Target {
1293 &self.snapshot
1294 }
1295}
1296
1297impl PartialEq for ParseStep {
1298 fn eq(&self, _: &Self) -> bool {
1299 false
1300 }
1301}
1302
1303impl Eq for ParseStep {}
1304
1305impl PartialOrd for ParseStep {
1306 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1307 Some(self.cmp(&other))
1308 }
1309}
1310
1311impl Ord for ParseStep {
1312 fn cmp(&self, other: &Self) -> Ordering {
1313 let range_a = self.range();
1314 let range_b = other.range();
1315 Ord::cmp(&other.depth, &self.depth)
1316 .then_with(|| Ord::cmp(&range_b.start, &range_a.start))
1317 .then_with(|| Ord::cmp(&range_a.end, &range_b.end))
1318 .then_with(|| self.language.id().cmp(&other.language.id()))
1319 }
1320}
1321
1322impl ParseStep {
1323 fn range(&self) -> Range<usize> {
1324 if let ParseMode::Combined {
1325 parent_layer_range, ..
1326 } = &self.mode
1327 {
1328 parent_layer_range.clone()
1329 } else {
1330 let start = self.included_ranges.first().map_or(0, |r| r.start_byte);
1331 let end = self.included_ranges.last().map_or(0, |r| r.end_byte);
1332 start..end
1333 }
1334 }
1335}
1336
1337impl ChangedRegion {
1338 fn cmp(&self, other: &Self, buffer: &BufferSnapshot) -> Ordering {
1339 let range_a = &self.range;
1340 let range_b = &other.range;
1341 Ord::cmp(&self.depth, &other.depth)
1342 .then_with(|| range_a.start.cmp(&range_b.start, buffer))
1343 .then_with(|| range_b.end.cmp(&range_a.end, buffer))
1344 }
1345}
1346
1347impl ChangeRegionSet {
1348 fn start_position(&self) -> ChangeStartPosition {
1349 self.0.first().map_or(
1350 ChangeStartPosition {
1351 depth: usize::MAX,
1352 position: Anchor::MAX,
1353 },
1354 |region| ChangeStartPosition {
1355 depth: region.depth,
1356 position: region.range.start,
1357 },
1358 )
1359 }
1360
1361 fn intersects(&self, layer: &SyntaxLayer, text: &BufferSnapshot) -> bool {
1362 for region in &self.0 {
1363 if region.depth < layer.depth {
1364 continue;
1365 }
1366 if region.depth > layer.depth {
1367 break;
1368 }
1369 if region.range.end.cmp(&layer.range.start, text).is_le() {
1370 continue;
1371 }
1372 if region.range.start.cmp(&layer.range.end, text).is_ge() {
1373 break;
1374 }
1375 return true;
1376 }
1377 false
1378 }
1379
1380 fn insert(&mut self, region: ChangedRegion, text: &BufferSnapshot) {
1381 if let Err(ix) = self.0.binary_search_by(|probe| probe.cmp(®ion, text)) {
1382 self.0.insert(ix, region);
1383 }
1384 }
1385
1386 fn prune(&mut self, summary: SyntaxLayerSummary, text: &BufferSnapshot) -> bool {
1387 let prev_len = self.0.len();
1388 self.0.retain(|region| {
1389 region.depth > summary.max_depth
1390 || (region.depth == summary.max_depth
1391 && region
1392 .range
1393 .end
1394 .cmp(&summary.last_layer_range.start, text)
1395 .is_gt())
1396 });
1397 self.0.len() < prev_len
1398 }
1399}
1400
1401impl Default for SyntaxLayerSummary {
1402 fn default() -> Self {
1403 Self {
1404 max_depth: 0,
1405 min_depth: 0,
1406 range: Anchor::MAX..Anchor::MIN,
1407 last_layer_range: Anchor::MIN..Anchor::MAX,
1408 last_layer_language: None,
1409 contains_unknown_injections: false,
1410 }
1411 }
1412}
1413
1414impl sum_tree::Summary for SyntaxLayerSummary {
1415 type Context = BufferSnapshot;
1416
1417 fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
1418 if other.max_depth > self.max_depth {
1419 self.max_depth = other.max_depth;
1420 self.range = other.range.clone();
1421 } else {
1422 if other.range.start.cmp(&self.range.start, buffer).is_lt() {
1423 self.range.start = other.range.start;
1424 }
1425 if other.range.end.cmp(&self.range.end, buffer).is_gt() {
1426 self.range.end = other.range.end;
1427 }
1428 }
1429 self.last_layer_range = other.last_layer_range.clone();
1430 self.last_layer_language = other.last_layer_language;
1431 self.contains_unknown_injections |= other.contains_unknown_injections;
1432 }
1433}
1434
1435impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for SyntaxLayerPosition {
1436 fn cmp(&self, cursor_location: &SyntaxLayerSummary, buffer: &BufferSnapshot) -> Ordering {
1437 Ord::cmp(&self.depth, &cursor_location.max_depth)
1438 .then_with(|| {
1439 self.range
1440 .start
1441 .cmp(&cursor_location.last_layer_range.start, buffer)
1442 })
1443 .then_with(|| {
1444 cursor_location
1445 .last_layer_range
1446 .end
1447 .cmp(&self.range.end, buffer)
1448 })
1449 .then_with(|| self.language.cmp(&cursor_location.last_layer_language))
1450 }
1451}
1452
1453impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for ChangeStartPosition {
1454 fn cmp(&self, cursor_location: &SyntaxLayerSummary, text: &BufferSnapshot) -> Ordering {
1455 Ord::cmp(&self.depth, &cursor_location.max_depth)
1456 .then_with(|| self.position.cmp(&cursor_location.range.end, text))
1457 }
1458}
1459
1460impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary>
1461 for SyntaxLayerPositionBeforeChange
1462{
1463 fn cmp(&self, cursor_location: &SyntaxLayerSummary, buffer: &BufferSnapshot) -> Ordering {
1464 if self.change.cmp(cursor_location, buffer).is_le() {
1465 return Ordering::Less;
1466 } else {
1467 self.position.cmp(cursor_location, buffer)
1468 }
1469 }
1470}
1471
1472impl sum_tree::Item for SyntaxLayer {
1473 type Summary = SyntaxLayerSummary;
1474
1475 fn summary(&self) -> Self::Summary {
1476 SyntaxLayerSummary {
1477 min_depth: self.depth,
1478 max_depth: self.depth,
1479 range: self.range.clone(),
1480 last_layer_range: self.range.clone(),
1481 last_layer_language: self.content.language_id(),
1482 contains_unknown_injections: matches!(self.content, SyntaxLayerContent::Pending { .. }),
1483 }
1484 }
1485}
1486
1487impl std::fmt::Debug for SyntaxLayer {
1488 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1489 f.debug_struct("SyntaxLayer")
1490 .field("depth", &self.depth)
1491 .field("range", &self.range)
1492 .field("tree", &self.content.tree())
1493 .finish()
1494 }
1495}
1496
1497impl<'a> tree_sitter::TextProvider<'a> for TextProvider<'a> {
1498 type I = ByteChunks<'a>;
1499
1500 fn text(&mut self, node: tree_sitter::Node) -> Self::I {
1501 ByteChunks(self.0.chunks_in_range(node.byte_range()))
1502 }
1503}
1504
1505impl<'a> Iterator for ByteChunks<'a> {
1506 type Item = &'a [u8];
1507
1508 fn next(&mut self) -> Option<Self::Item> {
1509 self.0.next().map(str::as_bytes)
1510 }
1511}
1512
1513impl QueryCursorHandle {
1514 pub(crate) fn new() -> Self {
1515 let mut cursor = QUERY_CURSORS.lock().pop().unwrap_or_else(QueryCursor::new);
1516 cursor.set_match_limit(64);
1517 QueryCursorHandle(Some(cursor))
1518 }
1519}
1520
1521impl Deref for QueryCursorHandle {
1522 type Target = QueryCursor;
1523
1524 fn deref(&self) -> &Self::Target {
1525 self.0.as_ref().unwrap()
1526 }
1527}
1528
1529impl DerefMut for QueryCursorHandle {
1530 fn deref_mut(&mut self) -> &mut Self::Target {
1531 self.0.as_mut().unwrap()
1532 }
1533}
1534
1535impl Drop for QueryCursorHandle {
1536 fn drop(&mut self) {
1537 let mut cursor = self.0.take().unwrap();
1538 cursor.set_byte_range(0..usize::MAX);
1539 cursor.set_point_range(Point::zero().to_ts_point()..Point::MAX.to_ts_point());
1540 QUERY_CURSORS.lock().push(cursor)
1541 }
1542}
1543
1544pub(crate) trait ToTreeSitterPoint {
1545 fn to_ts_point(self) -> tree_sitter::Point;
1546 fn from_ts_point(point: tree_sitter::Point) -> Self;
1547}
1548
1549impl ToTreeSitterPoint for Point {
1550 fn to_ts_point(self) -> tree_sitter::Point {
1551 tree_sitter::Point::new(self.row as usize, self.column as usize)
1552 }
1553
1554 fn from_ts_point(point: tree_sitter::Point) -> Self {
1555 Point::new(point.row as u32, point.column as u32)
1556 }
1557}
1558
1559#[cfg(test)]
1560mod tests {
1561 use super::*;
1562 use crate::LanguageConfig;
1563 use rand::rngs::StdRng;
1564 use std::env;
1565 use text::Buffer;
1566 use unindent::Unindent as _;
1567 use util::test::marked_text_ranges;
1568
1569 #[test]
1570 fn test_splice_included_ranges() {
1571 let ranges = vec![ts_range(20..30), ts_range(50..60), ts_range(80..90)];
1572
1573 let new_ranges = splice_included_ranges(
1574 ranges.clone(),
1575 &[54..56, 58..68],
1576 &[ts_range(50..54), ts_range(59..67)],
1577 );
1578 assert_eq!(
1579 new_ranges,
1580 &[
1581 ts_range(20..30),
1582 ts_range(50..54),
1583 ts_range(59..67),
1584 ts_range(80..90),
1585 ]
1586 );
1587
1588 let new_ranges = splice_included_ranges(ranges.clone(), &[70..71, 91..100], &[]);
1589 assert_eq!(
1590 new_ranges,
1591 &[ts_range(20..30), ts_range(50..60), ts_range(80..90)]
1592 );
1593
1594 let new_ranges =
1595 splice_included_ranges(ranges.clone(), &[], &[ts_range(0..2), ts_range(70..75)]);
1596 assert_eq!(
1597 new_ranges,
1598 &[
1599 ts_range(0..2),
1600 ts_range(20..30),
1601 ts_range(50..60),
1602 ts_range(70..75),
1603 ts_range(80..90)
1604 ]
1605 );
1606
1607 let new_ranges = splice_included_ranges(ranges.clone(), &[30..50], &[ts_range(25..55)]);
1608 assert_eq!(new_ranges, &[ts_range(25..55), ts_range(80..90)]);
1609
1610 fn ts_range(range: Range<usize>) -> tree_sitter::Range {
1611 tree_sitter::Range {
1612 start_byte: range.start,
1613 start_point: tree_sitter::Point {
1614 row: 0,
1615 column: range.start,
1616 },
1617 end_byte: range.end,
1618 end_point: tree_sitter::Point {
1619 row: 0,
1620 column: range.end,
1621 },
1622 }
1623 }
1624 }
1625
1626 #[gpui::test]
1627 fn test_syntax_map_layers_for_range() {
1628 let registry = Arc::new(LanguageRegistry::test());
1629 let language = Arc::new(rust_lang());
1630 registry.add(language.clone());
1631
1632 let mut buffer = Buffer::new(
1633 0,
1634 0,
1635 r#"
1636 fn a() {
1637 assert_eq!(
1638 b(vec![C {}]),
1639 vec![d.e],
1640 );
1641 println!("{}", f(|_| true));
1642 }
1643 "#
1644 .unindent(),
1645 );
1646
1647 let mut syntax_map = SyntaxMap::new();
1648 syntax_map.set_language_registry(registry.clone());
1649 syntax_map.reparse(language.clone(), &buffer);
1650
1651 assert_layers_for_range(
1652 &syntax_map,
1653 &buffer,
1654 Point::new(2, 0)..Point::new(2, 0),
1655 &[
1656 "...(function_item ... (block (expression_statement (macro_invocation...",
1657 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
1658 ],
1659 );
1660 assert_layers_for_range(
1661 &syntax_map,
1662 &buffer,
1663 Point::new(2, 14)..Point::new(2, 16),
1664 &[
1665 "...(function_item ...",
1666 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
1667 "...(array_expression (struct_expression ...",
1668 ],
1669 );
1670 assert_layers_for_range(
1671 &syntax_map,
1672 &buffer,
1673 Point::new(3, 14)..Point::new(3, 16),
1674 &[
1675 "...(function_item ...",
1676 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
1677 "...(array_expression (field_expression ...",
1678 ],
1679 );
1680 assert_layers_for_range(
1681 &syntax_map,
1682 &buffer,
1683 Point::new(5, 12)..Point::new(5, 16),
1684 &[
1685 "...(function_item ...",
1686 "...(call_expression ... (arguments (closure_expression ...",
1687 ],
1688 );
1689
1690 // Replace a vec! macro invocation with a plain slice, removing a syntactic layer.
1691 let macro_name_range = range_for_text(&buffer, "vec!");
1692 buffer.edit([(macro_name_range, "&")]);
1693 syntax_map.interpolate(&buffer);
1694 syntax_map.reparse(language.clone(), &buffer);
1695
1696 assert_layers_for_range(
1697 &syntax_map,
1698 &buffer,
1699 Point::new(2, 14)..Point::new(2, 16),
1700 &[
1701 "...(function_item ...",
1702 "...(tuple_expression (call_expression ... arguments: (arguments (reference_expression value: (array_expression...",
1703 ],
1704 );
1705
1706 // Put the vec! macro back, adding back the syntactic layer.
1707 buffer.undo();
1708 syntax_map.interpolate(&buffer);
1709 syntax_map.reparse(language.clone(), &buffer);
1710
1711 assert_layers_for_range(
1712 &syntax_map,
1713 &buffer,
1714 Point::new(2, 14)..Point::new(2, 16),
1715 &[
1716 "...(function_item ...",
1717 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
1718 "...(array_expression (struct_expression ...",
1719 ],
1720 );
1721 }
1722
1723 #[gpui::test]
1724 fn test_dynamic_language_injection() {
1725 let registry = Arc::new(LanguageRegistry::test());
1726 let markdown = Arc::new(markdown_lang());
1727 registry.add(markdown.clone());
1728 registry.add(Arc::new(rust_lang()));
1729 registry.add(Arc::new(ruby_lang()));
1730
1731 let mut buffer = Buffer::new(
1732 0,
1733 0,
1734 r#"
1735 This is a code block:
1736
1737 ```rs
1738 fn foo() {}
1739 ```
1740 "#
1741 .unindent(),
1742 );
1743
1744 let mut syntax_map = SyntaxMap::new();
1745 syntax_map.set_language_registry(registry.clone());
1746 syntax_map.reparse(markdown.clone(), &buffer);
1747 assert_layers_for_range(
1748 &syntax_map,
1749 &buffer,
1750 Point::new(3, 0)..Point::new(3, 0),
1751 &[
1752 "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter...",
1753 "...(function_item name: (identifier) parameters: (parameters) body: (block)...",
1754 ],
1755 );
1756
1757 // Replace Rust with Ruby in code block.
1758 let macro_name_range = range_for_text(&buffer, "rs");
1759 buffer.edit([(macro_name_range, "ruby")]);
1760 syntax_map.interpolate(&buffer);
1761 syntax_map.reparse(markdown.clone(), &buffer);
1762 assert_layers_for_range(
1763 &syntax_map,
1764 &buffer,
1765 Point::new(3, 0)..Point::new(3, 0),
1766 &[
1767 "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter...",
1768 "...(call method: (identifier) arguments: (argument_list (call method: (identifier) arguments: (argument_list) block: (block)...",
1769 ],
1770 );
1771
1772 // Replace Ruby with a language that hasn't been loaded yet.
1773 let macro_name_range = range_for_text(&buffer, "ruby");
1774 buffer.edit([(macro_name_range, "html")]);
1775 syntax_map.interpolate(&buffer);
1776 syntax_map.reparse(markdown.clone(), &buffer);
1777 assert_layers_for_range(
1778 &syntax_map,
1779 &buffer,
1780 Point::new(3, 0)..Point::new(3, 0),
1781 &[
1782 "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter..."
1783 ],
1784 );
1785 assert!(syntax_map.contains_unknown_injections());
1786
1787 registry.add(Arc::new(html_lang()));
1788 syntax_map.reparse(markdown.clone(), &buffer);
1789 assert_layers_for_range(
1790 &syntax_map,
1791 &buffer,
1792 Point::new(3, 0)..Point::new(3, 0),
1793 &[
1794 "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter...",
1795 "(fragment (text))",
1796 ],
1797 );
1798 assert!(!syntax_map.contains_unknown_injections());
1799 }
1800
1801 #[gpui::test]
1802 fn test_typing_multiple_new_injections() {
1803 let (buffer, syntax_map) = test_edit_sequence(
1804 "Rust",
1805 &[
1806 "fn a() { dbg }",
1807 "fn a() { dbg«!» }",
1808 "fn a() { dbg!«()» }",
1809 "fn a() { dbg!(«b») }",
1810 "fn a() { dbg!(b«.») }",
1811 "fn a() { dbg!(b.«c») }",
1812 "fn a() { dbg!(b.c«()») }",
1813 "fn a() { dbg!(b.c(«vec»)) }",
1814 "fn a() { dbg!(b.c(vec«!»)) }",
1815 "fn a() { dbg!(b.c(vec!«[]»)) }",
1816 "fn a() { dbg!(b.c(vec![«d»])) }",
1817 "fn a() { dbg!(b.c(vec![d«.»])) }",
1818 "fn a() { dbg!(b.c(vec![d.«e»])) }",
1819 ],
1820 );
1821
1822 assert_capture_ranges(
1823 &syntax_map,
1824 &buffer,
1825 &["field"],
1826 "fn a() { dbg!(b.«c»(vec![d.«e»])) }",
1827 );
1828 }
1829
1830 #[gpui::test]
1831 fn test_pasting_new_injection_line_between_others() {
1832 let (buffer, syntax_map) = test_edit_sequence(
1833 "Rust",
1834 &[
1835 "
1836 fn a() {
1837 b!(B {});
1838 c!(C {});
1839 d!(D {});
1840 e!(E {});
1841 f!(F {});
1842 g!(G {});
1843 }
1844 ",
1845 "
1846 fn a() {
1847 b!(B {});
1848 c!(C {});
1849 d!(D {});
1850 « h!(H {});
1851 » e!(E {});
1852 f!(F {});
1853 g!(G {});
1854 }
1855 ",
1856 ],
1857 );
1858
1859 assert_capture_ranges(
1860 &syntax_map,
1861 &buffer,
1862 &["struct"],
1863 "
1864 fn a() {
1865 b!(«B {}»);
1866 c!(«C {}»);
1867 d!(«D {}»);
1868 h!(«H {}»);
1869 e!(«E {}»);
1870 f!(«F {}»);
1871 g!(«G {}»);
1872 }
1873 ",
1874 );
1875 }
1876
1877 #[gpui::test]
1878 fn test_joining_injections_with_child_injections() {
1879 let (buffer, syntax_map) = test_edit_sequence(
1880 "Rust",
1881 &[
1882 "
1883 fn a() {
1884 b!(
1885 c![one.two.three],
1886 d![four.five.six],
1887 );
1888 e!(
1889 f![seven.eight],
1890 );
1891 }
1892 ",
1893 "
1894 fn a() {
1895 b!(
1896 c![one.two.three],
1897 d![four.five.six],
1898 ˇ f![seven.eight],
1899 );
1900 }
1901 ",
1902 ],
1903 );
1904
1905 assert_capture_ranges(
1906 &syntax_map,
1907 &buffer,
1908 &["field"],
1909 "
1910 fn a() {
1911 b!(
1912 c![one.«two».«three»],
1913 d![four.«five».«six»],
1914 f![seven.«eight»],
1915 );
1916 }
1917 ",
1918 );
1919 }
1920
1921 #[gpui::test]
1922 fn test_editing_edges_of_injection() {
1923 test_edit_sequence(
1924 "Rust",
1925 &[
1926 "
1927 fn a() {
1928 b!(c!())
1929 }
1930 ",
1931 "
1932 fn a() {
1933 «d»!(c!())
1934 }
1935 ",
1936 "
1937 fn a() {
1938 «e»d!(c!())
1939 }
1940 ",
1941 "
1942 fn a() {
1943 ed!«[»c!()«]»
1944 }
1945 ",
1946 ],
1947 );
1948 }
1949
1950 #[gpui::test]
1951 fn test_edits_preceding_and_intersecting_injection() {
1952 test_edit_sequence(
1953 "Rust",
1954 &[
1955 //
1956 "const aaaaaaaaaaaa: B = c!(d(e.f));",
1957 "const aˇa: B = c!(d(eˇ));",
1958 ],
1959 );
1960 }
1961
1962 #[gpui::test]
1963 fn test_non_local_changes_create_injections() {
1964 test_edit_sequence(
1965 "Rust",
1966 &[
1967 "
1968 // a! {
1969 static B: C = d;
1970 // }
1971 ",
1972 "
1973 ˇa! {
1974 static B: C = d;
1975 ˇ}
1976 ",
1977 ],
1978 );
1979 }
1980
1981 #[gpui::test]
1982 fn test_creating_many_injections_in_one_edit() {
1983 test_edit_sequence(
1984 "Rust",
1985 &[
1986 "
1987 fn a() {
1988 one(Two::three(3));
1989 four(Five::six(6));
1990 seven(Eight::nine(9));
1991 }
1992 ",
1993 "
1994 fn a() {
1995 one«!»(Two::three(3));
1996 four«!»(Five::six(6));
1997 seven«!»(Eight::nine(9));
1998 }
1999 ",
2000 "
2001 fn a() {
2002 one!(Two::three«!»(3));
2003 four!(Five::six«!»(6));
2004 seven!(Eight::nine«!»(9));
2005 }
2006 ",
2007 ],
2008 );
2009 }
2010
2011 #[gpui::test]
2012 fn test_editing_across_injection_boundary() {
2013 test_edit_sequence(
2014 "Rust",
2015 &[
2016 "
2017 fn one() {
2018 two();
2019 three!(
2020 three.four,
2021 five.six,
2022 );
2023 }
2024 ",
2025 "
2026 fn one() {
2027 two();
2028 th«irty_five![»
2029 three.four,
2030 five.six,
2031 « seven.eight,
2032 ];»
2033 }
2034 ",
2035 ],
2036 );
2037 }
2038
2039 #[gpui::test]
2040 fn test_removing_injection_by_replacing_across_boundary() {
2041 test_edit_sequence(
2042 "Rust",
2043 &[
2044 "
2045 fn one() {
2046 two!(
2047 three.four,
2048 );
2049 }
2050 ",
2051 "
2052 fn one() {
2053 t«en
2054 .eleven(
2055 twelve,
2056 »
2057 three.four,
2058 );
2059 }
2060 ",
2061 ],
2062 );
2063 }
2064
2065 #[gpui::test]
2066 fn test_combined_injections() {
2067 let (buffer, syntax_map) = test_edit_sequence(
2068 "ERB",
2069 &[
2070 "
2071 <body>
2072 <% if @one %>
2073 <div class=one>
2074 <% else %>
2075 <div class=two>
2076 <% end %>
2077 </div>
2078 </body>
2079 ",
2080 "
2081 <body>
2082 <% if @one %>
2083 <div class=one>
2084 ˇ else ˇ
2085 <div class=two>
2086 <% end %>
2087 </div>
2088 </body>
2089 ",
2090 "
2091 <body>
2092 <% if @one «;» end %>
2093 </div>
2094 </body>
2095 ",
2096 ],
2097 );
2098
2099 assert_capture_ranges(
2100 &syntax_map,
2101 &buffer,
2102 &["tag", "ivar"],
2103 "
2104 <«body»>
2105 <% if «@one» ; end %>
2106 </«div»>
2107 </«body»>
2108 ",
2109 );
2110 }
2111
2112 #[gpui::test]
2113 fn test_combined_injections_empty_ranges() {
2114 test_edit_sequence(
2115 "ERB",
2116 &[
2117 "
2118 <% if @one %>
2119 <% else %>
2120 <% end %>
2121 ",
2122 "
2123 <% if @one %>
2124 ˇ<% end %>
2125 ",
2126 ],
2127 );
2128 }
2129
2130 #[gpui::test]
2131 fn test_combined_injections_edit_edges_of_ranges() {
2132 let (buffer, syntax_map) = test_edit_sequence(
2133 "ERB",
2134 &[
2135 "
2136 <%= one @two %>
2137 <%= three @four %>
2138 ",
2139 "
2140 <%= one @two %ˇ
2141 <%= three @four %>
2142 ",
2143 "
2144 <%= one @two %«>»
2145 <%= three @four %>
2146 ",
2147 ],
2148 );
2149
2150 assert_capture_ranges(
2151 &syntax_map,
2152 &buffer,
2153 &["tag", "ivar"],
2154 "
2155 <%= one «@two» %>
2156 <%= three «@four» %>
2157 ",
2158 );
2159 }
2160
2161 #[gpui::test]
2162 fn test_combined_injections_splitting_some_injections() {
2163 let (_buffer, _syntax_map) = test_edit_sequence(
2164 "ERB",
2165 &[
2166 r#"
2167 <%A if b(:c) %>
2168 d
2169 <% end %>
2170 eee
2171 <% f %>
2172 "#,
2173 r#"
2174 <%« AAAAAAA %>
2175 hhhhhhh
2176 <%=» if b(:c) %>
2177 d
2178 <% end %>
2179 eee
2180 <% f %>
2181 "#,
2182 ],
2183 );
2184 }
2185
2186 #[gpui::test(iterations = 50)]
2187 fn test_random_syntax_map_edits(mut rng: StdRng) {
2188 let operations = env::var("OPERATIONS")
2189 .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
2190 .unwrap_or(10);
2191
2192 let text = r#"
2193 fn test_something() {
2194 let vec = vec![5, 1, 3, 8];
2195 assert_eq!(
2196 vec
2197 .into_iter()
2198 .map(|i| i * 2)
2199 .collect::<Vec<usize>>(),
2200 vec![
2201 5 * 2, 1 * 2, 3 * 2, 8 * 2
2202 ],
2203 );
2204 }
2205 "#
2206 .unindent()
2207 .repeat(2);
2208
2209 let registry = Arc::new(LanguageRegistry::test());
2210 let language = Arc::new(rust_lang());
2211 registry.add(language.clone());
2212 let mut buffer = Buffer::new(0, 0, text);
2213
2214 let mut syntax_map = SyntaxMap::new();
2215 syntax_map.set_language_registry(registry.clone());
2216 syntax_map.reparse(language.clone(), &buffer);
2217
2218 let mut reference_syntax_map = SyntaxMap::new();
2219 reference_syntax_map.set_language_registry(registry.clone());
2220
2221 log::info!("initial text:\n{}", buffer.text());
2222
2223 for _ in 0..operations {
2224 let prev_buffer = buffer.snapshot();
2225 let prev_syntax_map = syntax_map.snapshot();
2226
2227 buffer.randomly_edit(&mut rng, 3);
2228 log::info!("text:\n{}", buffer.text());
2229
2230 syntax_map.interpolate(&buffer);
2231 check_interpolation(&prev_syntax_map, &syntax_map, &prev_buffer, &buffer);
2232
2233 syntax_map.reparse(language.clone(), &buffer);
2234
2235 reference_syntax_map.clear();
2236 reference_syntax_map.reparse(language.clone(), &buffer);
2237 }
2238
2239 for i in 0..operations {
2240 let i = operations - i - 1;
2241 buffer.undo();
2242 log::info!("undoing operation {}", i);
2243 log::info!("text:\n{}", buffer.text());
2244
2245 syntax_map.interpolate(&buffer);
2246 syntax_map.reparse(language.clone(), &buffer);
2247
2248 reference_syntax_map.clear();
2249 reference_syntax_map.reparse(language.clone(), &buffer);
2250 assert_eq!(
2251 syntax_map.layers(&buffer).len(),
2252 reference_syntax_map.layers(&buffer).len(),
2253 "wrong number of layers after undoing edit {i}"
2254 );
2255 }
2256
2257 let layers = syntax_map.layers(&buffer);
2258 let reference_layers = reference_syntax_map.layers(&buffer);
2259 for (edited_layer, reference_layer) in layers.into_iter().zip(reference_layers.into_iter())
2260 {
2261 assert_eq!(edited_layer.node.to_sexp(), reference_layer.node.to_sexp());
2262 assert_eq!(edited_layer.node.range(), reference_layer.node.range());
2263 }
2264 }
2265
2266 #[gpui::test(iterations = 50)]
2267 fn test_random_syntax_map_edits_with_combined_injections(mut rng: StdRng) {
2268 let operations = env::var("OPERATIONS")
2269 .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
2270 .unwrap_or(10);
2271
2272 let text = r#"
2273 <div id="main">
2274 <% if one?(:two) %>
2275 <p class="three" four>
2276 <%= yield :five %>
2277 </p>
2278 <% elsif Six.seven(8) %>
2279 <p id="three" four>
2280 <%= yield :five %>
2281 </p>
2282 <% else %>
2283 <span>Ok</span>
2284 <% end %>
2285 </div>
2286 "#
2287 .unindent()
2288 .repeat(8);
2289
2290 let registry = Arc::new(LanguageRegistry::test());
2291 let language = Arc::new(erb_lang());
2292 registry.add(language.clone());
2293 registry.add(Arc::new(ruby_lang()));
2294 registry.add(Arc::new(html_lang()));
2295 let mut buffer = Buffer::new(0, 0, text);
2296
2297 let mut syntax_map = SyntaxMap::new();
2298 syntax_map.set_language_registry(registry.clone());
2299 syntax_map.reparse(language.clone(), &buffer);
2300
2301 let mut reference_syntax_map = SyntaxMap::new();
2302 reference_syntax_map.set_language_registry(registry.clone());
2303
2304 log::info!("initial text:\n{}", buffer.text());
2305
2306 for _ in 0..operations {
2307 let prev_buffer = buffer.snapshot();
2308 let prev_syntax_map = syntax_map.snapshot();
2309
2310 buffer.randomly_edit(&mut rng, 3);
2311 log::info!("text:\n{}", buffer.text());
2312
2313 syntax_map.interpolate(&buffer);
2314 check_interpolation(&prev_syntax_map, &syntax_map, &prev_buffer, &buffer);
2315
2316 syntax_map.reparse(language.clone(), &buffer);
2317
2318 reference_syntax_map.clear();
2319 reference_syntax_map.reparse(language.clone(), &buffer);
2320 }
2321
2322 for i in 0..operations {
2323 let i = operations - i - 1;
2324 buffer.undo();
2325 log::info!("undoing operation {}", i);
2326 log::info!("text:\n{}", buffer.text());
2327
2328 syntax_map.interpolate(&buffer);
2329 syntax_map.reparse(language.clone(), &buffer);
2330
2331 reference_syntax_map.clear();
2332 reference_syntax_map.reparse(language.clone(), &buffer);
2333 assert_eq!(
2334 syntax_map.layers(&buffer).len(),
2335 reference_syntax_map.layers(&buffer).len(),
2336 "wrong number of layers after undoing edit {i}"
2337 );
2338 }
2339
2340 let layers = syntax_map.layers(&buffer);
2341 let reference_layers = reference_syntax_map.layers(&buffer);
2342 for (edited_layer, reference_layer) in layers.into_iter().zip(reference_layers.into_iter())
2343 {
2344 assert_eq!(edited_layer.node.to_sexp(), reference_layer.node.to_sexp());
2345 assert_eq!(edited_layer.node.range(), reference_layer.node.range());
2346 }
2347 }
2348
2349 fn check_interpolation(
2350 old_syntax_map: &SyntaxSnapshot,
2351 new_syntax_map: &SyntaxSnapshot,
2352 old_buffer: &BufferSnapshot,
2353 new_buffer: &BufferSnapshot,
2354 ) {
2355 let edits = new_buffer
2356 .edits_since::<usize>(&old_buffer.version())
2357 .collect::<Vec<_>>();
2358
2359 for (old_layer, new_layer) in old_syntax_map
2360 .layers
2361 .iter()
2362 .zip(new_syntax_map.layers.iter())
2363 {
2364 assert_eq!(old_layer.range, new_layer.range);
2365 let Some(old_tree) = old_layer.content.tree() else { continue };
2366 let Some(new_tree) = new_layer.content.tree() else { continue };
2367 let old_start_byte = old_layer.range.start.to_offset(old_buffer);
2368 let new_start_byte = new_layer.range.start.to_offset(new_buffer);
2369 let old_start_point = old_layer.range.start.to_point(old_buffer).to_ts_point();
2370 let new_start_point = new_layer.range.start.to_point(new_buffer).to_ts_point();
2371 let old_node = old_tree.root_node_with_offset(old_start_byte, old_start_point);
2372 let new_node = new_tree.root_node_with_offset(new_start_byte, new_start_point);
2373 check_node_edits(
2374 old_layer.depth,
2375 &old_layer.range,
2376 old_node,
2377 new_node,
2378 old_buffer,
2379 new_buffer,
2380 &edits,
2381 );
2382 }
2383
2384 fn check_node_edits(
2385 depth: usize,
2386 range: &Range<Anchor>,
2387 old_node: Node,
2388 new_node: Node,
2389 old_buffer: &BufferSnapshot,
2390 new_buffer: &BufferSnapshot,
2391 edits: &[text::Edit<usize>],
2392 ) {
2393 assert_eq!(old_node.kind(), new_node.kind());
2394
2395 let old_range = old_node.byte_range();
2396 let new_range = new_node.byte_range();
2397
2398 let is_edited = edits
2399 .iter()
2400 .any(|edit| edit.new.start < new_range.end && edit.new.end > new_range.start);
2401 if is_edited {
2402 assert!(
2403 new_node.has_changes(),
2404 concat!(
2405 "failed to mark node as edited.\n",
2406 "layer depth: {}, old layer range: {:?}, new layer range: {:?},\n",
2407 "node kind: {}, old node range: {:?}, new node range: {:?}",
2408 ),
2409 depth,
2410 range.to_offset(old_buffer),
2411 range.to_offset(new_buffer),
2412 new_node.kind(),
2413 old_range,
2414 new_range,
2415 );
2416 }
2417
2418 if !new_node.has_changes() {
2419 assert_eq!(
2420 old_buffer
2421 .text_for_range(old_range.clone())
2422 .collect::<String>(),
2423 new_buffer
2424 .text_for_range(new_range.clone())
2425 .collect::<String>(),
2426 concat!(
2427 "mismatched text for node\n",
2428 "layer depth: {}, old layer range: {:?}, new layer range: {:?},\n",
2429 "node kind: {}, old node range:{:?}, new node range:{:?}",
2430 ),
2431 depth,
2432 range.to_offset(old_buffer),
2433 range.to_offset(new_buffer),
2434 new_node.kind(),
2435 old_range,
2436 new_range,
2437 );
2438 }
2439
2440 for i in 0..new_node.child_count() {
2441 check_node_edits(
2442 depth,
2443 range,
2444 old_node.child(i).unwrap(),
2445 new_node.child(i).unwrap(),
2446 old_buffer,
2447 new_buffer,
2448 edits,
2449 )
2450 }
2451 }
2452 }
2453
2454 fn test_edit_sequence(language_name: &str, steps: &[&str]) -> (Buffer, SyntaxMap) {
2455 let registry = Arc::new(LanguageRegistry::test());
2456 registry.add(Arc::new(rust_lang()));
2457 registry.add(Arc::new(ruby_lang()));
2458 registry.add(Arc::new(html_lang()));
2459 registry.add(Arc::new(erb_lang()));
2460 registry.add(Arc::new(markdown_lang()));
2461 let language = registry.language_for_name(language_name).unwrap();
2462 let mut buffer = Buffer::new(0, 0, Default::default());
2463
2464 let mut mutated_syntax_map = SyntaxMap::new();
2465 mutated_syntax_map.set_language_registry(registry.clone());
2466 mutated_syntax_map.reparse(language.clone(), &buffer);
2467
2468 for (i, marked_string) in steps.into_iter().enumerate() {
2469 buffer.edit_via_marked_text(&marked_string.unindent());
2470
2471 // Reparse the syntax map
2472 mutated_syntax_map.interpolate(&buffer);
2473 mutated_syntax_map.reparse(language.clone(), &buffer);
2474
2475 // Create a second syntax map from scratch
2476 let mut reference_syntax_map = SyntaxMap::new();
2477 reference_syntax_map.set_language_registry(registry.clone());
2478 reference_syntax_map.reparse(language.clone(), &buffer);
2479
2480 // Compare the mutated syntax map to the new syntax map
2481 let mutated_layers = mutated_syntax_map.layers(&buffer);
2482 let reference_layers = reference_syntax_map.layers(&buffer);
2483 assert_eq!(
2484 mutated_layers.len(),
2485 reference_layers.len(),
2486 "wrong number of layers at step {i}"
2487 );
2488 for (edited_layer, reference_layer) in
2489 mutated_layers.into_iter().zip(reference_layers.into_iter())
2490 {
2491 assert_eq!(
2492 edited_layer.node.to_sexp(),
2493 reference_layer.node.to_sexp(),
2494 "different layer at step {i}"
2495 );
2496 assert_eq!(
2497 edited_layer.node.range(),
2498 reference_layer.node.range(),
2499 "different layer at step {i}"
2500 );
2501 }
2502 }
2503
2504 (buffer, mutated_syntax_map)
2505 }
2506
2507 fn html_lang() -> Language {
2508 Language::new(
2509 LanguageConfig {
2510 name: "HTML".into(),
2511 path_suffixes: vec!["html".to_string()],
2512 ..Default::default()
2513 },
2514 Some(tree_sitter_html::language()),
2515 )
2516 .with_highlights_query(
2517 r#"
2518 (tag_name) @tag
2519 (erroneous_end_tag_name) @tag
2520 (attribute_name) @property
2521 "#,
2522 )
2523 .unwrap()
2524 }
2525
2526 fn ruby_lang() -> Language {
2527 Language::new(
2528 LanguageConfig {
2529 name: "Ruby".into(),
2530 path_suffixes: vec!["rb".to_string()],
2531 ..Default::default()
2532 },
2533 Some(tree_sitter_ruby::language()),
2534 )
2535 .with_highlights_query(
2536 r#"
2537 ["if" "do" "else" "end"] @keyword
2538 (instance_variable) @ivar
2539 "#,
2540 )
2541 .unwrap()
2542 }
2543
2544 fn erb_lang() -> Language {
2545 Language::new(
2546 LanguageConfig {
2547 name: "ERB".into(),
2548 path_suffixes: vec!["erb".to_string()],
2549 ..Default::default()
2550 },
2551 Some(tree_sitter_embedded_template::language()),
2552 )
2553 .with_highlights_query(
2554 r#"
2555 ["<%" "%>"] @keyword
2556 "#,
2557 )
2558 .unwrap()
2559 .with_injection_query(
2560 r#"
2561 ((code) @content
2562 (#set! "language" "ruby")
2563 (#set! "combined"))
2564
2565 ((content) @content
2566 (#set! "language" "html")
2567 (#set! "combined"))
2568 "#,
2569 )
2570 .unwrap()
2571 }
2572
2573 fn rust_lang() -> Language {
2574 Language::new(
2575 LanguageConfig {
2576 name: "Rust".into(),
2577 path_suffixes: vec!["rs".to_string()],
2578 ..Default::default()
2579 },
2580 Some(tree_sitter_rust::language()),
2581 )
2582 .with_highlights_query(
2583 r#"
2584 (field_identifier) @field
2585 (struct_expression) @struct
2586 "#,
2587 )
2588 .unwrap()
2589 .with_injection_query(
2590 r#"
2591 (macro_invocation
2592 (token_tree) @content
2593 (#set! "language" "rust"))
2594 "#,
2595 )
2596 .unwrap()
2597 }
2598
2599 fn markdown_lang() -> Language {
2600 Language::new(
2601 LanguageConfig {
2602 name: "Markdown".into(),
2603 path_suffixes: vec!["md".into()],
2604 ..Default::default()
2605 },
2606 Some(tree_sitter_markdown::language()),
2607 )
2608 .with_injection_query(
2609 r#"
2610 (fenced_code_block
2611 (info_string
2612 (language) @language)
2613 (code_fence_content) @content)
2614 "#,
2615 )
2616 .unwrap()
2617 }
2618
2619 fn range_for_text(buffer: &Buffer, text: &str) -> Range<usize> {
2620 let start = buffer.as_rope().to_string().find(text).unwrap();
2621 start..start + text.len()
2622 }
2623
2624 fn assert_layers_for_range(
2625 syntax_map: &SyntaxMap,
2626 buffer: &BufferSnapshot,
2627 range: Range<Point>,
2628 expected_layers: &[&str],
2629 ) {
2630 let layers = syntax_map
2631 .layers_for_range(range, &buffer)
2632 .collect::<Vec<_>>();
2633 assert_eq!(
2634 layers.len(),
2635 expected_layers.len(),
2636 "wrong number of layers"
2637 );
2638 for (i, (SyntaxLayerInfo { node, .. }, expected_s_exp)) in
2639 layers.iter().zip(expected_layers.iter()).enumerate()
2640 {
2641 let actual_s_exp = node.to_sexp();
2642 assert!(
2643 string_contains_sequence(
2644 &actual_s_exp,
2645 &expected_s_exp.split("...").collect::<Vec<_>>()
2646 ),
2647 "layer {i}:\n\nexpected: {expected_s_exp}\nactual: {actual_s_exp}",
2648 );
2649 }
2650 }
2651
2652 fn assert_capture_ranges(
2653 syntax_map: &SyntaxMap,
2654 buffer: &BufferSnapshot,
2655 highlight_query_capture_names: &[&str],
2656 marked_string: &str,
2657 ) {
2658 let mut actual_ranges = Vec::<Range<usize>>::new();
2659 let captures = syntax_map.captures(0..buffer.len(), buffer, |grammar| {
2660 grammar.highlights_query.as_ref()
2661 });
2662 let queries = captures
2663 .grammars()
2664 .iter()
2665 .map(|grammar| grammar.highlights_query.as_ref().unwrap())
2666 .collect::<Vec<_>>();
2667 for capture in captures {
2668 let name = &queries[capture.grammar_index].capture_names()[capture.index as usize];
2669 if highlight_query_capture_names.contains(&name.as_str()) {
2670 actual_ranges.push(capture.node.byte_range());
2671 }
2672 }
2673
2674 let (text, expected_ranges) = marked_text_ranges(&marked_string.unindent(), false);
2675 assert_eq!(text, buffer.text());
2676 assert_eq!(actual_ranges, expected_ranges);
2677 }
2678
2679 pub fn string_contains_sequence(text: &str, parts: &[&str]) -> bool {
2680 let mut last_part_end = 0;
2681 for part in parts {
2682 if let Some(start_ix) = text[last_part_end..].find(part) {
2683 last_part_end = start_ix + part.len();
2684 } else {
2685 return false;
2686 }
2687 }
2688 true
2689 }
2690}