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