Unnamed repository; edit this file 'description' to name the repository.
feat: Highlight Rust String interpolation macros
Fixes #5845
Nikita Revenco 10 months ago
parent be1cf09 · commit 9bb80a7
-rw-r--r--book/src/generated/lang-support.md1
-rw-r--r--languages.toml10
-rw-r--r--runtime/queries/rust/injections.scm101
-rw-r--r--runtime/queries/rustfmt/highlights.scm29
4 files changed, 141 insertions, 0 deletions
diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md
index 1447b66d..96572377 100644
--- a/book/src/generated/lang-support.md
+++ b/book/src/generated/lang-support.md
@@ -199,6 +199,7 @@
| rst | ✓ | | | |
| ruby | ✓ | ✓ | ✓ | `ruby-lsp`, `solargraph` |
| rust | ✓ | ✓ | ✓ | `rust-analyzer` |
+| rustfmt | ✓ | | | |
| sage | ✓ | ✓ | | |
| scala | ✓ | ✓ | ✓ | `metals` |
| scheme | ✓ | | ✓ | |
diff --git a/languages.toml b/languages.toml
index 7cc37300..e286c450 100644
--- a/languages.toml
+++ b/languages.toml
@@ -4360,3 +4360,13 @@ file-types = [ { glob = "dunst/dunstrc" } ]
[[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" }
diff --git a/runtime/queries/rust/injections.scm b/runtime/queries/rust/injections.scm
index 42ca12b5..2c9ec7b1 100644
--- a/runtime/queries/rust/injections.scm
+++ b/runtime/queries/rust/injections.scm
@@ -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))
diff --git a/runtime/queries/rustfmt/highlights.scm b/runtime/queries/rustfmt/highlights.scm
new file mode 100644
index 00000000..a4a99f99
--- /dev/null
+++ b/runtime/queries/rustfmt/highlights.scm
@@ -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