@ -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 ,