Rainbow tree-sitter matches 🌈 #13530
Open
+1,269
−275
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is #2857 based on the tree-house bindings. (Recreated after that PR closed unexpectedly)
Configurable, themable, nesting rainbow highlights:
This approach uses the syntax tree to guide nesting levels and highlights so it ends up being much more flexible than a naive pair-matching implementation. For example, we can highlight
<
/>
when used in Rust type parameters likestruct MyStruct<'a> { .. }
and not mistakenly highlight<
/>
comparison operators. We can also capture multiple nodes, for example the#
,[
and]
characters in a Rust attribute like#[cfg(windows)]
and none of these characters are required to be adjacent.The cherry on top is that we can highlight according to the syntax tree's nesting information rather than whether characters surround each other. For example, in this TOML table,
characters
is a sub-table ofeditor.whitespace
and the rainbow highlights reflect that fact.It also works across injected languages like javascript injected into HTML script tags.
(You can see each of these things in action in the gif above.)
How does it work?...
This implementation leverages tree-sitter queries. We use a
QueryCaptures
Iterator very similar to the existing one for syntax highlights to query the parsed syntax tree for newrainbows.scm
patterns.Two new captures -
@rainbow.scope
and@rainbow.bracket
- track nesting level and capture syntax nodes for highlighting with rainbows. Specifically:@rainbow.scope
pushes aRainbowScope
on a stack. When@rainbow.bracket
matches, we test that the captured node is a direct descendant of the current scope. If it is, we emit highlights for it according to the scope's level of nesting.Configuration...
In the theme we add a
rainbow
key that takes a list ofStyle
s. You can have however many you want and you can re-use colors from the palette or even throw modifiers in there:A default rainbow using the red, yellow, green, blue, cyan, and magenta terminal colors is used as a fallback.
Enable the rendering of rainbow brackets in your
config.toml
Or enable rendering per-language in
languages.toml
(this overrides theconfig.toml
setting for any languages that set this value):When the
rainbow-brackets
option is disabled, rainbow brackets are not rendered or computed.Closes #695