on master help sign in
use a single query for injections
68a98acPascal Kuthe
helix-core/src/syntax.rs+43−59
@@ -1135,6 +1135,10 @@ impl Syntax {
1135 layer.tree().root_node(),
1135 layer.tree().root_node(),
1136 RopeProvider(source_slice),
1136 RopeProvider(source_slice),
1137 );
1137 );
1138+ let mut combined_injections = vec![
1139+ (None, Vec::new(), IncludedChildren::default());
1140+ layer.config.combined_injections_patterns.len()
1141+ ];
1138 let mut injections = Vec::new();
1142 let mut injections = Vec::new();
1139 let mut last_injection_end = 0;
1143 let mut last_injection_end = 0;
1140 for mat in matches {
1144 for mat in matches {
@@ -1142,6 +1146,27 @@ impl Syntax {
1142 .config
1146 .config
1143 .injection_for_match(&layer.config.injections_query, &mat, source_slice);
1147 .injection_for_match(&layer.config.injections_query, &mat, source_slice);
1144
1148
1149+ // in case this is a combined injection save it for more processing later
1150+ if let Some(combined_injection_idx) = layer
1151+ .config
1152+ .combined_injections_patterns
1153+ .iter()
1154+ .position(|&pattern| pattern == mat.pattern_index)
1155+ {
1156+ let entry = &mut combined_injections[combined_injection_idx];
1157+ if injection_capture.is_some() {
1158+ entry.0 = injection_capture;
1159+ }
1160+ if let Some(content_node) = content_node {
1161+ if content_node.start_byte() >= last_injection_end {
1162+ entry.1.push(content_node);
1163+ last_injection_end = content_node.end_byte();
1164+ }
1165+ }
1166+ entry.2 = included_children;
1167+ continue;
1168+ }
1169+
1145 // Explicitly remove this match so that none of its other captures will remain
1170 // Explicitly remove this match so that none of its other captures will remain
1146 // in the stream of captures.
1171 // in the stream of captures.
1147 mat.remove();
1172 mat.remove();
@@ -1166,43 +1191,13 @@ impl Syntax {
1166 }
1191 }
1167 }
1192 }
1168
1193
1169− // Process combined injections.
1170− if let Some(combined_injections_query) = &layer.config.combined_injections_query {
1171− let mut injections_by_pattern_index =
1172− vec![
1173− (None, Vec::new(), IncludedChildren::default());
1174− combined_injections_query.pattern_count()
1175− ];
1176− let matches = cursor.matches(
1177− combined_injections_query,
1178− layer.tree().root_node(),
1179− RopeProvider(source_slice),
1180− );
1181− for mat in matches {
1182− let entry = &mut injections_by_pattern_index[mat.pattern_index];
1183− let (injection_capture, content_node, included_children) = layer
1184− .config
1185− .injection_for_match(combined_injections_query, &mat, source_slice);
1186− if injection_capture.is_some() {
1187− entry.0 = injection_capture;
1188− }
1189− if let Some(content_node) = content_node {
1190− entry.1.push(content_node);
1191− }
1192− entry.2 = included_children;
1193− }
1194− for (lang_name, content_nodes, included_children) in injections_by_pattern_index
1194+ for (lang_name, content_nodes, included_children) in combined_injections {
1195− {
1196− if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) {
1195+ if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) {
1197− if let Some(config) = (injection_callback)(&lang_name) {
1196+ if let Some(config) = (injection_callback)(&lang_name) {
1198− let ranges = intersect_ranges(
1197+ let ranges =
1199− &layer.ranges,
1200− &content_nodes,
1201− included_children,
1198+ intersect_ranges(&layer.ranges, &content_nodes, included_children);
1202− );
1203− if !ranges.is_empty() {
1199+ if !ranges.is_empty() {
1204− injections.push((config, ranges));
1200+ injections.push((config, ranges));
1205− }
1206 }
1201 }
1207 }
1202 }
1208 }
1203 }
@@ -1565,7 +1560,7 @@ pub struct HighlightConfiguration {
1565 pub language: Grammar,
1560 pub language: Grammar,
1566 pub query: Query,
1561 pub query: Query,
1567 injections_query: Query,
1562 injections_query: Query,
1568− combined_injections_query: Option<Query>,
1563+ combined_injections_patterns: Vec<usize>,
1569 highlights_pattern_index: usize,
1564 highlights_pattern_index: usize,
1570 highlight_indices: ArcSwap<Vec<Option<Highlight>>>,
1565 highlight_indices: ArcSwap<Vec<Option<Highlight>>>,
1571 non_local_variable_patterns: Vec<bool>,
1566 non_local_variable_patterns: Vec<bool>,
@@ -1681,26 +1676,15 @@ impl HighlightConfiguration {
1681 }
1676 }
1682 }
1677 }
1683
1678
1684− let mut injections_query = Query::new(language, injection_query)?;
1679+ let injections_query = Query::new(language, injection_query)?;
1685−
1686− // Construct a separate query just for dealing with the 'combined injections'.
1687− // Disable the combined injection patterns in the main query.
1688− let mut combined_injections_query = Query::new(language, injection_query)?;
1689− let mut has_combined_queries = false;
1690− for pattern_index in 0..injections_query.pattern_count() {
1680+ let combined_injections_patterns = (0..injections_query.pattern_count())
1681+ .filter(|&i| {
1682+ injections_query
1691− let settings = injections_query.property_settings(pattern_index);
1683+ .property_settings(i)
1684+ .iter()
1692− if settings.iter().any(|s| &*s.key == "injection.combined") {
1685+ .any(|s| &*s.key == "injection.combined")
1693− has_combined_queries = true;
1686+ })
1694− injections_query.disable_pattern(pattern_index);
1687+ .collect();
1695− } else {
1696− combined_injections_query.disable_pattern(pattern_index);
1697− }
1698− }
1699− let combined_injections_query = if has_combined_queries {
1700− Some(combined_injections_query)
1701− } else {
1702− None
1703− };
1704
1688
1705 // Find all of the highlighting patterns that are disabled for nodes that
1689 // Find all of the highlighting patterns that are disabled for nodes that
1706 // have been identified as local variables.
1690 // have been identified as local variables.
@@ -1749,7 +1733,7 @@ impl HighlightConfiguration {
1749 language,
1733 language,
1750 query,
1734 query,
1751 injections_query,
1735 injections_query,
1752− combined_injections_query,
1736+ combined_injections_patterns,
1753 highlights_pattern_index,
1737 highlights_pattern_index,
1754 highlight_indices,
1738 highlight_indices,
1755 non_local_variable_patterns,
1739 non_local_variable_patterns,