feat: Highlight Rust String interpolation macros

Fixes #5845
rainbow
Nikita Revenco 2025-02-04 03:31:04 +00:00 committed by Michael Davis
parent be1cf090c3
commit 9bb80a74e1
No known key found for this signature in database
4 changed files with 141 additions and 0 deletions

View File

@ -199,6 +199,7 @@
| rst | ✓ | | | |
| ruby | ✓ | ✓ | ✓ | `ruby-lsp`, `solargraph` |
| rust | ✓ | ✓ | ✓ | `rust-analyzer` |
| rustfmt | ✓ | | | |
| sage | ✓ | ✓ | | |
| scala | ✓ | ✓ | ✓ | `metals` |
| scheme | ✓ | | ✓ | |

View File

@ -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" }

View File

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

View File

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