use a single query for injections
In the past we used two separate queries for combined and normal injections. There was no real reason for this (except historical/slightly easier implementation). Instead, we now use a single query and simply check if an injection corresponds to a combined injection or not.
This commit is contained in:
parent
2d5ff9ec8f
commit
68a98ac36b
1 changed files with 43 additions and 59 deletions
|
@ -1135,6 +1135,10 @@ impl Syntax {
|
||||||
layer.tree().root_node(),
|
layer.tree().root_node(),
|
||||||
RopeProvider(source_slice),
|
RopeProvider(source_slice),
|
||||||
);
|
);
|
||||||
|
let mut combined_injections = vec![
|
||||||
|
(None, Vec::new(), IncludedChildren::default());
|
||||||
|
layer.config.combined_injections_patterns.len()
|
||||||
|
];
|
||||||
let mut injections = Vec::new();
|
let mut injections = Vec::new();
|
||||||
let mut last_injection_end = 0;
|
let mut last_injection_end = 0;
|
||||||
for mat in matches {
|
for mat in matches {
|
||||||
|
@ -1142,6 +1146,27 @@ impl Syntax {
|
||||||
.config
|
.config
|
||||||
.injection_for_match(&layer.config.injections_query, &mat, source_slice);
|
.injection_for_match(&layer.config.injections_query, &mat, source_slice);
|
||||||
|
|
||||||
|
// in case this is a combined injection save it for more processing later
|
||||||
|
if let Some(combined_injection_idx) = layer
|
||||||
|
.config
|
||||||
|
.combined_injections_patterns
|
||||||
|
.iter()
|
||||||
|
.position(|&pattern| pattern == mat.pattern_index)
|
||||||
|
{
|
||||||
|
let entry = &mut combined_injections[combined_injection_idx];
|
||||||
|
if injection_capture.is_some() {
|
||||||
|
entry.0 = injection_capture;
|
||||||
|
}
|
||||||
|
if let Some(content_node) = content_node {
|
||||||
|
if content_node.start_byte() >= last_injection_end {
|
||||||
|
entry.1.push(content_node);
|
||||||
|
last_injection_end = content_node.end_byte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry.2 = included_children;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Explicitly remove this match so that none of its other captures will remain
|
// Explicitly remove this match so that none of its other captures will remain
|
||||||
// in the stream of captures.
|
// in the stream of captures.
|
||||||
mat.remove();
|
mat.remove();
|
||||||
|
@ -1166,43 +1191,13 @@ impl Syntax {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process combined injections.
|
for (lang_name, content_nodes, included_children) in combined_injections {
|
||||||
if let Some(combined_injections_query) = &layer.config.combined_injections_query {
|
if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) {
|
||||||
let mut injections_by_pattern_index =
|
if let Some(config) = (injection_callback)(&lang_name) {
|
||||||
vec![
|
let ranges =
|
||||||
(None, Vec::new(), IncludedChildren::default());
|
intersect_ranges(&layer.ranges, &content_nodes, included_children);
|
||||||
combined_injections_query.pattern_count()
|
if !ranges.is_empty() {
|
||||||
];
|
injections.push((config, ranges));
|
||||||
let matches = cursor.matches(
|
|
||||||
combined_injections_query,
|
|
||||||
layer.tree().root_node(),
|
|
||||||
RopeProvider(source_slice),
|
|
||||||
);
|
|
||||||
for mat in matches {
|
|
||||||
let entry = &mut injections_by_pattern_index[mat.pattern_index];
|
|
||||||
let (injection_capture, content_node, included_children) = layer
|
|
||||||
.config
|
|
||||||
.injection_for_match(combined_injections_query, &mat, source_slice);
|
|
||||||
if injection_capture.is_some() {
|
|
||||||
entry.0 = injection_capture;
|
|
||||||
}
|
|
||||||
if let Some(content_node) = content_node {
|
|
||||||
entry.1.push(content_node);
|
|
||||||
}
|
|
||||||
entry.2 = included_children;
|
|
||||||
}
|
|
||||||
for (lang_name, content_nodes, included_children) in injections_by_pattern_index
|
|
||||||
{
|
|
||||||
if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) {
|
|
||||||
if let Some(config) = (injection_callback)(&lang_name) {
|
|
||||||
let ranges = intersect_ranges(
|
|
||||||
&layer.ranges,
|
|
||||||
&content_nodes,
|
|
||||||
included_children,
|
|
||||||
);
|
|
||||||
if !ranges.is_empty() {
|
|
||||||
injections.push((config, ranges));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1565,7 +1560,7 @@ pub struct HighlightConfiguration {
|
||||||
pub language: Grammar,
|
pub language: Grammar,
|
||||||
pub query: Query,
|
pub query: Query,
|
||||||
injections_query: Query,
|
injections_query: Query,
|
||||||
combined_injections_query: Option<Query>,
|
combined_injections_patterns: Vec<usize>,
|
||||||
highlights_pattern_index: usize,
|
highlights_pattern_index: usize,
|
||||||
highlight_indices: ArcSwap<Vec<Option<Highlight>>>,
|
highlight_indices: ArcSwap<Vec<Option<Highlight>>>,
|
||||||
non_local_variable_patterns: Vec<bool>,
|
non_local_variable_patterns: Vec<bool>,
|
||||||
|
@ -1681,26 +1676,15 @@ impl HighlightConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut injections_query = Query::new(language, injection_query)?;
|
let injections_query = Query::new(language, injection_query)?;
|
||||||
|
let combined_injections_patterns = (0..injections_query.pattern_count())
|
||||||
// Construct a separate query just for dealing with the 'combined injections'.
|
.filter(|&i| {
|
||||||
// Disable the combined injection patterns in the main query.
|
injections_query
|
||||||
let mut combined_injections_query = Query::new(language, injection_query)?;
|
.property_settings(i)
|
||||||
let mut has_combined_queries = false;
|
.iter()
|
||||||
for pattern_index in 0..injections_query.pattern_count() {
|
.any(|s| &*s.key == "injection.combined")
|
||||||
let settings = injections_query.property_settings(pattern_index);
|
})
|
||||||
if settings.iter().any(|s| &*s.key == "injection.combined") {
|
.collect();
|
||||||
has_combined_queries = true;
|
|
||||||
injections_query.disable_pattern(pattern_index);
|
|
||||||
} else {
|
|
||||||
combined_injections_query.disable_pattern(pattern_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let combined_injections_query = if has_combined_queries {
|
|
||||||
Some(combined_injections_query)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find all of the highlighting patterns that are disabled for nodes that
|
// Find all of the highlighting patterns that are disabled for nodes that
|
||||||
// have been identified as local variables.
|
// have been identified as local variables.
|
||||||
|
@ -1749,7 +1733,7 @@ impl HighlightConfiguration {
|
||||||
language,
|
language,
|
||||||
query,
|
query,
|
||||||
injections_query,
|
injections_query,
|
||||||
combined_injections_query,
|
combined_injections_patterns,
|
||||||
highlights_pattern_index,
|
highlights_pattern_index,
|
||||||
highlight_indices,
|
highlight_indices,
|
||||||
non_local_variable_patterns,
|
non_local_variable_patterns,
|
||||||
|
|
Loading…
Add table
Reference in a new issue