Skip to content

Commit

Permalink
inject language based on file extension
Browse files Browse the repository at this point in the history
Nodes can now be captured with "injection.extension". If this capture
contains a valid file extension known to Helix, then the content will
be highlighted as that language.
  • Loading branch information
nrdxp committed Sep 27, 2022
1 parent e8f0886 commit 0daa8d4
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
14 changes: 14 additions & 0 deletions helix-core/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ impl Syntax {
&layer.config.injections_query,
&mat,
source_slice,
&self.loader,
);

// Explicitly remove this match so that none of its other captures will remain
Expand Down Expand Up @@ -809,6 +810,7 @@ impl Syntax {
combined_injections_query,
&mat,
source_slice,
&self.loader,
);
if language_name.is_some() {
entry.0 = language_name;
Expand Down Expand Up @@ -1163,6 +1165,7 @@ pub struct HighlightConfiguration {
non_local_variable_patterns: Vec<bool>,
injection_content_capture_index: Option<u32>,
injection_language_capture_index: Option<u32>,
injection_filename_capture_index: Option<u32>,
local_scope_capture_index: Option<u32>,
local_def_capture_index: Option<u32>,
local_def_value_capture_index: Option<u32>,
Expand Down Expand Up @@ -1307,6 +1310,7 @@ impl HighlightConfiguration {
// Store the numeric ids for all of the special captures.
let mut injection_content_capture_index = None;
let mut injection_language_capture_index = None;
let mut injection_filename_capture_index = None;
let mut local_def_capture_index = None;
let mut local_def_value_capture_index = None;
let mut local_ref_capture_index = None;
Expand All @@ -1327,6 +1331,7 @@ impl HighlightConfiguration {
match name.as_str() {
"injection.content" => injection_content_capture_index = i,
"injection.language" => injection_language_capture_index = i,
"injection.filename" => injection_filename_capture_index = i,
_ => {}
}
}
Expand All @@ -1342,6 +1347,7 @@ impl HighlightConfiguration {
non_local_variable_patterns,
injection_content_capture_index,
injection_language_capture_index,
injection_filename_capture_index,
local_scope_capture_index,
local_def_capture_index,
local_def_value_capture_index,
Expand Down Expand Up @@ -1814,9 +1820,11 @@ fn injection_for_match<'a>(
query: &'a Query,
query_match: &QueryMatch<'a, 'a>,
source: RopeSlice<'a>,
loader: &Loader,
) -> (Option<Cow<'a, str>>, Option<Node<'a>>, IncludedChildren) {
let content_capture_index = config.injection_content_capture_index;
let language_capture_index = config.injection_language_capture_index;
let language_filename_index = config.injection_filename_capture_index;

let mut language_name = None;
let mut content_node = None;
Expand All @@ -1827,6 +1835,12 @@ fn injection_for_match<'a>(
language_name = Some(name);
} else if index == content_capture_index {
content_node = Some(capture.node);
} else if index == language_filename_index {
let file = byte_range_to_str(capture.node.byte_range(), source);
let language = loader.language_config_for_file_name(Path::new(file.as_ref()));
if let Some(config) = language {
language_name = Some(Cow::from(config.language_id.clone()));
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions runtime/queries/nix/injections.scm
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,10 @@
(#match? @_path "^text$")
(#set! injection.language "bash")
(#set! injection.combined))

((apply_expression
function: (apply_expression function: (_) @_func
argument: (string_expression (string_fragment) @injection.filename))
argument: (indented_string_expression (string_fragment) @injection.content))
(#match? @_func "(^|\\.)write(Text|Script(Bin)?)$")
(#set! injection.combined))

0 comments on commit 0daa8d4

Please sign in to comment.