diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 5670f8e9d773f..16909ef58b66b 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -5962,8 +5962,8 @@ async fn test_autoclose_with_embedded_language(cx: &mut gpui::TestAppContext) { .with_injection_query( r#" (script_element - (raw_text) @content - (#set! "language" "javascript")) + (raw_text) @injection.content + (#set! injection.language "javascript")) "#, ) .unwrap(), @@ -9068,8 +9068,8 @@ async fn test_toggle_block_comment(cx: &mut gpui::TestAppContext) { .with_injection_query( r#" (script_element - (raw_text) @content - (#set! "language" "javascript")) + (raw_text) @injection.content + (#set! injection.language "javascript")) "#, ) .unwrap(), diff --git a/crates/language/src/buffer_tests.rs b/crates/language/src/buffer_tests.rs index 4eab416965ef8..a90651d0d7e69 100644 --- a/crates/language/src/buffer_tests.rs +++ b/crates/language/src/buffer_tests.rs @@ -3115,8 +3115,8 @@ fn html_lang() -> Language { .with_injection_query( r#" (script_element - (raw_text) @content - (#set! "language" "javascript")) + (raw_text) @injection.content + (#set! injection.language "javascript")) "#, ) .unwrap() @@ -3138,15 +3138,15 @@ fn erb_lang() -> Language { .with_injection_query( r#" ( - (code) @content - (#set! "language" "ruby") - (#set! "combined") + (code) @injection.content + (#set! injection.language "ruby") + (#set! injection.combined) ) ( - (content) @content - (#set! "language" "html") - (#set! "combined") + (content) @injection.content + (#set! injection.language "html") + (#set! injection.combined) ) "#, ) @@ -3278,11 +3278,11 @@ pub fn markdown_lang() -> Language { r#" (fenced_code_block (info_string - (language) @language) - (code_fence_content) @content) + (language) @injection.language) + (code_fence_content) @injection.content) - ((inline) @content - (#set! "language" "markdown-inline")) + ((inline) @injection.content + (#set! injection.language "markdown-inline")) "#, ) .unwrap() diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index dfe9be8e268a9..793513e025fee 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -1273,23 +1273,45 @@ impl Language { .ok_or_else(|| anyhow!("cannot mutate grammar"))?; let query = Query::new(&grammar.ts_language, source)?; let mut language_capture_ix = None; + let mut injection_language_capture_ix = None; let mut content_capture_ix = None; + let mut injection_content_capture_ix = None; get_capture_indices( &query, &mut [ ("language", &mut language_capture_ix), + ("injection.language", &mut injection_language_capture_ix), ("content", &mut content_capture_ix), + ("injection.content", &mut injection_content_capture_ix), ], ); + language_capture_ix = match (language_capture_ix, injection_language_capture_ix) { + (None, Some(ix)) => Some(ix), + (Some(_), Some(_)) => { + return Err(anyhow!( + "both language and injection.language captures are present" + )); + } + _ => language_capture_ix, + }; + content_capture_ix = match (content_capture_ix, injection_content_capture_ix) { + (None, Some(ix)) => Some(ix), + (Some(_), Some(_)) => { + return Err(anyhow!( + "both content and injection.content captures are present" + )); + } + _ => content_capture_ix, + }; let patterns = (0..query.pattern_count()) .map(|ix| { let mut config = InjectionPatternConfig::default(); for setting in query.property_settings(ix) { match setting.key.as_ref() { - "language" => { + "language" | "injection.language" => { config.language.clone_from(&setting.value); } - "combined" => { + "combined" | "injection.combined" => { config.combined = true; } _ => {} diff --git a/crates/language/src/syntax_map/syntax_map_tests.rs b/crates/language/src/syntax_map/syntax_map_tests.rs index f6d27bcbd2194..8c3517af7a3bb 100644 --- a/crates/language/src/syntax_map/syntax_map_tests.rs +++ b/crates/language/src/syntax_map/syntax_map_tests.rs @@ -1193,15 +1193,15 @@ fn erb_lang() -> Language { .with_injection_query( r#" ( - (code) @content - (#set! "language" "ruby") - (#set! "combined") + (code) @injection.content + (#set! injection.language "ruby") + (#set! injection.combined) ) ( - (content) @content - (#set! "language" "html") - (#set! "combined") + (content) @injection.content + (#set! injection.language "html") + (#set! injection.combined) ) "#, ) @@ -1230,8 +1230,8 @@ fn rust_lang() -> Language { .with_injection_query( r#" (macro_invocation - (token_tree) @content - (#set! "language" "rust")) + (token_tree) @injection.content + (#set! injection.language "rust")) "#, ) .unwrap() @@ -1277,13 +1277,13 @@ fn heex_lang() -> Language { (partial_expression_value) (expression_value) (ending_expression_value) - ] @content) - (#set! language "elixir") - (#set! combined) + ] @injection.content) + (#set! injection.language "elixir") + (#set! injection.combined) ) - ((expression (expression_value) @content) - (#set! language "elixir")) + ((expression (expression_value) @injection.content) + (#set! injection.language "elixir")) "#, ) .unwrap() diff --git a/crates/languages/src/c/injections.scm b/crates/languages/src/c/injections.scm index 2696594af2151..73d2628225f05 100644 --- a/crates/languages/src/c/injections.scm +++ b/crates/languages/src/c/injections.scm @@ -1,7 +1,7 @@ (preproc_def - value: (preproc_arg) @content - (#set! "language" "c")) + value: (preproc_arg) @injection.content + (#set! injection.language "c")) (preproc_function_def - value: (preproc_arg) @content - (#set! "language" "c")) + value: (preproc_arg) @injection.content + (#set! injection.language "c")) diff --git a/crates/languages/src/cpp/injections.scm b/crates/languages/src/cpp/injections.scm index 57cd3ac7f32ad..e903e1affd53a 100644 --- a/crates/languages/src/cpp/injections.scm +++ b/crates/languages/src/cpp/injections.scm @@ -1,11 +1,11 @@ (preproc_def - value: (preproc_arg) @content - (#set! "language" "c++")) + value: (preproc_arg) @injection.content + (#set! injection.language "c++")) (preproc_function_def - value: (preproc_arg) @content - (#set! "language" "c++")) + value: (preproc_arg) @injection.content + (#set! injection.language "c++")) (raw_string_literal - delimiter: (raw_string_delimiter) @language - (raw_string_content) @content) + delimiter: (raw_string_delimiter) @injection.language + (raw_string_content) @injection.content) diff --git a/crates/languages/src/go/injections.scm b/crates/languages/src/go/injections.scm index 7744d98679baa..2be0844d97b7f 100644 --- a/crates/languages/src/go/injections.scm +++ b/crates/languages/src/go/injections.scm @@ -9,5 +9,5 @@ [ (raw_string_literal) (interpreted_string_literal) - ] @content - (#set! "language" "regex"))) + ] @injection.content + (#set! injection.language "regex"))) diff --git a/crates/languages/src/javascript/injections.scm b/crates/languages/src/javascript/injections.scm index 180608944aba5..7baba5f227eb0 100644 --- a/crates/languages/src/javascript/injections.scm +++ b/crates/languages/src/javascript/injections.scm @@ -1,60 +1,60 @@ (((comment) @_jsdoc_comment - (#match? @_jsdoc_comment "(?s)^/[*][*][^*].*[*]/$")) @content - (#set! "language" "jsdoc")) + (#match? @_jsdoc_comment "(?s)^/[*][*][^*].*[*]/$")) @injection.content + (#set! injection.language "jsdoc")) -((regex) @content - (#set! "language" "regex")) +((regex) @injection.content + (#set! injection.language "regex")) (call_expression function: (identifier) @_name (#eq? @_name "css") - arguments: (template_string (string_fragment) @content - (#set! "language" "css")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "css")) ) (call_expression function: (identifier) @_name (#eq? @_name "html") - arguments: (template_string) @content - (#set! "language" "html") + arguments: (template_string) @injection.content + (#set! injection.language "html") ) (call_expression function: (identifier) @_name (#eq? @_name "js") - arguments: (template_string (string_fragment) @content - (#set! "language" "javascript")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "javascript")) ) (call_expression function: (identifier) @_name (#eq? @_name "json") - arguments: (template_string (string_fragment) @content - (#set! "language" "json")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "json")) ) (call_expression function: (identifier) @_name (#eq? @_name "sql") - arguments: (template_string (string_fragment) @content - (#set! "language" "sql")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "sql")) ) (call_expression function: (identifier) @_name (#eq? @_name "ts") - arguments: (template_string (string_fragment) @content - (#set! "language" "typescript")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "typescript")) ) (call_expression function: (identifier) @_name (#match? @_name "^ya?ml$") - arguments: (template_string (string_fragment) @content - (#set! "language" "yaml")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "yaml")) ) (call_expression function: (identifier) @_name (#match? @_name "^g(raph)?ql$") - arguments: (template_string (string_fragment) @content - (#set! "language" "graphql")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "graphql")) ) (call_expression function: (identifier) @_name (#match? @_name "^g(raph)?ql$") - arguments: (arguments (template_string (string_fragment) @content - (#set! "language" "graphql"))) + arguments: (arguments (template_string (string_fragment) @injection.content + (#set! injection.language "graphql"))) ) diff --git a/crates/languages/src/markdown/injections.scm b/crates/languages/src/markdown/injections.scm index b2c35642e554b..f2b959dfdae9d 100644 --- a/crates/languages/src/markdown/injections.scm +++ b/crates/languages/src/markdown/injections.scm @@ -1,14 +1,14 @@ (fenced_code_block (info_string - (language) @language) - (code_fence_content) @content) + (language) @injection.language) + (code_fence_content) @injection.content) -((inline) @content - (#set! "language" "markdown-inline")) +((inline) @injection.content + (#set! injection.language "markdown-inline")) -((html_block) @content - (#set! "language" "html")) +((html_block) @injection.content + (#set! injection.language "html")) -((minus_metadata) @content (#set! "language" "yaml")) +((minus_metadata) @injection.content (#set! injection.language "yaml")) -((plus_metadata) @content (#set! "language" "toml")) +((plus_metadata) @injection.content (#set! injection.language "toml")) diff --git a/crates/languages/src/rust/injections.scm b/crates/languages/src/rust/injections.scm index 0ce91f228773f..0c6094ec19898 100644 --- a/crates/languages/src/rust/injections.scm +++ b/crates/languages/src/rust/injections.scm @@ -1,7 +1,7 @@ (macro_invocation - (token_tree) @content - (#set! "language" "rust")) + (token_tree) @injection.content + (#set! injection.language "rust")) (macro_rule - (token_tree) @content - (#set! "language" "rust")) + (token_tree) @injection.content + (#set! injection.language "rust")) diff --git a/crates/languages/src/tsx/injections.scm b/crates/languages/src/tsx/injections.scm index 3aa6bfd7455ec..48da80995bba8 100644 --- a/crates/languages/src/tsx/injections.scm +++ b/crates/languages/src/tsx/injections.scm @@ -1,60 +1,60 @@ (((comment) @_jsdoc_comment - (#match? @_jsdoc_comment "(?s)^/[*][*][^*].*[*]/$")) @content - (#set! "language" "jsdoc")) + (#match? @_jsdoc_comment "(?s)^/[*][*][^*].*[*]/$")) @injection.content + (#set! injection.language "jsdoc")) -((regex) @content - (#set! "language" "regex")) +((regex) @injection.content + (#set! injection.language "regex")) (call_expression function: (identifier) @_name (#eq? @_name "css") - arguments: (template_string (string_fragment) @content - (#set! "language" "css")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "css")) ) (call_expression function: (identifier) @_name (#eq? @_name "html") - arguments: (template_string (string_fragment) @content - (#set! "language" "html")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "html")) ) (call_expression function: (identifier) @_name (#eq? @_name "js") - arguments: (template_string (string_fragment) @content - (#set! "language" "javascript")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "javascript")) ) (call_expression function: (identifier) @_name (#eq? @_name "json") - arguments: (template_string (string_fragment) @content - (#set! "language" "json")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "json")) ) (call_expression function: (identifier) @_name (#eq? @_name "sql") - arguments: (template_string (string_fragment) @content - (#set! "language" "sql")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "sql")) ) (call_expression function: (identifier) @_name (#eq? @_name "ts") - arguments: (template_string (string_fragment) @content - (#set! "language" "typescript")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "typescript")) ) (call_expression function: (identifier) @_name (#match? @_name "^ya?ml$") - arguments: (template_string (string_fragment) @content - (#set! "language" "yaml")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "yaml")) ) (call_expression function: (identifier) @_name (#match? @_name "^g(raph)?ql$") - arguments: (template_string (string_fragment) @content - (#set! "language" "graphql")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "graphql")) ) (call_expression function: (identifier) @_name (#match? @_name "^g(raph)?ql$") - arguments: (arguments (template_string (string_fragment) @content - (#set! "language" "graphql"))) + arguments: (arguments (template_string (string_fragment) @injection.content + (#set! injection.language "graphql"))) ) diff --git a/crates/languages/src/typescript/injections.scm b/crates/languages/src/typescript/injections.scm index db8d7a9b59cb9..c8bb72bdc59d2 100644 --- a/crates/languages/src/typescript/injections.scm +++ b/crates/languages/src/typescript/injections.scm @@ -1,64 +1,64 @@ (((comment) @_jsdoc_comment - (#match? @_jsdoc_comment "(?s)^/[*][*][^*].*[*]/$")) @content - (#set! "language" "jsdoc")) + (#match? @_jsdoc_comment "(?s)^/[*][*][^*].*[*]/$")) @injection.content + (#set! injection.language "jsdoc")) (((comment) @reference - (#match? @reference "^///\\s+\\s*$")) @content - (#set! "language" "html")) + (#match? @reference "^///\\s+\\s*$")) @injection.content + (#set! injection.language "html")) -((regex) @content - (#set! "language" "regex")) +((regex) @injection.content + (#set! injection.language "regex")) (call_expression function: (identifier) @_name (#eq? @_name "css") - arguments: (template_string (string_fragment) @content - (#set! "language" "css")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "css")) ) (call_expression function: (identifier) @_name (#eq? @_name "html") - arguments: (template_string) @content - (#set! "language" "html") + arguments: (template_string) @injection.content + (#set! injection.language "html") ) (call_expression function: (identifier) @_name (#eq? @_name "js") - arguments: (template_string (string_fragment) @content - (#set! "language" "javascript")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "javascript")) ) (call_expression function: (identifier) @_name (#eq? @_name "json") - arguments: (template_string (string_fragment) @content - (#set! "language" "json")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "json")) ) (call_expression function: (identifier) @_name (#eq? @_name "sql") - arguments: (template_string (string_fragment) @content - (#set! "language" "sql")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "sql")) ) (call_expression function: (identifier) @_name (#eq? @_name "ts") - arguments: (template_string (string_fragment) @content - (#set! "language" "typescript")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "typescript")) ) (call_expression function: (identifier) @_name (#match? @_name "^ya?ml$") - arguments: (template_string (string_fragment) @content - (#set! "language" "yaml")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "yaml")) ) (call_expression function: (identifier) @_name (#match? @_name "^g(raph)?ql$") - arguments: (template_string (string_fragment) @content - (#set! "language" "graphql")) + arguments: (template_string (string_fragment) @injection.content + (#set! injection.language "graphql")) ) (call_expression function: (identifier) @_name (#match? @_name "^g(raph)?ql$") - arguments: (arguments (template_string (string_fragment) @content - (#set! "language" "graphql"))) + arguments: (arguments (template_string (string_fragment) @injection.content + (#set! injection.language "graphql"))) ) diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index c5c857c25181e..79ee08fa017bb 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -6043,8 +6043,8 @@ mod tests { .with_injection_query( r#" (macro_invocation - (token_tree) @content - (#set! "language" "rust")) + (token_tree) @injection.content + (#set! injection.language "rust")) "#, ) .unwrap() diff --git a/docs/src/extensions/languages.md b/docs/src/extensions/languages.md index 9b414ab4fe858..40a41d36b74de 100644 --- a/docs/src/extensions/languages.md +++ b/docs/src/extensions/languages.md @@ -203,19 +203,19 @@ Here's an example from an `injections.scm` file for Markdown: ```scheme (fenced_code_block (info_string - (language) @language) - (code_fence_content) @content) + (language) @injection.language) + (code_fence_content) @injection.content) ((inline) @content - (#set! "language" "markdown-inline")) + (#set! injection.language "markdown-inline")) ``` This query identifies fenced code blocks, capturing the language specified in the info string and the content within the block. It also captures inline content and sets its language to "markdown-inline". -| Capture | Description | -| --------- | ---------------------------------------------------------- | -| @language | Captures the language identifier for a code block | -| @content | Captures the content to be treated as a different language | +| Capture | Description | +| ------------------- | ---------------------------------------------------------- | +| @injection.language | Captures the language identifier for a code block | +| @injection.content | Captures the content to be treated as a different language | Note that we couldn't use JSON as an example here because it doesn't support language injections. diff --git a/extensions/elixir/languages/elixir/injections.scm b/extensions/elixir/languages/elixir/injections.scm index 4de229f1046ca..009c82505b46b 100644 --- a/extensions/elixir/languages/elixir/injections.scm +++ b/extensions/elixir/languages/elixir/injections.scm @@ -2,6 +2,6 @@ ((sigil (sigil_name) @_sigil_name - (quoted_content) @content) + (quoted_content) @injection.content) (#eq? @_sigil_name "H") - (#set! language "heex")) + (#set! injection.language "heex")) diff --git a/extensions/elixir/languages/heex/injections.scm b/extensions/elixir/languages/heex/injections.scm index b503bcb28dc10..96c1d7c8c00d9 100644 --- a/extensions/elixir/languages/heex/injections.scm +++ b/extensions/elixir/languages/heex/injections.scm @@ -4,10 +4,10 @@ (partial_expression_value) (expression_value) (ending_expression_value) - ] @content) - (#set! language "elixir") - (#set! combined) + ] @injection.content) + (#set! injection.language "elixir") + (#set! injection.combined) ) -((expression (expression_value) @content) - (#set! language "elixir")) +((expression (expression_value) @injection.content) + (#set! injection.language "elixir")) diff --git a/extensions/html/languages/html/injections.scm b/extensions/html/languages/html/injections.scm index 9084e373f217b..1c31b2a0a95e8 100644 --- a/extensions/html/languages/html/injections.scm +++ b/extensions/html/languages/html/injections.scm @@ -1,7 +1,7 @@ (script_element - (raw_text) @content - (#set! "language" "javascript")) + (raw_text) @injection.content + (#set! injection.language "javascript")) (style_element - (raw_text) @content - (#set! "language" "css")) + (raw_text) @injection.content + (#set! injection.language "css")) diff --git a/extensions/php/languages/php/injections.scm b/extensions/php/languages/php/injections.scm index 122d0b377af70..fdf5559130d47 100644 --- a/extensions/php/languages/php/injections.scm +++ b/extensions/php/languages/php/injections.scm @@ -1,9 +1,9 @@ -((text) @content - (#set! "language" "html") - (#set! "combined")) +((text) @injection.content + (#set! injection.language "html") + (#set! injection.combined)) -((comment) @content - (#match? @content "^/\\*\\*[^*]") - (#set! "language" "phpdoc")) +((comment) @injection.content + (#match? @injection.content "^/\\*\\*[^*]") + (#set! injection.language "phpdoc")) -((heredoc_body) (heredoc_end) @language) @content +((heredoc_body) (heredoc_end) @injection.language) @injection.content diff --git a/extensions/terraform/languages/hcl/injections.scm b/extensions/terraform/languages/hcl/injections.scm index 8617e9fc2ef43..f06f6b970c4e3 100644 --- a/extensions/terraform/languages/hcl/injections.scm +++ b/extensions/terraform/languages/hcl/injections.scm @@ -1,6 +1,6 @@ ; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/hcl/injections.scm (heredoc_template - (template_literal) @content - (heredoc_identifier) @language - (#downcase! @language)) + (template_literal) @injection.content + (heredoc_identifier) @injection.language + (#downcase! @injection.language)) diff --git a/extensions/terraform/languages/terraform-vars/injections.scm b/extensions/terraform/languages/terraform-vars/injections.scm index b41ee95d403ce..49e7d8d325194 100644 --- a/extensions/terraform/languages/terraform-vars/injections.scm +++ b/extensions/terraform/languages/terraform-vars/injections.scm @@ -1,9 +1,9 @@ ; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/hcl/injections.scm (heredoc_template - (template_literal) @content - (heredoc_identifier) @language - (#downcase! @language)) + (template_literal) @injection.content + (heredoc_identifier) @injection.language + (#downcase! @injection.language)) ; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/terraform/injections.scm ; inherits: hcl diff --git a/extensions/terraform/languages/terraform/injections.scm b/extensions/terraform/languages/terraform/injections.scm index b41ee95d403ce..49e7d8d325194 100644 --- a/extensions/terraform/languages/terraform/injections.scm +++ b/extensions/terraform/languages/terraform/injections.scm @@ -1,9 +1,9 @@ ; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/hcl/injections.scm (heredoc_template - (template_literal) @content - (heredoc_identifier) @language - (#downcase! @language)) + (template_literal) @injection.content + (heredoc_identifier) @injection.language + (#downcase! @injection.language)) ; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/terraform/injections.scm ; inherits: hcl