mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-26 03:59:55 +00:00
Fix range relativization when combined injections occur inside of other injections
For example, ERB template inside of a markdown code block Co-authored-by: Antonio Scandurra <antonio@zed.dev>
This commit is contained in:
parent
2e1adb0724
commit
a366ba19af
1 changed files with 51 additions and 12 deletions
|
@ -165,6 +165,7 @@ struct ParseStep {
|
||||||
mode: ParseMode,
|
mode: ParseMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum ParseStepLanguage {
|
enum ParseStepLanguage {
|
||||||
Loaded { language: Arc<Language> },
|
Loaded { language: Arc<Language> },
|
||||||
Pending { name: Arc<str> },
|
Pending { name: Arc<str> },
|
||||||
|
@ -514,15 +515,32 @@ impl SyntaxSnapshot {
|
||||||
let Some(grammar) = language.grammar() else { continue };
|
let Some(grammar) = language.grammar() else { continue };
|
||||||
let tree;
|
let tree;
|
||||||
let changed_ranges;
|
let changed_ranges;
|
||||||
|
|
||||||
let mut included_ranges = step.included_ranges;
|
let mut included_ranges = step.included_ranges;
|
||||||
|
for range in &mut included_ranges {
|
||||||
|
range.start_byte -= step_start_byte;
|
||||||
|
range.end_byte -= step_start_byte;
|
||||||
|
range.start_point = (Point::from_ts_point(range.start_point)
|
||||||
|
- step_start_point)
|
||||||
|
.to_ts_point();
|
||||||
|
range.end_point = (Point::from_ts_point(range.end_point)
|
||||||
|
- step_start_point)
|
||||||
|
.to_ts_point();
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(SyntaxLayerContent::Parsed { tree: old_tree, .. }) =
|
if let Some(SyntaxLayerContent::Parsed { tree: old_tree, .. }) =
|
||||||
old_layer.map(|layer| &layer.content)
|
old_layer.map(|layer| &layer.content)
|
||||||
{
|
{
|
||||||
if let ParseMode::Combined {
|
if let ParseMode::Combined {
|
||||||
parent_layer_changed_ranges,
|
mut parent_layer_changed_ranges,
|
||||||
..
|
..
|
||||||
} = step.mode
|
} = step.mode
|
||||||
{
|
{
|
||||||
|
for range in &mut parent_layer_changed_ranges {
|
||||||
|
range.start -= step_start_byte;
|
||||||
|
range.end -= step_start_byte;
|
||||||
|
}
|
||||||
|
|
||||||
included_ranges = splice_included_ranges(
|
included_ranges = splice_included_ranges(
|
||||||
old_tree.included_ranges(),
|
old_tree.included_ranges(),
|
||||||
&parent_layer_changed_ranges,
|
&parent_layer_changed_ranges,
|
||||||
|
@ -534,7 +552,6 @@ impl SyntaxSnapshot {
|
||||||
grammar,
|
grammar,
|
||||||
text.as_rope(),
|
text.as_rope(),
|
||||||
step_start_byte,
|
step_start_byte,
|
||||||
step_start_point,
|
|
||||||
included_ranges,
|
included_ranges,
|
||||||
Some(old_tree.clone()),
|
Some(old_tree.clone()),
|
||||||
);
|
);
|
||||||
|
@ -551,7 +568,6 @@ impl SyntaxSnapshot {
|
||||||
grammar,
|
grammar,
|
||||||
text.as_rope(),
|
text.as_rope(),
|
||||||
step_start_byte,
|
step_start_byte,
|
||||||
step_start_point,
|
|
||||||
included_ranges,
|
included_ranges,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
@ -1060,17 +1076,9 @@ fn parse_text(
|
||||||
grammar: &Grammar,
|
grammar: &Grammar,
|
||||||
text: &Rope,
|
text: &Rope,
|
||||||
start_byte: usize,
|
start_byte: usize,
|
||||||
start_point: Point,
|
ranges: Vec<tree_sitter::Range>,
|
||||||
mut ranges: Vec<tree_sitter::Range>,
|
|
||||||
old_tree: Option<Tree>,
|
old_tree: Option<Tree>,
|
||||||
) -> Tree {
|
) -> Tree {
|
||||||
for range in &mut ranges {
|
|
||||||
range.start_byte -= start_byte;
|
|
||||||
range.end_byte -= start_byte;
|
|
||||||
range.start_point = (Point::from_ts_point(range.start_point) - start_point).to_ts_point();
|
|
||||||
range.end_point = (Point::from_ts_point(range.end_point) - start_point).to_ts_point();
|
|
||||||
}
|
|
||||||
|
|
||||||
PARSER.with(|parser| {
|
PARSER.with(|parser| {
|
||||||
let mut parser = parser.borrow_mut();
|
let mut parser = parser.borrow_mut();
|
||||||
let mut chunks = text.chunks_in_range(start_byte..text.len());
|
let mut chunks = text.chunks_in_range(start_byte..text.len());
|
||||||
|
@ -2208,6 +2216,37 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn test_combined_injections_inside_injections() {
|
||||||
|
let (_buffer, _syntax_map) = test_edit_sequence(
|
||||||
|
"Markdown",
|
||||||
|
&[
|
||||||
|
r#"
|
||||||
|
here is some ERB code:
|
||||||
|
|
||||||
|
```erb
|
||||||
|
<ul>
|
||||||
|
<% people.each do |person| %>
|
||||||
|
<li><%= person.name %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
here is some ERB code:
|
||||||
|
|
||||||
|
```erb
|
||||||
|
<ul>
|
||||||
|
<% people«2».each do |person| %>
|
||||||
|
<li><%= person.name %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
"#,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 50)]
|
#[gpui::test(iterations = 50)]
|
||||||
fn test_random_syntax_map_edits(mut rng: StdRng) {
|
fn test_random_syntax_map_edits(mut rng: StdRng) {
|
||||||
let operations = env::var("OPERATIONS")
|
let operations = env::var("OPERATIONS")
|
||||||
|
|
Loading…
Reference in a new issue