Skip to content

Commit

Permalink
Add a "rainbow.include-children" property for HTML
Browse files Browse the repository at this point in the history
This allows us to use rainbow nesting highlights for HTML
tags. The nesting node is the HTML grammar's `element` node.
`<`/`>` are direct descendants of `start_tag` and `end_tag` rather
than `element` though. `<`/`>` is not valid in this grammar except
in cases where we want to highlight it. So we can exclude the
`start_tag` and `end_tag` parents (which aren't scopes) and
instead have the `element` match on any children `<`/`>`.

Note that "rainbow.include-children" only applies to the scope
captured with `@rainbow.scope`: any children scopes will disable
the setting.
  • Loading branch information
the-mikedavis committed Aug 15, 2022
1 parent 97d0056 commit 3396f9b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 11 deletions.
2 changes: 1 addition & 1 deletion book/src/generated/lang-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
| haskell || | | | `haskell-language-server-wrapper` |
| hcl || || | `terraform-ls` |
| heex ||| | | |
| html || | | | `vscode-html-language-server` |
| html || | | | `vscode-html-language-server` |
| idris | | | | | `idris2-lsp` |
| iex || | | | |
| java || | || `jdtls` |
Expand Down
24 changes: 14 additions & 10 deletions helix-core/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2000,13 +2000,22 @@ impl<'a> Iterator for RainbowIter<'a> {
// If the node represents a rainbow scope, push a new rainbow scope onto
// the scope stack.
if Some(capture.index) == layer.config.rainbow_scope_capture_index {
let scope = RainbowScope {
let mut scope = RainbowScope {
range: range.clone(),
node_id: capture.node.id(),
highlight: Highlight(
self.context.rainbow_stack.len() % self.context.rainbow_length,
),
};
for prop in layer
.config
.rainbow_query
.property_settings(match_.pattern_index)
{
if prop.key.as_ref() == "rainbow.include-children" {
scope.node_id = usize::MAX;
}
}
self.context.rainbow_stack.push(scope);
}

Expand All @@ -2024,15 +2033,10 @@ impl<'a> Iterator for RainbowIter<'a> {

if Some(capture.index) == layer.config.rainbow_bracket_capture_index {
if let Some(scope) = self.context.rainbow_stack.last() {
// Check that the parent of the `@rainbow.bracket` capture is
// the `@rainbow.scope` node. This allows us to have bracket
// highlights for type parameters/arguments in Rust for example
// without also highlighting operators like < and >.
if capture
.node
.parent()
.map(|p| p.id() == scope.node_id)
.unwrap_or_default()
// If the scope includes all children or if this capture is a direct descendant of
// the scope's captured node then this capture inherits the scope's highlight.
if scope.node_id == usize::MAX
|| capture.node.parent().map(|p| p.id()) == Some(scope.node_id)
{
rainbow_highlight = Some(scope.highlight);
}
Expand Down
13 changes: 13 additions & 0 deletions runtime/queries/html/rainbows.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
(doctype)
(erroneous_end_tag)
] @rainbow.scope

([
(element)
(script_element)
(style_element)
] @rainbow.scope
(#set! rainbow.include-children))

["<" ">" "<!" "</" "/>"] @rainbow.bracket

0 comments on commit 3396f9b

Please sign in to comment.