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