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};
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_for_range<'a, T: ToOffset>(
414 &self,
415 range: Range<T>,
416 buffer: &BufferSnapshot,
417 ) -> Vec<(Tree, &Grammar)> {
418 let start = buffer.anchor_before(range.start.to_offset(buffer));
419 let end = buffer.anchor_after(range.end.to_offset(buffer));
420
421 let mut cursor = self.layers.filter::<_, ()>(|summary| {
422 let is_before_start = summary.range.end.cmp(&start, buffer).is_lt();
423 let is_after_end = summary.range.start.cmp(&end, buffer).is_gt();
424 !is_before_start && !is_after_end
425 });
426
427 let mut result = Vec::new();
428 cursor.next(buffer);
429 while let Some(item) = cursor.item() {
430 if let Some(grammar) = &item.language.grammar {
431 result.push((item.tree.clone(), grammar.as_ref()));
432 }
433 cursor.next(buffer)
434 }
435
436 result
437 }
438}
439
440fn parse_text(
441 grammar: &Grammar,
442 text: &Rope,
443 old_tree: Option<Tree>,
444 mut ranges: Vec<tree_sitter::Range>,
445) -> Tree {
446 let (start_byte, start_point) = ranges
447 .first()
448 .map(|range| (range.start_byte, Point::from_ts_point(range.start_point)))
449 .unwrap_or_default();
450
451 for range in &mut ranges {
452 range.start_byte -= start_byte;
453 range.end_byte -= start_byte;
454 range.start_point = (Point::from_ts_point(range.start_point) - start_point).to_ts_point();
455 range.end_point = (Point::from_ts_point(range.end_point) - start_point).to_ts_point();
456 }
457
458 PARSER.with(|parser| {
459 let mut parser = parser.borrow_mut();
460 let mut chunks = text.chunks_in_range(start_byte..text.len());
461 parser
462 .set_included_ranges(&ranges)
463 .expect("overlapping ranges");
464 parser
465 .set_language(grammar.ts_language)
466 .expect("incompatible grammar");
467 parser
468 .parse_with(
469 &mut move |offset, _| {
470 chunks.seek(start_byte + offset);
471 chunks.next().unwrap_or("").as_bytes()
472 },
473 old_tree.as_ref(),
474 )
475 .expect("invalid language")
476 })
477}
478
479fn get_injections(
480 config: &InjectionConfig,
481 text: &BufferSnapshot,
482 tree: &Tree,
483 language_registry: &LanguageRegistry,
484 depth: usize,
485 start_byte: usize,
486 start_point: Point,
487 query_ranges: &[Range<usize>],
488 stack: &mut BinaryHeap<ReparseStep>,
489) -> bool {
490 let mut result = false;
491 let mut query_cursor = QueryCursorHandle::new();
492 let mut prev_match = None;
493 for query_range in query_ranges {
494 query_cursor.set_byte_range(query_range.start..query_range.end);
495 for mat in query_cursor.matches(
496 &config.query,
497 tree.root_node(),
498 TextProvider(text.as_rope()),
499 ) {
500 let content_ranges = mat
501 .nodes_for_capture_index(config.content_capture_ix)
502 .map(|node| tree_sitter::Range {
503 start_byte: start_byte + node.start_byte(),
504 end_byte: start_byte + node.end_byte(),
505 start_point: (start_point + Point::from_ts_point(node.start_position()))
506 .to_ts_point(),
507 end_point: (start_point + Point::from_ts_point(node.end_position()))
508 .to_ts_point(),
509 })
510 .collect::<Vec<_>>();
511 if content_ranges.is_empty() {
512 continue;
513 }
514
515 // Avoid duplicate matches if two changed ranges intersect the same injection.
516 let content_range =
517 content_ranges.first().unwrap().start_byte..content_ranges.last().unwrap().end_byte;
518 if let Some((last_pattern_ix, last_range)) = &prev_match {
519 if mat.pattern_index == *last_pattern_ix && content_range == *last_range {
520 continue;
521 }
522 }
523 prev_match = Some((mat.pattern_index, content_range));
524
525 let language_name = config.languages_by_pattern_ix[mat.pattern_index]
526 .as_ref()
527 .map(|s| Cow::Borrowed(s.as_ref()))
528 .or_else(|| {
529 let ix = config.language_capture_ix?;
530 let node = mat.nodes_for_capture_index(ix).next()?;
531 Some(Cow::Owned(
532 text.text_for_range(
533 start_byte + node.start_byte()..start_byte + node.end_byte(),
534 )
535 .collect(),
536 ))
537 });
538
539 if let Some(language_name) = language_name {
540 if let Some(language) = language_registry.get_language(language_name.as_ref()) {
541 result = true;
542 stack.push(ReparseStep::CreateLayer {
543 depth,
544 language,
545 ranges: content_ranges,
546 })
547 }
548 }
549 }
550 }
551 result
552}
553
554fn layer_is_changed(
555 layer: &SyntaxLayer,
556 text: &BufferSnapshot,
557 changed_ranges: &HashMap<usize, Range<Anchor>>,
558) -> bool {
559 changed_ranges.values().any(|range| {
560 let is_before_layer = range.end.cmp(&layer.range.start, text).is_le();
561 let is_after_layer = range.start.cmp(&layer.range.end, text).is_ge();
562 !is_before_layer && !is_after_layer
563 })
564}
565
566impl std::ops::Deref for SyntaxMap {
567 type Target = SyntaxSnapshot;
568
569 fn deref(&self) -> &Self::Target {
570 &self.snapshot
571 }
572}
573
574impl ReparseStep {
575 fn sort_key(&self) -> (usize, Range<usize>) {
576 match self {
577 ReparseStep::CreateLayer { depth, ranges, .. } => (
578 *depth,
579 ranges.first().map_or(0, |r| r.start_byte)
580 ..ranges.last().map_or(usize::MAX, |r| r.end_byte),
581 ),
582 ReparseStep::EnterChangedRange { depth, range, .. } => {
583 (*depth, range.start..usize::MAX)
584 }
585 ReparseStep::LeaveChangedRange { depth, range, .. } => (*depth, range.end..usize::MAX),
586 }
587 }
588}
589
590impl PartialEq for ReparseStep {
591 fn eq(&self, _: &Self) -> bool {
592 false
593 }
594}
595
596impl Eq for ReparseStep {}
597
598impl PartialOrd for ReparseStep {
599 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
600 Some(self.cmp(&other))
601 }
602}
603
604impl Ord for ReparseStep {
605 fn cmp(&self, other: &Self) -> Ordering {
606 let (depth_a, range_a) = self.sort_key();
607 let (depth_b, range_b) = other.sort_key();
608 Ord::cmp(&depth_b, &depth_a)
609 .then_with(|| Ord::cmp(&range_b.start, &range_a.start))
610 .then_with(|| Ord::cmp(&range_a.end, &range_b.end))
611 }
612}
613
614impl Default for SyntaxLayerSummary {
615 fn default() -> Self {
616 Self {
617 max_depth: 0,
618 range: Anchor::MAX..Anchor::MIN,
619 last_layer_range: Anchor::MIN..Anchor::MAX,
620 }
621 }
622}
623
624impl sum_tree::Summary for SyntaxLayerSummary {
625 type Context = BufferSnapshot;
626
627 fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
628 if other.max_depth > self.max_depth {
629 *self = other.clone();
630 } else {
631 if other.range.start.cmp(&self.range.start, buffer).is_lt() {
632 self.range.start = other.range.start;
633 }
634 if other.range.end.cmp(&self.range.end, buffer).is_gt() {
635 self.range.end = other.range.end;
636 }
637 self.last_layer_range = other.last_layer_range.clone();
638 }
639 }
640}
641
642impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for Depth {
643 fn cmp(&self, cursor_location: &SyntaxLayerSummary, _: &BufferSnapshot) -> Ordering {
644 Ord::cmp(&self.0, &cursor_location.max_depth)
645 }
646}
647
648impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for (Depth, MaxPosition) {
649 fn cmp(&self, cursor_location: &SyntaxLayerSummary, text: &BufferSnapshot) -> Ordering {
650 self.0
651 .cmp(&cursor_location, text)
652 .then_with(|| (self.1).0.cmp(&cursor_location.range.end, text))
653 }
654}
655
656impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for (Depth, Range<Anchor>) {
657 fn cmp(&self, cursor_location: &SyntaxLayerSummary, buffer: &BufferSnapshot) -> Ordering {
658 self.0
659 .cmp(&cursor_location, buffer)
660 .then_with(|| {
661 self.1
662 .start
663 .cmp(&cursor_location.last_layer_range.start, buffer)
664 })
665 .then_with(|| {
666 cursor_location
667 .last_layer_range
668 .end
669 .cmp(&self.1.end, buffer)
670 })
671 }
672}
673
674impl sum_tree::Item for SyntaxLayer {
675 type Summary = SyntaxLayerSummary;
676
677 fn summary(&self) -> Self::Summary {
678 SyntaxLayerSummary {
679 max_depth: self.depth,
680 range: self.range.clone(),
681 last_layer_range: self.range.clone(),
682 }
683 }
684}
685
686impl std::fmt::Debug for SyntaxLayer {
687 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
688 f.debug_struct("SyntaxLayer")
689 .field("depth", &self.depth)
690 .field("range", &self.range)
691 .field("tree", &self.tree)
692 .finish()
693 }
694}
695
696#[cfg(test)]
697mod tests {
698 use super::*;
699 use crate::LanguageConfig;
700 use text::{Buffer, Point};
701 use unindent::Unindent as _;
702
703 #[gpui::test]
704 fn test_syntax_map_layers_for_range() {
705 let registry = Arc::new(LanguageRegistry::test());
706 let language = Arc::new(rust_lang());
707 registry.add(language.clone());
708
709 let mut buffer = Buffer::new(
710 0,
711 0,
712 r#"
713 fn a() {
714 assert_eq!(
715 b(vec![C {}]),
716 vec![d.e],
717 );
718 println!("{}", f(|_| true));
719 }
720 "#
721 .unindent(),
722 );
723
724 let mut syntax_map = SyntaxMap::new();
725 syntax_map.set_language_registry(registry.clone());
726 syntax_map.reparse(language.clone(), &buffer);
727
728 assert_layers_for_range(
729 &syntax_map,
730 &buffer,
731 Point::new(2, 0)..Point::new(2, 0),
732 &[
733 "...(function_item ... (block (expression_statement (macro_invocation...",
734 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
735 ],
736 );
737 assert_layers_for_range(
738 &syntax_map,
739 &buffer,
740 Point::new(2, 14)..Point::new(2, 16),
741 &[
742 "...(function_item ...",
743 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
744 "...(array_expression (struct_expression ...",
745 ],
746 );
747 assert_layers_for_range(
748 &syntax_map,
749 &buffer,
750 Point::new(3, 14)..Point::new(3, 16),
751 &[
752 "...(function_item ...",
753 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
754 "...(array_expression (field_expression ...",
755 ],
756 );
757 assert_layers_for_range(
758 &syntax_map,
759 &buffer,
760 Point::new(5, 12)..Point::new(5, 16),
761 &[
762 "...(function_item ...",
763 "...(call_expression ... (arguments (closure_expression ...",
764 ],
765 );
766
767 // Replace a vec! macro invocation with a plain slice, removing a syntactic layer.
768 let macro_name_range = range_for_text(&buffer, "vec!");
769 buffer.edit([(macro_name_range, "&")]);
770 syntax_map.interpolate(&buffer);
771 syntax_map.reparse(language.clone(), &buffer);
772
773 assert_layers_for_range(
774 &syntax_map,
775 &buffer,
776 Point::new(2, 14)..Point::new(2, 16),
777 &[
778 "...(function_item ...",
779 "...(tuple_expression (call_expression ... arguments: (arguments (reference_expression value: (array_expression...",
780 ],
781 );
782
783 // Put the vec! macro back, adding back the syntactic layer.
784 buffer.undo();
785 syntax_map.interpolate(&buffer);
786 syntax_map.reparse(language.clone(), &buffer);
787
788 assert_layers_for_range(
789 &syntax_map,
790 &buffer,
791 Point::new(2, 14)..Point::new(2, 16),
792 &[
793 "...(function_item ...",
794 "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
795 "...(array_expression (struct_expression ...",
796 ],
797 );
798 }
799
800 fn rust_lang() -> Language {
801 Language::new(
802 LanguageConfig {
803 name: "Rust".into(),
804 path_suffixes: vec!["rs".to_string()],
805 ..Default::default()
806 },
807 Some(tree_sitter_rust::language()),
808 )
809 .with_injection_query(
810 r#"
811 (macro_invocation
812 (token_tree) @content
813 (#set! "language" "rust"))
814 "#,
815 )
816 .unwrap()
817 }
818
819 fn range_for_text(buffer: &Buffer, text: &str) -> Range<usize> {
820 let start = buffer.as_rope().to_string().find(text).unwrap();
821 start..start + text.len()
822 }
823
824 fn assert_layers_for_range(
825 syntax_map: &SyntaxMap,
826 buffer: &BufferSnapshot,
827 range: Range<Point>,
828 expected_layers: &[&str],
829 ) {
830 let layers = syntax_map.layers_for_range(range, &buffer);
831 assert_eq!(
832 layers.len(),
833 expected_layers.len(),
834 "wrong number of layers"
835 );
836 for (i, (layer, expected_s_exp)) in layers.iter().zip(expected_layers.iter()).enumerate() {
837 let actual_s_exp = layer.0.root_node().to_sexp();
838 assert!(
839 string_contains_sequence(
840 &actual_s_exp,
841 &expected_s_exp.split("...").collect::<Vec<_>>()
842 ),
843 "layer {i}:\n\nexpected: {expected_s_exp}\nactual: {actual_s_exp}",
844 );
845 }
846 }
847
848 pub fn string_contains_sequence(text: &str, parts: &[&str]) -> bool {
849 let mut last_part_end = 0;
850 for part in parts {
851 if let Some(start_ix) = text[last_part_end..].find(part) {
852 last_part_end = start_ix + part.len();
853 } else {
854 return false;
855 }
856 }
857 true
858 }
859}