Skip to content

Commit

Permalink
Add injection.include-unnamed-children parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
MDeiml committed Jul 26, 2022
1 parent f6bafab commit 574fac3
Showing 1 changed file with 44 additions and 16 deletions.
60 changes: 44 additions & 16 deletions helix-core/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,12 +766,13 @@ impl Syntax {
);
let mut injections = Vec::new();
for mat in matches {
let (language_name, content_node, include_children) = injection_for_match(
&layer.config,
&layer.config.injections_query,
&mat,
source_slice,
);
let (language_name, content_node, include_children, include_unnamed_children) =
injection_for_match(
&layer.config,
&layer.config.injections_query,
&mat,
source_slice,
);

// Explicitly remove this match so that none of its other captures will remain
// in the stream of captures.
Expand All @@ -782,8 +783,12 @@ impl Syntax {
if let (Some(language_name), Some(content_node)) = (language_name, content_node)
{
if let Some(config) = (injection_callback)(&language_name) {
let ranges =
intersect_ranges(&layer.ranges, &[content_node], include_children);
let ranges = intersect_ranges(
&layer.ranges,
&[content_node],
include_children,
include_unnamed_children,
);

if !ranges.is_empty() {
injections.push((config, ranges));
Expand All @@ -794,16 +799,24 @@ impl Syntax {

// Process combined injections.
if let Some(combined_injections_query) = &layer.config.combined_injections_query {
let mut injections_by_pattern_index =
vec![(None, Vec::new(), false); combined_injections_query.pattern_count()];
let mut injections_by_pattern_index = vec![
(None, Vec::new(), false, false);
combined_injections_query
.pattern_count()
];
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 (language_name, content_node, include_children) = injection_for_match(
let (
language_name,
content_node,
include_children,
include_unnamed_children,
) = injection_for_match(
&layer.config,
combined_injections_query,
&mat,
Expand All @@ -816,15 +829,18 @@ impl Syntax {
entry.1.push(content_node);
}
entry.2 = include_children;
entry.3 = include_unnamed_children;
}
for (lang_name, content_nodes, includes_children) in injections_by_pattern_index
for (lang_name, content_nodes, includes_children, includes_unnamed_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,
includes_children,
includes_unnamed_children,
);
if !ranges.is_empty() {
injections.push((config, ranges));
Expand Down Expand Up @@ -1435,6 +1451,7 @@ fn intersect_ranges(
parent_ranges: &[Range],
nodes: &[Node],
includes_children: bool,
includes_unnamed_children: bool,
) -> Vec<Range> {
let mut cursor = nodes[0].walk();
let mut result = Vec::new();
Expand All @@ -1457,9 +1474,9 @@ fn intersect_ranges(
};

for excluded_range in node
.named_children(&mut cursor)
.children(&mut cursor)
.filter_map(|child| {
if includes_children {
if includes_children || (includes_unnamed_children && !child.is_named()) {
None
} else {
Some(child.range())
Expand Down Expand Up @@ -1791,7 +1808,7 @@ fn injection_for_match<'a>(
query: &'a Query,
query_match: &QueryMatch<'a, 'a>,
source: RopeSlice<'a>,
) -> (Option<Cow<'a, str>>, Option<Node<'a>>, bool) {
) -> (Option<Cow<'a, str>>, Option<Node<'a>>, bool, bool) {
let content_capture_index = config.injection_content_capture_index;
let language_capture_index = config.injection_language_capture_index;

Expand All @@ -1808,6 +1825,7 @@ fn injection_for_match<'a>(
}

let mut include_children = false;
let mut include_unnamed_children = false;
for prop in query.property_settings(query_match.pattern_index) {
match prop.key.as_ref() {
// In addition to specifying the language name via the text of a
Expand All @@ -1824,11 +1842,21 @@ fn injection_for_match<'a>(
// node itself. This can be changed using a `#set!` predicate that
// sets the `injection.include-children` key.
"injection.include-children" => include_children = true,

// Some queries might only exclude named children but include unnamed
// children in their `injection.content` node. This can be enabled using
// a `#set!` predicate that sets the `injection.include-unnamed-children` key.
"injection.include-unnamed-children" => include_unnamed_children = true,
_ => {}
}
}

(language_name, content_node, include_children)
(
language_name,
content_node,
include_children,
include_unnamed_children,
)
}

pub struct Merge<I> {
Expand Down

0 comments on commit 574fac3

Please sign in to comment.