1use crate::{
2 Grammar, InjectionConfig, Language, LanguageRegistry, QueryCursorHandle, TextProvider,
3 ToTreeSitterPoint,
4};
5use collections::HashMap;
6use std::{
7 borrow::Cow, cell::RefCell, cmp::Ordering, collections::BinaryHeap, ops::Range, sync::Arc,
8};
9use sum_tree::{Bias, SeekTarget, SumTree};
10use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint};
11use tree_sitter::{Parser, Tree};
12use util::post_inc;
13
14thread_local! {
15 static PARSER: RefCell<Parser> = RefCell::new(Parser::new());
16}
17
18#[derive(Default)]
19pub struct SyntaxMap {
20 version: clock::Global,
21 snapshot: SyntaxSnapshot,
22 language_registry: Option<Arc<LanguageRegistry>>,
23}
24
25#[derive(Clone, Default)]
26pub struct SyntaxSnapshot {
27 layers: SumTree<SyntaxLayer>,
28}
29
30#[derive(Clone)]
31struct SyntaxLayer {
32 depth: usize,
33 range: Range<Anchor>,
34 tree: tree_sitter::Tree,
35 language: Arc<Language>,
36}
37
38#[derive(Debug, Clone)]
39struct SyntaxLayerSummary {
40 max_depth: usize,
41 range: Range<Anchor>,
42 last_layer_range: Range<Anchor>,
43}
44
45#[derive(Clone, Debug)]
46struct Depth(usize);
47
48#[derive(Clone, Debug)]
49struct MaxPosition(Anchor);
50
51enum ReparseStep {
52 CreateLayer {
53 depth: usize,
54 language: Arc<Language>,
55 ranges: Vec<tree_sitter::Range>,
56 },
57 EnterChangedRange {
58 id: usize,
59 depth: usize,
60 range: Range<usize>,
61 },
62 LeaveChangedRange {
63 id: usize,
64 depth: usize,
65 range: Range<usize>,
66 },
67}
68
69impl SyntaxMap {
70 pub fn new() -> Self {
71 Self::default()
72 }
73
74 pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) {
75 self.language_registry = Some(registry);
76 }
77
78 pub fn snapshot(&self) -> SyntaxSnapshot {
79 self.snapshot.clone()
80 }
81
82 pub fn interpolate(&mut self, text: &BufferSnapshot) {
83 self.snapshot.interpolate(&self.version, text);
84 self.version = text.version.clone();
85 }
86
87 pub fn reparse(&mut self, language: Arc<Language>, text: &BufferSnapshot) {
88 self.version = text.version.clone();
89 self.snapshot
90 .reparse(self.language_registry.clone(), language, text);
91 }
92}
93
94// Assumptions:
95// * The maximum depth is small (< 5)
96// * For a given depth, the number of layers that touch a given range
97// is small (usually only 1)
98
99// |change|
100// 0 (............................................................)
101// 1 (...............................................)
102// 1 (................)
103// 1 (.......)
104// 2 (....)
105// 2 (....)
106// 2 (.......)
107// 2 (...)
108// 2 (.........)
109// 2 (...)
110// 3 (.)
111// 3 (.)
112// 3 (..)
113// 3 (..)
114// 3 (..)
115// 3 (.)
116
117impl SyntaxSnapshot {
118 pub fn interpolate(&mut self, current_version: &clock::Global, text: &BufferSnapshot) {
119 let edits = text
120 .edits_since::<(usize, Point)>(¤t_version)
121 .collect::<Vec<_>>();
122 if edits.is_empty() {
123 return;
124 }
125
126 let mut layers = SumTree::new();
127 let max_depth = self.layers.summary().max_depth;
128 let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
129 cursor.next(&text);
130
131 for depth in 0..=max_depth {
132 let mut edits = &edits[..];
133 layers.push_tree(cursor.slice(&Depth(depth), Bias::Left, text), text);
134
135 while let Some(layer) = cursor.item() {
136 let mut endpoints = text.summaries_for_anchors::<(usize, Point), _>([
137 &layer.range.start,
138 &layer.range.end,
139 ]);
140 let layer_range = endpoints.next().unwrap()..endpoints.next().unwrap();
141 let start_byte = layer_range.start.0;
142 let start_point = layer_range.start.1;
143
144 // Preserve any layers at this depth that precede the first edit.
145 let first_edit = if let Some(edit) = edits.first() {
146 edit
147 } else {
148 break;
149 };
150 if first_edit.new.start.0 > layer_range.end.0 {
151 layers.push_tree(
152 cursor.slice(
153 &(
154 Depth(depth),
155 MaxPosition(text.anchor_before(first_edit.new.start.0)),
156 ),
157 Bias::Left,
158 text,
159 ),
160 text,
161 );
162 continue;
163 }
164
165 // Preserve any layers at this depth that follow the last edit.
166 let last_edit = edits.last().unwrap();
167 if last_edit.new.end.0 < layer_range.start.0 {
168 break;
169 }
170
171 let mut layer = layer.clone();
172 for (i, edit) in edits.iter().enumerate().rev() {
173 // Ignore any edits that start after the end of this layer.
174 if edit.new.start.0 > layer_range.end.0 {
175 continue;
176 }
177
178 // Ignore edits that end before the start of this layer, and don't consider them
179 // for any subsequent layers at this same depth.
180 if edit.new.end.0 <= start_byte {
181 edits = &edits[i + 1..];
182 break;
183 }
184
185 // Apply any edits that intersect this layer to the layer's syntax tree.
186 if edit.new.start.0 >= start_byte {
187 layer.tree.edit(&tree_sitter::InputEdit {
188 start_byte: edit.new.start.0 - start_byte,
189 old_end_byte: edit.new.start.0 - start_byte
190 + (edit.old.end.0 - edit.old.start.0),
191 new_end_byte: edit.new.end.0 - start_byte,
192 start_position: (edit.new.start.1 - start_point).to_ts_point(),
193 old_end_position: (edit.new.start.1 - start_point
194 + (edit.old.end.1 - edit.old.start.1))
195 .to_ts_point(),
196 new_end_position: (edit.new.end.1 - start_point).to_ts_point(),
197 });
198 } else {
199 layer.tree.edit(&tree_sitter::InputEdit {
200 start_byte: 0,
201 old_end_byte: edit.new.end.0 - start_byte,
202 new_end_byte: 0,
203 start_position: Default::default(),
204 old_end_position: (edit.new.end.1 - start_point).to_ts_point(),
205 new_end_position: Default::default(),
206 });
207 break;
208 }
209 }
210
211 layers.push(layer, text);
212 cursor.next(text);
213 }
214 }
215
216 layers.push_tree(cursor.suffix(&text), &text);
217 drop(cursor);
218 self.layers = layers;
219 }
220
221 pub fn reparse(
222 &mut self,
223 registry: Option<Arc<LanguageRegistry>>,
224 language: Arc<Language>,
225 text: &BufferSnapshot,
226 ) {
227 let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
228 cursor.next(&text);
229 let mut layers = SumTree::new();
230
231 let mut next_change_id = 0;
232 let mut current_changes = HashMap::default();
233 let mut queue = BinaryHeap::new();
234 queue.push(ReparseStep::CreateLayer {
235 depth: 0,
236 language: language.clone(),
237 ranges: Vec::new(),
238 });
239
240 while let Some(step) = queue.pop() {
241 match step {
242 ReparseStep::CreateLayer {
243 depth,
244 language,
245 ranges,
246 } => {
247 let range;
248 let start_point;
249 let start_byte;
250 let end_byte;
251 if let Some((first, last)) = ranges.first().zip(ranges.last()) {
252 start_point = first.start_point;
253 start_byte = first.start_byte;
254 end_byte = last.end_byte;
255 range = text.anchor_before(start_byte)..text.anchor_after(end_byte);
256 } else {
257 start_point = Point::zero().to_ts_point();
258 start_byte = 0;
259 end_byte = text.len();
260 range = Anchor::MIN..Anchor::MAX;
261 };
262
263 let target = (Depth(depth), range.clone());
264 if target.cmp(cursor.start(), &text).is_gt() {
265 if current_changes.is_empty() {
266 let slice = cursor.slice(&target, Bias::Left, text);
267 layers.push_tree(slice, &text);
268 } else {
269 while let Some(layer) = cursor.item() {
270 if layer.depth > depth
271 || layer.depth == depth
272 && layer.range.start.cmp(&range.end, text).is_ge()
273 {
274 break;
275 }
276 if !layer_is_changed(layer, text, ¤t_changes) {
277 layers.push(layer.clone(), text);
278 }
279 cursor.next(text);
280 }
281 }
282 }
283
284 let mut old_layer = cursor.item();
285 if let Some(layer) = old_layer {
286 if layer.range.to_offset(text) == (start_byte..end_byte) {
287 cursor.next(&text);
288 } else {
289 old_layer = None;
290 }
291 }
292
293 let grammar = if let Some(grammar) = language.grammar.as_deref() {
294 grammar
295 } else {
296 continue;
297 };
298
299 let tree;
300 let changed_ranges;
301 if let Some(old_layer) = old_layer {
302 tree = parse_text(
303 grammar,
304 text.as_rope(),
305 Some(old_layer.tree.clone()),
306 ranges,
307 );
308
309 changed_ranges = old_layer
310 .tree
311 .changed_ranges(&tree)
312 .map(|r| r.start_byte..r.end_byte)
313 .collect();
314 } else {
315 tree = parse_text(grammar, text.as_rope(), None, ranges);
316 changed_ranges = vec![0..end_byte - start_byte];
317 }
318
319 layers.push(
320 SyntaxLayer {
321 depth,
322 range,
323 tree: tree.clone(),
324 language: language.clone(),
325 },
326 &text,
327 );
328
329 if let (Some((config, registry)), false) = (
330 grammar.injection_config.as_ref().zip(registry.as_ref()),
331 changed_ranges.is_empty(),
332 ) {
333 let depth = depth + 1;
334 queue.extend(changed_ranges.iter().flat_map(|range| {
335 let id = post_inc(&mut next_change_id);
336 let range = start_byte + range.start..start_byte + range.end;
337 [
338 ReparseStep::EnterChangedRange {
339 id,
340 depth,
341 range: range.clone(),
342 },
343 ReparseStep::LeaveChangedRange {
344 id,
345 depth,
346 range: range.clone(),
347 },
348 ]
349 }));
350
351 get_injections(
352 config,
353 text,
354 &tree,
355 registry,
356 depth,
357 start_byte,
358 Point::from_ts_point(start_point),
359 &changed_ranges,
360 &mut queue,
361 );
362 }
363 }
364 ReparseStep::EnterChangedRange { id, depth, range } => {
365 let range = text.anchor_before(range.start)..text.anchor_after(range.end);
366 if current_changes.is_empty() {
367 let target = (Depth(depth), range.start..Anchor::MAX);
368 let slice = cursor.slice(&target, Bias::Left, text);
369 layers.push_tree(slice, text);
370 } else {
371 while let Some(layer) = cursor.item() {
372 if layer.depth > depth
373 || layer.depth == depth
374 && layer.range.end.cmp(&range.start, text).is_gt()
375 {
376 break;
377 }
378 if !layer_is_changed(layer, text, ¤t_changes) {
379 layers.push(layer.clone(), text);
380 }
381 cursor.next(text);
382 }
383 }
384
385 current_changes.insert(id, range);
386 }
387 ReparseStep::LeaveChangedRange { id, depth, range } => {
388 let range = text.anchor_before(range.start)..text.anchor_after(range.end);
389 while let Some(layer) = cursor.item() {
390 if layer.depth > depth
391 || layer.depth == depth
392 && layer.range.start.cmp(&range.end, text).is_ge()
393 {
394 break;
395 }
396 if !layer_is_changed(layer, text, ¤t_changes) {
397 layers.push(layer.clone(), text);
398 }
399 cursor.next(text);
400 }
401
402 current_changes.remove(&id);
403 }
404 }
405 }
406
407 let slice = cursor.suffix(&text);
408 layers.push_tree(slice, &text);
409 drop(cursor);
410 self.layers = layers;
411 }
412
413 pub fn layers(&self, buffer: &BufferSnapshot) -> Vec<(&Grammar, &Tree, (usize, Point))> {
414 self.layers
415 .iter()
416 .filter_map(|layer| {
417 if let Some(grammar) = &layer.language.grammar {
418 Some((
419 grammar.as_ref(),
420 &layer.tree,
421 (
422 layer.range.start.to_offset(buffer),
423 layer.range.start.to_point(buffer),
424 ),
425 ))
426 } else {
427 None
428 }
429 })
430 .collect()
431 }
432
433 pub fn layers_for_range<'a, T: ToOffset>(
434 &self,
435 range: Range<T>,
436 buffer: &BufferSnapshot,
437 ) -> Vec<(&Grammar, &Tree, (usize, Point))> {
438 let start = buffer.anchor_before(range.start.to_offset(buffer));
439 let end = buffer.anchor_after(range.end.to_offset(buffer));
440
441 let mut cursor = self.layers.filter::<_, ()>(|summary| {
442 let is_before_start = summary.range.end.cmp(&start, buffer).is_lt();
443 let is_after_end = summary.range.start.cmp(&end, buffer).is_gt();
444 !is_before_start && !is_after_end
445 });
446
447 let mut result = Vec::new();
448 cursor.next(buffer);
449 while let Some(layer) = cursor.item() {
450 if let Some(grammar) = &layer.language.grammar {
451 result.push((
452 grammar.as_ref(),
453 &layer.tree,
454 (
455 layer.range.start.to_offset(buffer),
456 layer.range.start.to_point(buffer),
457 ),
458 ));
459 }
460 cursor.next(buffer)
461 }
462
463 result
464 }
465}
466
467fn parse_text(
468 grammar: &Grammar,
469 text: &Rope,
470 old_tree: Option<Tree>,
471 mut ranges: Vec<tree_sitter::Range>,
472) -> Tree {
473 let (start_byte, start_point) = ranges
474 .first()
475 .map(|range| (range.start_byte, Point::from_ts_point(range.start_point)))
476 .unwrap_or_default();
477
478 for range in &mut ranges {
479 range.start_byte -= start_byte;
480 range.end_byte -= start_byte;
481 range.start_point = (Point::from_ts_point(range.start_point) - start_point).to_ts_point();
482 range.end_point = (Point::from_ts_point(range.end_point) - start_point).to_ts_point();
483 }
484
485 PARSER.with(|parser| {
486 let mut parser = parser.borrow_mut();
487 let mut chunks = text.chunks_in_range(start_byte..text.len());
488 parser
489 .set_included_ranges(&ranges)
490 .expect("overlapping ranges");
491 parser
492 .set_language(grammar.ts_language)
493 .expect("incompatible grammar");
494 parser
495 .parse_with(
496 &mut move |offset, _| {
497 chunks.seek(start_byte + offset);
498 chunks.next().unwrap_or("").as_bytes()
499 },
500 old_tree.as_ref(),
501 )
502 .expect("invalid language")
503 })
504}
505
506fn get_injections(
507 config: &InjectionConfig,
508 text: &BufferSnapshot,
509 tree: &Tree,
510 language_registry: &LanguageRegistry,
511 depth: usize,
512 start_byte: usize,
513 start_point: Point,
514 query_ranges: &[Range<usize>],
515 stack: &mut BinaryHeap<ReparseStep>,
516) -> bool {
517 let mut result = false;
518 let mut query_cursor = QueryCursorHandle::new();
519 let mut prev_match = None;
520 for query_range in query_ranges {
521 query_cursor.set_byte_range(query_range.start..query_range.end);
522 for mat in query_cursor.matches(
523 &config.query,
524 tree.root_node(),
525 TextProvider(text.as_rope()),
526 ) {
527 let content_ranges = mat
528 .nodes_for_capture_index(config.content_capture_ix)
529 .map(|node| tree_sitter::Range {
530 start_byte: start_byte + node.start_byte(),
531 end_byte: start_byte + node.end_byte(),
532 start_point: (start_point + Point::from_ts_point(node.start_position()))
533 .to_ts_point(),
534 end_point: (start_point + Point::from_ts_point(node.end_position()))
535 .to_ts_point(),
536 })
537 .collect::<Vec<_>>();
538 if content_ranges.is_empty() {
539 continue;
540 }
541
542 // Avoid duplicate matches if two changed ranges intersect the same injection.
543 let content_range =
544 content_ranges.first().unwrap().start_byte..content_ranges.last().unwrap().end_byte;
545 if let Some((last_pattern_ix, last_range)) = &prev_match {
546 if mat.pattern_index == *last_pattern_ix && content_range == *last_range {
547 continue;
548 }
549 }
550 prev_match = Some((mat.pattern_index, content_range));
551
552 let language_name = config.languages_by_pattern_ix[mat.pattern_index]
553 .as_ref()
554 .map(|s| Cow::Borrowed(s.as_ref()))
555 .or_else(|| {
556 let ix = config.language_capture_ix?;
557 let node = mat.nodes_for_capture_index(ix).next()?;
558 Some(Cow::Owned(
559 text.text_for_range(
560 start_byte + node.start_byte()..start_byte + node.end_byte(),
561 )
562 .collect(),
563 ))
564 });
565
566 if let Some(language_name) = language_name {
567 if let Some(language) = language_registry.get_language(language_name.as_ref()) {
568 result = true;
569 stack.push(ReparseStep::CreateLayer {
570 depth,
571 language,
572 ranges: content_ranges,
573 })
574 }
575 }
576 }
577 }
578 result
579}
580
581fn layer_is_changed(
582 layer: &SyntaxLayer,
583 text: &BufferSnapshot,
584 changed_ranges: &HashMap<usize, Range<Anchor>>,
585) -> bool {
586 changed_ranges.values().any(|range| {
587 let is_before_layer = range.end.cmp(&layer.range.start, text).is_le();
588 let is_after_layer = range.start.cmp(&layer.range.end, text).is_ge();
589 !is_before_layer && !is_after_layer
590 })
591}
592
593impl std::ops::Deref for SyntaxMap {
594 type Target = SyntaxSnapshot;
595
596 fn deref(&self) -> &Self::Target {
597 &self.snapshot
598 }
599}
600
601impl ReparseStep {
602 fn sort_key(&self) -> (usize, Range<usize>) {
603 match self {
604 ReparseStep::CreateLayer { depth, ranges, .. } => (
605 *depth,
606 ranges.first().map_or(0, |r| r.start_byte)
607 ..ranges.last().map_or(usize::MAX, |r| r.end_byte),
608 ),
609 ReparseStep::EnterChangedRange { depth, range, .. } => {
610 (*depth, range.start..usize::MAX)
611 }
612 ReparseStep::LeaveChangedRange { depth, range, .. } => (*depth, range.end..usize::MAX),
613 }
614 }
615}
616
617impl PartialEq for ReparseStep {
618 fn eq(&self, _: &Self) -> bool {
619 false
620 }
621}
622
623impl Eq for ReparseStep {}
624
625impl PartialOrd for ReparseStep {
626 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
627 Some(self.cmp(&other))
628 }
629}
630
631impl Ord for ReparseStep {
632 fn cmp(&self, other: &Self) -> Ordering {
633 let (depth_a, range_a) = self.sort_key();
634 let (depth_b, range_b) = other.sort_key();
635 Ord::cmp(&depth_b, &depth_a)
636 .then_with(|| Ord::cmp(&range_b.start, &range_a.start))
637 .then_with(|| Ord::cmp(&range_a.end, &range_b.end))
638 }
639}
640
641impl Default for SyntaxLayerSummary {
642 fn default() -> Self {
643 Self {
644 max_depth: 0,
645 range: Anchor::MAX..Anchor::MIN,
646 last_layer_range: Anchor::MIN..Anchor::MAX,
647 }
648 }
649}
650
651impl sum_tree::Summary for SyntaxLayerSummary {
652 type Context = BufferSnapshot;
653
654 fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
655 if other.max_depth > self.max_depth {
656 *self = other.clone();
657 } else {
658 if other.range.start.cmp(&self.range.start, buffer).is_lt() {
659 self.range.start = other.range.start;
660 }
661 if other.range.end.cmp(&self.range.end, buffer).is_gt() {
662 self.range.end = other.range.end;
663 }
664 self.last_layer_range = other.last_layer_range.clone();
665 }
666 }
667}
668
669impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for Depth {
670 fn cmp(&self, cursor_location: &SyntaxLayerSummary, _: &BufferSnapshot) -> Ordering {
671 Ord::cmp(&self.0, &cursor_location.max_depth)
672 }
673}
674
675impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for (Depth, MaxPosition) {
676 fn cmp(&self, cursor_location: &SyntaxLayerSummary, text: &BufferSnapshot) -> Ordering {
677 self.0
678 .cmp(&cursor_location, text)
679 .then_with(|| (self.1).0.cmp(&cursor_location.range.end, text))
680 }
681}
682
683impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for (Depth, Range<Anchor>) {
684 fn cmp(&self, cursor_location: &SyntaxLayerSummary, buffer: &BufferSnapshot) -> Ordering {
685 self.0
686 .cmp(&cursor_location, buffer)
687 .then_with(|| {
688 self.1
689 .start
690 .cmp(&cursor_location.last_layer_range.start, buffer)
691 })
692 .then_with(|| {
693 cursor_location
694 .last_layer_range
695 .end
696 .cmp(&self.1.end, buffer)
697 })
698 }
699}
700
701impl sum_tree::Item for SyntaxLayer {
702 type Summary = SyntaxLayerSummary;
703
704 fn summary(&self) -> Self::Summary {
705 SyntaxLayerSummary {
706 max_depth: self.depth,
707 range: self.range.clone(),
708 last_layer_range: self.range.clone(),
709 }
710 }
711}
712
713impl std::fmt::Debug for SyntaxLayer {
714 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
715 f.debug_struct("SyntaxLayer")
716 .field("depth", &self.depth)
717 .field("range", &self.range)
718 .field("tree", &self.tree)
719 .finish()
720 }
721}
722
723#[cfg(test)]
724mod tests {
725 use super::*;
726 use crate::LanguageConfig;
727 use text::{Buffer, Point};
728 use tree_sitter::Query;
729 use unindent::Unindent as _;
730 use util::test::marked_text_ranges;
731
732 #[gpui::test]
733 fn test_syntax_map_layers_for_range() {
734 let registry = Arc::new(LanguageRegistry::test());
735 let language = Arc::new(rust_lang());
736 registry.add(language.clone());
737
738 let mut buffer = Buffer::new(
739 0,
740 0,
741 r#"
742 fn a() {
743 assert_eq!(
744 b(vec![C {}]),
745 vec![d.e],
746 );
747 println!("{}", f(|_| true));
748 }
749 "#
750 .unindent(),
751 );
752
753 let mut syntax_map = SyntaxMap::new();
754 syntax_map.set_language_registry(registry.clone());
755 syntax_map.reparse(language.clone(), &buffer);
756
757 assert_layers_for_range(
758 &syntax_map,
759 &buffer,
760 Point::new(2, 0)..Point::new(2, 0),
761 &[
762 "...(function_item ... (block (expression_statement (macro_invocation...",
763 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
764 ],
765 );
766 assert_layers_for_range(
767 &syntax_map,
768 &buffer,
769 Point::new(2, 14)..Point::new(2, 16),
770 &[
771 "...(function_item ...",
772 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
773 "...(array_expression (struct_expression ...",
774 ],
775 );
776 assert_layers_for_range(
777 &syntax_map,
778 &buffer,
779 Point::new(3, 14)..Point::new(3, 16),
780 &[
781 "...(function_item ...",
782 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
783 "...(array_expression (field_expression ...",
784 ],
785 );
786 assert_layers_for_range(
787 &syntax_map,
788 &buffer,
789 Point::new(5, 12)..Point::new(5, 16),
790 &[
791 "...(function_item ...",
792 "...(call_expression ... (arguments (closure_expression ...",
793 ],
794 );
795
796 // Replace a vec! macro invocation with a plain slice, removing a syntactic layer.
797 let macro_name_range = range_for_text(&buffer, "vec!");
798 buffer.edit([(macro_name_range, "&")]);
799 syntax_map.interpolate(&buffer);
800 syntax_map.reparse(language.clone(), &buffer);
801
802 assert_layers_for_range(
803 &syntax_map,
804 &buffer,
805 Point::new(2, 14)..Point::new(2, 16),
806 &[
807 "...(function_item ...",
808 "...(tuple_expression (call_expression ... arguments: (arguments (reference_expression value: (array_expression...",
809 ],
810 );
811
812 // Put the vec! macro back, adding back the syntactic layer.
813 buffer.undo();
814 syntax_map.interpolate(&buffer);
815 syntax_map.reparse(language.clone(), &buffer);
816
817 assert_layers_for_range(
818 &syntax_map,
819 &buffer,
820 Point::new(2, 14)..Point::new(2, 16),
821 &[
822 "...(function_item ...",
823 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
824 "...(array_expression (struct_expression ...",
825 ],
826 );
827 }
828
829 #[gpui::test]
830 fn test_syntax_map_edits() {
831 let registry = Arc::new(LanguageRegistry::test());
832 let language = Arc::new(rust_lang());
833 let mut syntax_map = SyntaxMap::new();
834 syntax_map.set_language_registry(registry.clone());
835 registry.add(language.clone());
836
837 let mut buffer = Buffer::new(0, 0, "".into());
838 syntax_map.reparse(language.clone(), &buffer);
839
840 edit_buffer_n(
841 &mut buffer,
842 &[
843 "«fn a() { dbg }»",
844 "fn a() { dbg«!» }",
845 "fn a() { dbg!«()» }",
846 "fn a() { dbg!(«b») }",
847 "fn a() { dbg!(b«.») }",
848 "fn a() { dbg!(b.«c») }",
849 "fn a() { dbg!(b.c«()») }",
850 "fn a() { dbg!(b.c(«vec»)) }",
851 "fn a() { dbg!(b.c(vec«!»)) }",
852 "fn a() { dbg!(b.c(vec!«[]»)) }",
853 "fn a() { dbg!(b.c(vec![«d»])) }",
854 "fn a() { dbg!(b.c(vec![d«.»])) }",
855 "fn a() { dbg!(b.c(vec![d.«e»])) }",
856 ],
857 );
858
859 syntax_map.interpolate(&buffer);
860 syntax_map.reparse(language.clone(), &buffer);
861
862 assert_node_ranges(
863 &syntax_map,
864 &buffer,
865 "(field_identifier) @_",
866 "fn a() { dbg!(b.«c»(vec![d.«e»])) }",
867 );
868 }
869
870 fn rust_lang() -> Language {
871 Language::new(
872 LanguageConfig {
873 name: "Rust".into(),
874 path_suffixes: vec!["rs".to_string()],
875 ..Default::default()
876 },
877 Some(tree_sitter_rust::language()),
878 )
879 .with_injection_query(
880 r#"
881 (macro_invocation
882 (token_tree) @content
883 (#set! "language" "rust"))
884 "#,
885 )
886 .unwrap()
887 }
888
889 fn range_for_text(buffer: &Buffer, text: &str) -> Range<usize> {
890 let start = buffer.as_rope().to_string().find(text).unwrap();
891 start..start + text.len()
892 }
893
894 fn assert_layers_for_range(
895 syntax_map: &SyntaxMap,
896 buffer: &BufferSnapshot,
897 range: Range<Point>,
898 expected_layers: &[&str],
899 ) {
900 let layers = syntax_map.layers_for_range(range, &buffer);
901 assert_eq!(
902 layers.len(),
903 expected_layers.len(),
904 "wrong number of layers"
905 );
906 for (i, ((_, tree, _), expected_s_exp)) in
907 layers.iter().zip(expected_layers.iter()).enumerate()
908 {
909 let actual_s_exp = tree.root_node().to_sexp();
910 assert!(
911 string_contains_sequence(
912 &actual_s_exp,
913 &expected_s_exp.split("...").collect::<Vec<_>>()
914 ),
915 "layer {i}:\n\nexpected: {expected_s_exp}\nactual: {actual_s_exp}",
916 );
917 }
918 }
919
920 fn assert_node_ranges(
921 syntax_map: &SyntaxMap,
922 buffer: &BufferSnapshot,
923 query: &str,
924 marked_string: &str,
925 ) {
926 let mut cursor = QueryCursorHandle::new();
927 let mut actual_ranges = Vec::<Range<usize>>::new();
928 for (grammar, tree, (start_byte, _)) in syntax_map.layers(buffer) {
929 let query = Query::new(grammar.ts_language, query).unwrap();
930 for (mat, ix) in
931 cursor.captures(&query, tree.root_node(), TextProvider(buffer.as_rope()))
932 {
933 let range = mat.captures[ix].node.byte_range();
934 actual_ranges.push(start_byte + range.start..start_byte + range.end);
935 }
936 }
937
938 let (text, expected_ranges) = marked_text_ranges(marked_string, false);
939 assert_eq!(text, buffer.text());
940 assert_eq!(actual_ranges, expected_ranges);
941 }
942
943 fn edit_buffer_n(buffer: &mut Buffer, marked_strings: &[&str]) {
944 for marked_string in marked_strings {
945 edit_buffer(buffer, marked_string);
946 }
947 }
948
949 fn edit_buffer(buffer: &mut Buffer, marked_string: &str) {
950 let old_text = buffer.text();
951 let (new_text, mut ranges) = marked_text_ranges(marked_string, false);
952 assert_eq!(ranges.len(), 1);
953
954 let inserted_range = ranges.pop().unwrap();
955 let inserted_text = new_text[inserted_range.clone()].to_string();
956 let deleted_len = (inserted_range.len() as isize + old_text.len() as isize
957 - new_text.len() as isize) as usize;
958 let deleted_range = inserted_range.start..inserted_range.start + deleted_len;
959
960 assert_eq!(
961 old_text[..deleted_range.start],
962 new_text[..inserted_range.start],
963 "invalid edit",
964 );
965 assert_eq!(
966 old_text[deleted_range.end..],
967 new_text[inserted_range.end..],
968 "invalid edit",
969 );
970
971 buffer.edit([(deleted_range, inserted_text)]);
972 }
973
974 pub fn string_contains_sequence(text: &str, parts: &[&str]) -> bool {
975 let mut last_part_end = 0;
976 for part in parts {
977 if let Some(start_ix) = text[last_part_end..].find(part) {
978 last_part_end = start_ix + part.len();
979 } else {
980 return false;
981 }
982 }
983 true
984 }
985}