Mercurial > forks > helix
changeset 6789:8923fd2fae2a
feat: Highlight Rust String interpolation macros
Fixes #5845
author | Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> |
---|---|
date | Tue, 04 Feb 2025 03:31:04 +0000 |
parents | 609d6c4223f6 |
children | c5a08bc07dc8 |
files | book/src/generated/lang-support.md languages.toml runtime/queries/rust/injections.scm runtime/queries/rustfmt/highlights.scm |
diffstat | 4 files changed, 141 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/book/src/generated/lang-support.md Tue Feb 25 11:57:27 2025 -0500 +++ b/book/src/generated/lang-support.md Tue Feb 04 03:31:04 2025 +0000 @@ -199,6 +199,7 @@ | rst | ✓ | | | | | ruby | ✓ | ✓ | ✓ | `ruby-lsp`, `solargraph` | | rust | ✓ | ✓ | ✓ | `rust-analyzer` | +| rustfmt | ✓ | | | | | sage | ✓ | ✓ | | | | scala | ✓ | ✓ | ✓ | `metals` | | scheme | ✓ | | ✓ | |
--- a/languages.toml Tue Feb 25 11:57:27 2025 -0500 +++ b/languages.toml Tue Feb 04 03:31:04 2025 +0000 @@ -4360,3 +4360,13 @@ [[grammar]] name = "dunstrc" source = { git = "https://github.com/rotmh/tree-sitter-dunstrc", rev = "9cb9d5cc51cf5e2a47bb2a0e2f2e519ff11c1431" } + +[[language]] +name = "rustfmt" +scope = "source.rustfmt" +file-types = [] +injection-regex = "rustfmt" + +[[grammar]] +name = "rustfmt" +source = { git = "https://github.com/nik-rev/tree-sitter-rustfmt", rev = "d8e517d9aca1905261a378b25688e4500ae4dd22" }
--- a/runtime/queries/rust/injections.scm Tue Feb 25 11:57:27 2025 -0500 +++ b/runtime/queries/rust/injections.scm Tue Feb 04 03:31:04 2025 +0000 @@ -97,3 +97,104 @@ ] ) (#set! injection.language "sql")) + +; std::fmt + +; For these, only the first argument is format_args! +((macro_invocation + macro: + [ + (scoped_identifier + name: (_) @_macro_name) + (identifier) @_macro_name + ] + (token_tree . (string_literal) @injection.content)) + (#any-of? @_macro_name + ; std + "format" + "print" + "println" + "eprint" + "eprintln" + "format_args" + "todo" + "unreachable" + "unimplemented" + "compile_error" + ; log + "crit" + "trace" + "debug" + "info" + "warn" + "error" + ; anyhow + "anyhow" + "bail" + ; syn + "format_ident" + ; indoc + "formatdoc" + "printdoc" + "eprintdoc" + "writedoc") + (#set! injection.language "rustfmt") + (#set! injection.include-children)) + +; For these, only the second argument is format_args! +((macro_invocation + macro: + [ + (scoped_identifier + name: (_) @_macro_name) + (identifier) @_macro_name + ] + (token_tree . (_) . (string_literal) @injection.content)) + (#any-of? @_macro_name + ; std + "write" + "writeln" + "assert" + "debug_assert") + (#set! injection.language "rustfmt") + (#set! injection.include-children)) + +; For these, only the third argument is format_args! +((macro_invocation + macro: + [ + (scoped_identifier + name: (_) @_macro_name) + (identifier) @_macro_name + ] + (token_tree . (_) . (_) . (string_literal) @injection.content)) + (#any-of? @_macro_name + ; std + "assert_eq" + "debug_assert_eq" + "assert_ne" + "debug_assert_ne") + (#set! injection.language "rustfmt") + (#set! injection.include-children)) + +; Dioxus' "rsx!" macro relies heavily on string interpolation as well. The strings can be nested very deeply +((macro_invocation + macro: + [ + (scoped_identifier + name: (_) @_macro_name) + (identifier) @_macro_name + ] + ; TODO: This only captures 1 level of string literals. But in dioxus you can have + ; nested string literals. For instance: + ; + ; rsx! { "{hello} world" }: + ; -> (token_tree (string_literal)) + ; rsx! { div { "{hello} world" } } + ; -> (token_tree (token_tree (string_literal))) + ; rsx! { div { div { "{hello} world" } } } + ; -> (token_tree (token_tree (token_tree (string_literal)))) + (token_tree (string_literal) @injection.content)) + (#eq? @_macro_name "rsx") + (#set! injection.language "rustfmt") + (#set! injection.include-children))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime/queries/rustfmt/highlights.scm Tue Feb 04 03:31:04 2025 +0000 @@ -0,0 +1,29 @@ +; (format_string) @string + +(escaped) @constant.character.escape + +[ + "#" + (type) +] @special + +[ + (sign) + (fill) + (align) + (width) +] @operator + +(number) @constant.numeric + +(colon) @punctuation + +(identifier) @variable + +((identifier) @constant + (#match? @constant "^[A-Z_]+$")) + +[ + "{" + "}" +] @punctuation.special