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 language_for_injection(language_name, ®istry).is_some() {
385 resolved_injection_ranges.push(layer.range.to_offset(text));
386 }
387
388 cursor.next(text);
389 }
390 drop(cursor);
391
392 if !resolved_injection_ranges.is_empty() {
393 self.reparse_with_ranges(
394 text,
395 root_language,
396 resolved_injection_ranges,
397 Some(®istry),
398 );
399 }
400 self.language_registry_version = registry.version();
401 }
402 }
403 }
404
405 fn reparse_with_ranges(
406 &mut self,
407 text: &BufferSnapshot,
408 root_language: Arc<Language>,
409 invalidated_ranges: Vec<Range<usize>>,
410 registry: Option<&Arc<LanguageRegistry>>,
411 ) {
412 let max_depth = self.layers.summary().max_depth;
413 let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
414 cursor.next(&text);
415 let mut layers = SumTree::new();
416
417 let mut changed_regions = ChangeRegionSet::default();
418 let mut queue = BinaryHeap::new();
419 let mut combined_injection_ranges = HashMap::default();
420 queue.push(ParseStep {
421 depth: 0,
422 language: ParseStepLanguage::Loaded {
423 language: root_language,
424 },
425 included_ranges: vec![tree_sitter::Range {
426 start_byte: 0,
427 end_byte: text.len(),
428 start_point: Point::zero().to_ts_point(),
429 end_point: text.max_point().to_ts_point(),
430 }],
431 range: Anchor::MIN..Anchor::MAX,
432 mode: ParseMode::Single,
433 });
434
435 loop {
436 let step = queue.pop();
437 let position = if let Some(step) = &step {
438 SyntaxLayerPosition {
439 depth: step.depth,
440 range: step.range.clone(),
441 language: step.language.id(),
442 }
443 } else {
444 SyntaxLayerPosition {
445 depth: max_depth + 1,
446 range: Anchor::MAX..Anchor::MAX,
447 language: None,
448 }
449 };
450
451 let mut done = cursor.item().is_none();
452 while !done && position.cmp(&cursor.end(text), &text).is_gt() {
453 done = true;
454
455 let bounded_position = SyntaxLayerPositionBeforeChange {
456 position: position.clone(),
457 change: changed_regions.start_position(),
458 };
459 if bounded_position.cmp(&cursor.start(), &text).is_gt() {
460 let slice = cursor.slice(&bounded_position, Bias::Left, text);
461 if !slice.is_empty() {
462 layers.push_tree(slice, &text);
463 if changed_regions.prune(cursor.end(text), text) {
464 done = false;
465 }
466 }
467 }
468
469 while position.cmp(&cursor.end(text), text).is_gt() {
470 let Some(layer) = cursor.item() else { break };
471
472 if changed_regions.intersects(&layer, text) {
473 changed_regions.insert(
474 ChangedRegion {
475 depth: layer.depth + 1,
476 range: layer.range.clone(),
477 },
478 text,
479 );
480 } else {
481 layers.push(layer.clone(), text);
482 }
483
484 cursor.next(text);
485 if changed_regions.prune(cursor.end(text), text) {
486 done = false;
487 }
488 }
489 }
490
491 let Some(step) = step else { break };
492 let (step_start_byte, step_start_point) =
493 step.range.start.summary::<(usize, Point)>(text);
494 let step_end_byte = step.range.end.to_offset(text);
495
496 let mut old_layer = cursor.item();
497 if let Some(layer) = old_layer {
498 if layer.range.to_offset(text) == (step_start_byte..step_end_byte)
499 && layer.content.language_id() == step.language.id()
500 {
501 cursor.next(&text);
502 } else {
503 old_layer = None;
504 }
505 }
506
507 let content = match step.language {
508 ParseStepLanguage::Loaded { language } => {
509 let Some(grammar) = language.grammar() else { continue };
510 let tree;
511 let changed_ranges;
512 let mut included_ranges = step.included_ranges;
513 if let Some(SyntaxLayerContent::Parsed { tree: old_tree, .. }) =
514 old_layer.map(|layer| &layer.content)
515 {
516 if let ParseMode::Combined {
517 parent_layer_changed_ranges,
518 ..
519 } = step.mode
520 {
521 included_ranges = splice_included_ranges(
522 old_tree.included_ranges(),
523 &parent_layer_changed_ranges,
524 &included_ranges,
525 );
526 }
527
528 tree = parse_text(
529 grammar,
530 text.as_rope(),
531 step_start_byte,
532 step_start_point,
533 included_ranges,
534 Some(old_tree.clone()),
535 );
536 changed_ranges = join_ranges(
537 invalidated_ranges.iter().cloned().filter(|range| {
538 range.start <= step_end_byte && range.end >= step_start_byte
539 }),
540 old_tree.changed_ranges(&tree).map(|r| {
541 step_start_byte + r.start_byte..step_start_byte + r.end_byte
542 }),
543 );
544 } else {
545 tree = parse_text(
546 grammar,
547 text.as_rope(),
548 step_start_byte,
549 step_start_point,
550 included_ranges,
551 None,
552 );
553 changed_ranges = vec![step_start_byte..step_end_byte];
554 }
555
556 if let (Some((config, registry)), false) = (
557 grammar.injection_config.as_ref().zip(registry.as_ref()),
558 changed_ranges.is_empty(),
559 ) {
560 for range in &changed_ranges {
561 changed_regions.insert(
562 ChangedRegion {
563 depth: step.depth + 1,
564 range: text.anchor_before(range.start)
565 ..text.anchor_after(range.end),
566 },
567 text,
568 );
569 }
570 get_injections(
571 config,
572 text,
573 tree.root_node_with_offset(
574 step_start_byte,
575 step_start_point.to_ts_point(),
576 ),
577 registry,
578 step.depth + 1,
579 &changed_ranges,
580 &mut combined_injection_ranges,
581 &mut queue,
582 );
583 }
584
585 SyntaxLayerContent::Parsed { tree, language }
586 }
587 ParseStepLanguage::Pending { name } => SyntaxLayerContent::Pending {
588 language_name: name,
589 },
590 };
591
592 layers.push(
593 SyntaxLayer {
594 depth: step.depth,
595 range: step.range,
596 content,
597 },
598 &text,
599 );
600 }
601
602 drop(cursor);
603 self.layers = layers;
604 self.interpolated_version = text.version.clone();
605 self.parsed_version = text.version.clone();
606 }
607
608 pub fn single_tree_captures<'a>(
609 range: Range<usize>,
610 text: &'a Rope,
611 tree: &'a Tree,
612 language: &'a Arc<Language>,
613 query: fn(&Grammar) -> Option<&Query>,
614 ) -> SyntaxMapCaptures<'a> {
615 SyntaxMapCaptures::new(
616 range.clone(),
617 text,
618 [SyntaxLayerInfo {
619 language,
620 depth: 0,
621 node: tree.root_node(),
622 }]
623 .into_iter(),
624 query,
625 )
626 }
627
628 pub fn captures<'a>(
629 &'a self,
630 range: Range<usize>,
631 buffer: &'a BufferSnapshot,
632 query: fn(&Grammar) -> Option<&Query>,
633 ) -> SyntaxMapCaptures {
634 SyntaxMapCaptures::new(
635 range.clone(),
636 buffer.as_rope(),
637 self.layers_for_range(range, buffer).into_iter(),
638 query,
639 )
640 }
641
642 pub fn matches<'a>(
643 &'a self,
644 range: Range<usize>,
645 buffer: &'a BufferSnapshot,
646 query: fn(&Grammar) -> Option<&Query>,
647 ) -> SyntaxMapMatches {
648 SyntaxMapMatches::new(
649 range.clone(),
650 buffer.as_rope(),
651 self.layers_for_range(range, buffer).into_iter(),
652 query,
653 )
654 }
655
656 #[cfg(test)]
657 pub fn layers<'a>(&'a self, buffer: &'a BufferSnapshot) -> Vec<SyntaxLayerInfo> {
658 self.layers_for_range(0..buffer.len(), buffer).collect()
659 }
660
661 pub fn layers_for_range<'a, T: ToOffset>(
662 &'a self,
663 range: Range<T>,
664 buffer: &'a BufferSnapshot,
665 ) -> impl 'a + Iterator<Item = SyntaxLayerInfo> {
666 let start = buffer.anchor_before(range.start.to_offset(buffer));
667 let end = buffer.anchor_after(range.end.to_offset(buffer));
668
669 let mut cursor = self.layers.filter::<_, ()>(move |summary| {
670 if summary.max_depth > summary.min_depth {
671 true
672 } else {
673 let is_before_start = summary.range.end.cmp(&start, buffer).is_lt();
674 let is_after_end = summary.range.start.cmp(&end, buffer).is_gt();
675 !is_before_start && !is_after_end
676 }
677 });
678
679 cursor.next(buffer);
680 iter::from_fn(move || {
681 while let Some(layer) = cursor.item() {
682 if let SyntaxLayerContent::Parsed { tree, language } = &layer.content {
683 let info = SyntaxLayerInfo {
684 language,
685 depth: layer.depth,
686 node: tree.root_node_with_offset(
687 layer.range.start.to_offset(buffer),
688 layer.range.start.to_point(buffer).to_ts_point(),
689 ),
690 };
691 cursor.next(buffer);
692 return Some(info);
693 } else {
694 cursor.next(buffer);
695 }
696 }
697 None
698 })
699 }
700
701 pub fn contains_unknown_injections(&self) -> bool {
702 self.layers.summary().contains_unknown_injections
703 }
704
705 pub fn language_registry_version(&self) -> usize {
706 self.language_registry_version
707 }
708}
709
710impl<'a> SyntaxMapCaptures<'a> {
711 fn new(
712 range: Range<usize>,
713 text: &'a Rope,
714 layers: impl Iterator<Item = SyntaxLayerInfo<'a>>,
715 query: fn(&Grammar) -> Option<&Query>,
716 ) -> Self {
717 let mut result = Self {
718 layers: Vec::new(),
719 grammars: Vec::new(),
720 active_layer_count: 0,
721 };
722 for SyntaxLayerInfo {
723 language,
724 depth,
725 node,
726 } in layers
727 {
728 let grammar = match &language.grammar {
729 Some(grammer) => grammer,
730 None => continue,
731 };
732 let query = match query(&grammar) {
733 Some(query) => query,
734 None => continue,
735 };
736
737 let mut query_cursor = QueryCursorHandle::new();
738
739 // TODO - add a Tree-sitter API to remove the need for this.
740 let cursor = unsafe {
741 std::mem::transmute::<_, &'static mut QueryCursor>(query_cursor.deref_mut())
742 };
743
744 cursor.set_byte_range(range.clone());
745 let captures = cursor.captures(query, node, TextProvider(text));
746 let grammar_index = result
747 .grammars
748 .iter()
749 .position(|g| g.id == grammar.id())
750 .unwrap_or_else(|| {
751 result.grammars.push(grammar);
752 result.grammars.len() - 1
753 });
754 let mut layer = SyntaxMapCapturesLayer {
755 depth,
756 grammar_index,
757 next_capture: None,
758 captures,
759 _query_cursor: query_cursor,
760 };
761
762 layer.advance();
763 if layer.next_capture.is_some() {
764 let key = layer.sort_key();
765 let ix = match result.layers[..result.active_layer_count]
766 .binary_search_by_key(&key, |layer| layer.sort_key())
767 {
768 Ok(ix) | Err(ix) => ix,
769 };
770 result.layers.insert(ix, layer);
771 result.active_layer_count += 1;
772 } else {
773 result.layers.push(layer);
774 }
775 }
776
777 result
778 }
779
780 pub fn grammars(&self) -> &[&'a Grammar] {
781 &self.grammars
782 }
783
784 pub fn peek(&self) -> Option<SyntaxMapCapture<'a>> {
785 let layer = self.layers[..self.active_layer_count].first()?;
786 let capture = layer.next_capture?;
787 Some(SyntaxMapCapture {
788 depth: layer.depth,
789 grammar_index: layer.grammar_index,
790 index: capture.index,
791 node: capture.node,
792 })
793 }
794
795 pub fn advance(&mut self) -> bool {
796 let layer = if let Some(layer) = self.layers[..self.active_layer_count].first_mut() {
797 layer
798 } else {
799 return false;
800 };
801
802 layer.advance();
803 if layer.next_capture.is_some() {
804 let key = layer.sort_key();
805 let i = 1 + self.layers[1..self.active_layer_count]
806 .iter()
807 .position(|later_layer| key < later_layer.sort_key())
808 .unwrap_or(self.active_layer_count - 1);
809 self.layers[0..i].rotate_left(1);
810 } else {
811 self.layers[0..self.active_layer_count].rotate_left(1);
812 self.active_layer_count -= 1;
813 }
814
815 true
816 }
817
818 pub fn set_byte_range(&mut self, range: Range<usize>) {
819 for layer in &mut self.layers {
820 layer.captures.set_byte_range(range.clone());
821 if let Some(capture) = &layer.next_capture {
822 if capture.node.end_byte() > range.start {
823 continue;
824 }
825 }
826 layer.advance();
827 }
828 self.layers.sort_unstable_by_key(|layer| layer.sort_key());
829 self.active_layer_count = self
830 .layers
831 .iter()
832 .position(|layer| layer.next_capture.is_none())
833 .unwrap_or(self.layers.len());
834 }
835}
836
837impl<'a> SyntaxMapMatches<'a> {
838 fn new(
839 range: Range<usize>,
840 text: &'a Rope,
841 layers: impl Iterator<Item = SyntaxLayerInfo<'a>>,
842 query: fn(&Grammar) -> Option<&Query>,
843 ) -> Self {
844 let mut result = Self::default();
845 for SyntaxLayerInfo {
846 language,
847 depth,
848 node,
849 } in layers
850 {
851 let grammar = match &language.grammar {
852 Some(grammer) => grammer,
853 None => continue,
854 };
855 let query = match query(&grammar) {
856 Some(query) => query,
857 None => continue,
858 };
859
860 let mut query_cursor = QueryCursorHandle::new();
861
862 // TODO - add a Tree-sitter API to remove the need for this.
863 let cursor = unsafe {
864 std::mem::transmute::<_, &'static mut QueryCursor>(query_cursor.deref_mut())
865 };
866
867 cursor.set_byte_range(range.clone());
868 let matches = cursor.matches(query, node, TextProvider(text));
869 let grammar_index = result
870 .grammars
871 .iter()
872 .position(|g| g.id == grammar.id())
873 .unwrap_or_else(|| {
874 result.grammars.push(grammar);
875 result.grammars.len() - 1
876 });
877 let mut layer = SyntaxMapMatchesLayer {
878 depth,
879 grammar_index,
880 matches,
881 next_pattern_index: 0,
882 next_captures: Vec::new(),
883 has_next: false,
884 _query_cursor: query_cursor,
885 };
886
887 layer.advance();
888 if layer.has_next {
889 let key = layer.sort_key();
890 let ix = match result.layers[..result.active_layer_count]
891 .binary_search_by_key(&key, |layer| layer.sort_key())
892 {
893 Ok(ix) | Err(ix) => ix,
894 };
895 result.layers.insert(ix, layer);
896 result.active_layer_count += 1;
897 } else {
898 result.layers.push(layer);
899 }
900 }
901 result
902 }
903
904 pub fn grammars(&self) -> &[&'a Grammar] {
905 &self.grammars
906 }
907
908 pub fn peek(&self) -> Option<SyntaxMapMatch> {
909 let layer = self.layers.first()?;
910 if !layer.has_next {
911 return None;
912 }
913 Some(SyntaxMapMatch {
914 depth: layer.depth,
915 grammar_index: layer.grammar_index,
916 pattern_index: layer.next_pattern_index,
917 captures: &layer.next_captures,
918 })
919 }
920
921 pub fn advance(&mut self) -> bool {
922 let layer = if let Some(layer) = self.layers.first_mut() {
923 layer
924 } else {
925 return false;
926 };
927
928 layer.advance();
929 if layer.has_next {
930 let key = layer.sort_key();
931 let i = 1 + self.layers[1..self.active_layer_count]
932 .iter()
933 .position(|later_layer| key < later_layer.sort_key())
934 .unwrap_or(self.active_layer_count - 1);
935 self.layers[0..i].rotate_left(1);
936 } else {
937 self.layers[0..self.active_layer_count].rotate_left(1);
938 self.active_layer_count -= 1;
939 }
940
941 true
942 }
943}
944
945impl<'a> SyntaxMapCapturesLayer<'a> {
946 fn advance(&mut self) {
947 self.next_capture = self.captures.next().map(|(mat, ix)| mat.captures[ix]);
948 }
949
950 fn sort_key(&self) -> (usize, Reverse<usize>, usize) {
951 if let Some(capture) = &self.next_capture {
952 let range = capture.node.byte_range();
953 (range.start, Reverse(range.end), self.depth)
954 } else {
955 (usize::MAX, Reverse(0), usize::MAX)
956 }
957 }
958}
959
960impl<'a> SyntaxMapMatchesLayer<'a> {
961 fn advance(&mut self) {
962 if let Some(mat) = self.matches.next() {
963 self.next_captures.clear();
964 self.next_captures.extend_from_slice(&mat.captures);
965 self.next_pattern_index = mat.pattern_index;
966 self.has_next = true;
967 } else {
968 self.has_next = false;
969 }
970 }
971
972 fn sort_key(&self) -> (usize, Reverse<usize>, usize) {
973 if self.has_next {
974 let captures = &self.next_captures;
975 if let Some((first, last)) = captures.first().zip(captures.last()) {
976 return (
977 first.node.start_byte(),
978 Reverse(last.node.end_byte()),
979 self.depth,
980 );
981 }
982 }
983 (usize::MAX, Reverse(0), usize::MAX)
984 }
985}
986
987impl<'a> Iterator for SyntaxMapCaptures<'a> {
988 type Item = SyntaxMapCapture<'a>;
989
990 fn next(&mut self) -> Option<Self::Item> {
991 let result = self.peek();
992 self.advance();
993 result
994 }
995}
996
997fn join_ranges(
998 a: impl Iterator<Item = Range<usize>>,
999 b: impl Iterator<Item = Range<usize>>,
1000) -> Vec<Range<usize>> {
1001 let mut result = Vec::<Range<usize>>::new();
1002 let mut a = a.peekable();
1003 let mut b = b.peekable();
1004 loop {
1005 let range = match (a.peek(), b.peek()) {
1006 (Some(range_a), Some(range_b)) => {
1007 if range_a.start < range_b.start {
1008 a.next().unwrap()
1009 } else {
1010 b.next().unwrap()
1011 }
1012 }
1013 (None, Some(_)) => b.next().unwrap(),
1014 (Some(_), None) => a.next().unwrap(),
1015 (None, None) => break,
1016 };
1017
1018 if let Some(last) = result.last_mut() {
1019 if range.start <= last.end {
1020 last.end = last.end.max(range.end);
1021 continue;
1022 }
1023 }
1024 result.push(range);
1025 }
1026 result
1027}
1028
1029fn parse_text(
1030 grammar: &Grammar,
1031 text: &Rope,
1032 start_byte: usize,
1033 start_point: Point,
1034 mut ranges: Vec<tree_sitter::Range>,
1035 old_tree: Option<Tree>,
1036) -> Tree {
1037 for range in &mut ranges {
1038 range.start_byte -= start_byte;
1039 range.end_byte -= start_byte;
1040 range.start_point = (Point::from_ts_point(range.start_point) - start_point).to_ts_point();
1041 range.end_point = (Point::from_ts_point(range.end_point) - start_point).to_ts_point();
1042 }
1043
1044 PARSER.with(|parser| {
1045 let mut parser = parser.borrow_mut();
1046 let mut chunks = text.chunks_in_range(start_byte..text.len());
1047 parser
1048 .set_included_ranges(&ranges)
1049 .expect("overlapping ranges");
1050 parser
1051 .set_language(grammar.ts_language)
1052 .expect("incompatible grammar");
1053 parser
1054 .parse_with(
1055 &mut move |offset, _| {
1056 chunks.seek(start_byte + offset);
1057 chunks.next().unwrap_or("").as_bytes()
1058 },
1059 old_tree.as_ref(),
1060 )
1061 .expect("invalid language")
1062 })
1063}
1064
1065fn get_injections(
1066 config: &InjectionConfig,
1067 text: &BufferSnapshot,
1068 node: Node,
1069 language_registry: &LanguageRegistry,
1070 depth: usize,
1071 changed_ranges: &[Range<usize>],
1072 combined_injection_ranges: &mut HashMap<Arc<Language>, Vec<tree_sitter::Range>>,
1073 queue: &mut BinaryHeap<ParseStep>,
1074) {
1075 let mut query_cursor = QueryCursorHandle::new();
1076 let mut prev_match = None;
1077
1078 combined_injection_ranges.clear();
1079 for pattern in &config.patterns {
1080 if let (Some(language_name), true) = (pattern.language.as_ref(), pattern.combined) {
1081 if let Some(language) = language_for_injection(language_name, language_registry) {
1082 combined_injection_ranges.insert(language, Vec::new());
1083 }
1084 }
1085 }
1086
1087 for query_range in changed_ranges {
1088 query_cursor.set_byte_range(query_range.start.saturating_sub(1)..query_range.end + 1);
1089 for mat in query_cursor.matches(&config.query, node, TextProvider(text.as_rope())) {
1090 let content_ranges = mat
1091 .nodes_for_capture_index(config.content_capture_ix)
1092 .map(|node| node.range())
1093 .collect::<Vec<_>>();
1094 if content_ranges.is_empty() {
1095 continue;
1096 }
1097
1098 // Avoid duplicate matches if two changed ranges intersect the same injection.
1099 let content_range =
1100 content_ranges.first().unwrap().start_byte..content_ranges.last().unwrap().end_byte;
1101 if let Some((last_pattern_ix, last_range)) = &prev_match {
1102 if mat.pattern_index == *last_pattern_ix && content_range == *last_range {
1103 continue;
1104 }
1105 }
1106 prev_match = Some((mat.pattern_index, content_range.clone()));
1107
1108 let combined = config.patterns[mat.pattern_index].combined;
1109
1110 let mut language_name = None;
1111 let mut step_range = content_range.clone();
1112 if let Some(name) = config.patterns[mat.pattern_index].language.as_ref() {
1113 language_name = Some(Cow::Borrowed(name.as_ref()))
1114 } else if let Some(language_node) = config
1115 .language_capture_ix
1116 .and_then(|ix| mat.nodes_for_capture_index(ix).next())
1117 {
1118 step_range.start = cmp::min(content_range.start, language_node.start_byte());
1119 step_range.end = cmp::max(content_range.end, language_node.end_byte());
1120 language_name = Some(Cow::Owned(
1121 text.text_for_range(language_node.byte_range()).collect(),
1122 ))
1123 };
1124
1125 if let Some(language_name) = language_name {
1126 let language = language_for_injection(&language_name, language_registry);
1127 let range = text.anchor_before(step_range.start)..text.anchor_after(step_range.end);
1128 if let Some(language) = language {
1129 if combined {
1130 combined_injection_ranges
1131 .get_mut(&language.clone())
1132 .unwrap()
1133 .extend(content_ranges);
1134 } else {
1135 queue.push(ParseStep {
1136 depth,
1137 language: ParseStepLanguage::Loaded { language },
1138 included_ranges: content_ranges,
1139 range,
1140 mode: ParseMode::Single,
1141 });
1142 }
1143 } else {
1144 queue.push(ParseStep {
1145 depth,
1146 language: ParseStepLanguage::Pending {
1147 name: language_name.into(),
1148 },
1149 included_ranges: content_ranges,
1150 range,
1151 mode: ParseMode::Single,
1152 });
1153 }
1154 }
1155 }
1156 }
1157
1158 for (language, mut included_ranges) in combined_injection_ranges.drain() {
1159 included_ranges.sort_unstable();
1160 let range = text.anchor_before(node.start_byte())..text.anchor_after(node.end_byte());
1161 queue.push(ParseStep {
1162 depth,
1163 language: ParseStepLanguage::Loaded { language },
1164 range,
1165 included_ranges,
1166 mode: ParseMode::Combined {
1167 parent_layer_range: node.start_byte()..node.end_byte(),
1168 parent_layer_changed_ranges: changed_ranges.to_vec(),
1169 },
1170 })
1171 }
1172}
1173
1174fn language_for_injection(
1175 language_name: &str,
1176 language_registry: &LanguageRegistry,
1177) -> Option<Arc<Language>> {
1178 language_registry
1179 .language_for_name(language_name)
1180 .or_else(|| language_registry.language_for_extension(language_name))
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}