mirror of https://github.com/helix-editor/helix
Add rainbow highlights based on tree-sitter queries
parent
f46222ced3
commit
71cc25cbef
|
@ -13,14 +13,18 @@ use std::{
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use arc_swap::{ArcSwap, Guard};
|
use arc_swap::{ArcSwap, Guard};
|
||||||
use config::{Configuration, FileType, LanguageConfiguration, LanguageServerConfiguration};
|
use config::{Configuration, FileType, LanguageConfiguration, LanguageServerConfiguration};
|
||||||
|
use foldhash::HashSet;
|
||||||
use helix_loader::grammar::get_language;
|
use helix_loader::grammar::get_language;
|
||||||
use helix_stdx::rope::RopeSliceExt as _;
|
use helix_stdx::rope::RopeSliceExt as _;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use ropey::RopeSlice;
|
use ropey::RopeSlice;
|
||||||
use tree_house::{
|
use tree_house::{
|
||||||
highlighter,
|
highlighter,
|
||||||
query_iter::QueryIter,
|
query_iter::{QueryIter, QueryIterEvent},
|
||||||
tree_sitter::{Grammar, InactiveQueryCursor, InputEdit, Node, Query, RopeInput, Tree},
|
tree_sitter::{
|
||||||
|
query::{InvalidPredicateError, UserPredicate},
|
||||||
|
Capture, Grammar, InactiveQueryCursor, InputEdit, Node, Pattern, Query, RopeInput, Tree,
|
||||||
|
},
|
||||||
Error, InjectionLanguageMarker, LanguageConfig as SyntaxConfig, Layer,
|
Error, InjectionLanguageMarker, LanguageConfig as SyntaxConfig, Layer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,6 +41,7 @@ pub struct LanguageData {
|
||||||
syntax: OnceCell<Option<SyntaxConfig>>,
|
syntax: OnceCell<Option<SyntaxConfig>>,
|
||||||
indent_query: OnceCell<Option<IndentQuery>>,
|
indent_query: OnceCell<Option<IndentQuery>>,
|
||||||
textobject_query: OnceCell<Option<TextObjectQuery>>,
|
textobject_query: OnceCell<Option<TextObjectQuery>>,
|
||||||
|
rainbow_query: OnceCell<Option<RainbowQuery>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LanguageData {
|
impl LanguageData {
|
||||||
|
@ -46,6 +51,7 @@ impl LanguageData {
|
||||||
syntax: OnceCell::new(),
|
syntax: OnceCell::new(),
|
||||||
indent_query: OnceCell::new(),
|
indent_query: OnceCell::new(),
|
||||||
textobject_query: OnceCell::new(),
|
textobject_query: OnceCell::new(),
|
||||||
|
rainbow_query: OnceCell::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +160,36 @@ impl LanguageData {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compiles the rainbows.scm query for a language.
|
||||||
|
/// This function should only be used by this module or the xtask crate.
|
||||||
|
pub fn compile_rainbow_query(
|
||||||
|
grammar: Grammar,
|
||||||
|
config: &LanguageConfiguration,
|
||||||
|
) -> Result<Option<RainbowQuery>> {
|
||||||
|
let name = &config.language_id;
|
||||||
|
let text = read_query(name, "rainbows.scm");
|
||||||
|
if text.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
let rainbow_query = RainbowQuery::new(grammar, &text)
|
||||||
|
.with_context(|| format!("Failed to compile rainbows.scm query for '{name}'"))?;
|
||||||
|
Ok(Some(rainbow_query))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rainbow_query(&self, loader: &Loader) -> Option<&RainbowQuery> {
|
||||||
|
self.rainbow_query
|
||||||
|
.get_or_init(|| {
|
||||||
|
let grammar = self.syntax_config(loader)?.grammar;
|
||||||
|
Self::compile_rainbow_query(grammar, &self.config)
|
||||||
|
.map_err(|err| {
|
||||||
|
log::error!("{err}");
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
})
|
||||||
|
.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
fn reconfigure(&self, scopes: &[String]) {
|
fn reconfigure(&self, scopes: &[String]) {
|
||||||
if let Some(Some(config)) = self.syntax.get() {
|
if let Some(Some(config)) = self.syntax.get() {
|
||||||
reconfigure_highlights(config, scopes);
|
reconfigure_highlights(config, scopes);
|
||||||
|
@ -324,6 +360,10 @@ impl Loader {
|
||||||
self.language(lang).textobject_query(self)
|
self.language(lang).textobject_query(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rainbow_query(&self, lang: Language) -> Option<&RainbowQuery> {
|
||||||
|
self.language(lang).rainbow_query(self)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn language_server_configs(&self) -> &HashMap<String, LanguageServerConfiguration> {
|
pub fn language_server_configs(&self) -> &HashMap<String, LanguageServerConfiguration> {
|
||||||
&self.language_server_configs
|
&self.language_server_configs
|
||||||
}
|
}
|
||||||
|
@ -496,6 +536,79 @@ impl Syntax {
|
||||||
{
|
{
|
||||||
QueryIter::new(&self.inner, source, loader, range)
|
QueryIter::new(&self.inner, source, loader, range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rainbow_highlights(
|
||||||
|
&self,
|
||||||
|
source: RopeSlice,
|
||||||
|
rainbow_length: usize,
|
||||||
|
loader: &Loader,
|
||||||
|
range: impl RangeBounds<u32>,
|
||||||
|
) -> OverlayHighlights {
|
||||||
|
struct RainbowScope<'tree> {
|
||||||
|
end: u32,
|
||||||
|
node: Option<Node<'tree>>,
|
||||||
|
highlight: Highlight,
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut scope_stack = Vec::<RainbowScope>::new();
|
||||||
|
let mut highlights = Vec::new();
|
||||||
|
let mut query_iter = self.query_iter::<_, (), _>(
|
||||||
|
source,
|
||||||
|
|lang| loader.rainbow_query(lang).map(|q| &q.query),
|
||||||
|
range,
|
||||||
|
);
|
||||||
|
|
||||||
|
while let Some(event) = query_iter.next() {
|
||||||
|
let QueryIterEvent::Match(mat) = event else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let rainbow_query = loader
|
||||||
|
.rainbow_query(query_iter.current_language())
|
||||||
|
.expect("language must have a rainbow query to emit matches");
|
||||||
|
|
||||||
|
let byte_range = mat.node.byte_range();
|
||||||
|
// Pop any scopes that end before this capture begins.
|
||||||
|
while scope_stack
|
||||||
|
.last()
|
||||||
|
.is_some_and(|scope| byte_range.start >= scope.end)
|
||||||
|
{
|
||||||
|
scope_stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
let capture = Some(mat.capture);
|
||||||
|
if capture == rainbow_query.scope_capture {
|
||||||
|
scope_stack.push(RainbowScope {
|
||||||
|
end: byte_range.end,
|
||||||
|
node: if rainbow_query
|
||||||
|
.include_children_patterns
|
||||||
|
.contains(&mat.pattern)
|
||||||
|
{
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(mat.node.clone())
|
||||||
|
},
|
||||||
|
highlight: Highlight::new((scope_stack.len() % rainbow_length) as u32),
|
||||||
|
});
|
||||||
|
} else if capture == rainbow_query.bracket_capture {
|
||||||
|
if let Some(scope) = scope_stack.last() {
|
||||||
|
if !scope
|
||||||
|
.node
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|node| mat.node.parent().as_ref() != Some(node))
|
||||||
|
{
|
||||||
|
let start = source
|
||||||
|
.byte_to_char(source.floor_char_boundary(byte_range.start as usize));
|
||||||
|
let end =
|
||||||
|
source.byte_to_char(source.ceil_char_boundary(byte_range.end as usize));
|
||||||
|
highlights.push((scope.highlight, start..end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayHighlights::Heterogenous { highlights }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Highlighter<'a> = highlighter::Highlighter<'a, 'a, Loader>;
|
pub type Highlighter<'a> = highlighter::Highlighter<'a, 'a, Loader>;
|
||||||
|
@ -939,6 +1052,57 @@ fn pretty_print_tree_impl<W: fmt::Write>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Finds the child of `node` which contains the given byte range.
|
||||||
|
|
||||||
|
pub fn child_for_byte_range<'a>(node: &Node<'a>, range: ops::Range<u32>) -> Option<Node<'a>> {
|
||||||
|
for child in node.children() {
|
||||||
|
let child_range = child.byte_range();
|
||||||
|
|
||||||
|
if range.start >= child_range.start && range.end <= child_range.end {
|
||||||
|
return Some(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RainbowQuery {
|
||||||
|
query: Query,
|
||||||
|
include_children_patterns: HashSet<Pattern>,
|
||||||
|
scope_capture: Option<Capture>,
|
||||||
|
bracket_capture: Option<Capture>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RainbowQuery {
|
||||||
|
fn new(grammar: Grammar, source: &str) -> Result<Self, tree_sitter::query::ParseError> {
|
||||||
|
let mut include_children_patterns = HashSet::default();
|
||||||
|
|
||||||
|
let query = Query::new(grammar, source, |pattern, predicate| match predicate {
|
||||||
|
UserPredicate::SetProperty {
|
||||||
|
key: "rainbow.include-children",
|
||||||
|
val,
|
||||||
|
} => {
|
||||||
|
if val.is_some() {
|
||||||
|
return Err(
|
||||||
|
"property 'rainbow.include-children' does not take an argument".into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
include_children_patterns.insert(pattern);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
_ => Err(InvalidPredicateError::unknown(predicate)),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
include_children_patterns,
|
||||||
|
scope_capture: query.get_capture("rainbow.scope"),
|
||||||
|
bracket_capture: query.get_capture("rainbow.bracket"),
|
||||||
|
query,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
|
@ -98,6 +98,8 @@ pub struct LanguageConfiguration {
|
||||||
pub workspace_lsp_roots: Option<Vec<PathBuf>>,
|
pub workspace_lsp_roots: Option<Vec<PathBuf>>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub persistent_diagnostic_sources: Vec<String>,
|
pub persistent_diagnostic_sources: Vec<String>,
|
||||||
|
/// Overrides the `editor.rainbow-brackets` config key for the language.
|
||||||
|
pub rainbow_brackets: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LanguageConfiguration {
|
impl LanguageConfiguration {
|
||||||
|
|
|
@ -127,6 +127,18 @@ impl EditorView {
|
||||||
&text_annotations,
|
&text_annotations,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if doc
|
||||||
|
.language_config()
|
||||||
|
.and_then(|config| config.rainbow_brackets)
|
||||||
|
.unwrap_or(config.rainbow_brackets)
|
||||||
|
{
|
||||||
|
if let Some(overlay) =
|
||||||
|
Self::doc_rainbow_highlights(doc, view_offset.anchor, inner.height, theme, &loader)
|
||||||
|
{
|
||||||
|
overlays.push(overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Self::doc_diagnostics_highlights_into(doc, theme, &mut overlays);
|
Self::doc_diagnostics_highlights_into(doc, theme, &mut overlays);
|
||||||
|
|
||||||
if is_focused {
|
if is_focused {
|
||||||
|
@ -304,6 +316,27 @@ impl EditorView {
|
||||||
text_annotations.collect_overlay_highlights(range)
|
text_annotations.collect_overlay_highlights(range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn doc_rainbow_highlights(
|
||||||
|
doc: &Document,
|
||||||
|
anchor: usize,
|
||||||
|
height: u16,
|
||||||
|
theme: &Theme,
|
||||||
|
loader: &syntax::Loader,
|
||||||
|
) -> Option<OverlayHighlights> {
|
||||||
|
let syntax = doc.syntax()?;
|
||||||
|
let text = doc.text().slice(..);
|
||||||
|
let row = text.char_to_line(anchor.min(text.len_chars()));
|
||||||
|
let visible_range = Self::viewport_byte_range(text, row, height);
|
||||||
|
let start = syntax::child_for_byte_range(
|
||||||
|
&syntax.tree().root_node(),
|
||||||
|
visible_range.start as u32..visible_range.end as u32,
|
||||||
|
)
|
||||||
|
.map_or(visible_range.start as u32, |node| node.start_byte());
|
||||||
|
let range = start..visible_range.end as u32;
|
||||||
|
|
||||||
|
Some(syntax.rainbow_highlights(text, theme.rainbow_length(), loader, range))
|
||||||
|
}
|
||||||
|
|
||||||
/// Get highlight spans for document diagnostics
|
/// Get highlight spans for document diagnostics
|
||||||
pub fn doc_diagnostics_highlights_into(
|
pub fn doc_diagnostics_highlights_into(
|
||||||
doc: &Document,
|
doc: &Document,
|
||||||
|
|
|
@ -373,6 +373,8 @@ pub struct Config {
|
||||||
/// Whether to read settings from [EditorConfig](https://editorconfig.org) files. Defaults to
|
/// Whether to read settings from [EditorConfig](https://editorconfig.org) files. Defaults to
|
||||||
/// `true`.
|
/// `true`.
|
||||||
pub editor_config: bool,
|
pub editor_config: bool,
|
||||||
|
/// Whether to render rainbow colors for matching brackets. Defaults to `false`.
|
||||||
|
pub rainbow_brackets: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
|
||||||
|
@ -1024,6 +1026,7 @@ impl Default for Config {
|
||||||
end_of_line_diagnostics: DiagnosticFilter::Disable,
|
end_of_line_diagnostics: DiagnosticFilter::Disable,
|
||||||
clipboard_provider: ClipboardProvider::default(),
|
clipboard_provider: ClipboardProvider::default(),
|
||||||
editor_config: true,
|
editor_config: true,
|
||||||
|
rainbow_brackets: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,6 +227,7 @@ pub struct Theme {
|
||||||
// tree-sitter highlight styles are stored in a Vec to optimize lookups
|
// tree-sitter highlight styles are stored in a Vec to optimize lookups
|
||||||
scopes: Vec<String>,
|
scopes: Vec<String>,
|
||||||
highlights: Vec<Style>,
|
highlights: Vec<Style>,
|
||||||
|
rainbow_length: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Value> for Theme {
|
impl From<Value> for Theme {
|
||||||
|
@ -253,12 +254,20 @@ impl<'de> Deserialize<'de> for Theme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
fn build_theme_values(
|
fn build_theme_values(
|
||||||
mut values: Map<String, Value>,
|
mut values: Map<String, Value>,
|
||||||
) -> (HashMap<String, Style>, Vec<String>, Vec<Style>, Vec<String>) {
|
) -> (
|
||||||
|
HashMap<String, Style>,
|
||||||
|
Vec<String>,
|
||||||
|
Vec<Style>,
|
||||||
|
usize,
|
||||||
|
Vec<String>,
|
||||||
|
) {
|
||||||
let mut styles = HashMap::new();
|
let mut styles = HashMap::new();
|
||||||
let mut scopes = Vec::new();
|
let mut scopes = Vec::new();
|
||||||
let mut highlights = Vec::new();
|
let mut highlights = Vec::new();
|
||||||
|
let mut rainbow_length = 0;
|
||||||
|
|
||||||
let mut warnings = Vec::new();
|
let mut warnings = Vec::new();
|
||||||
|
|
||||||
|
@ -277,6 +286,27 @@ fn build_theme_values(
|
||||||
styles.reserve(values.len());
|
styles.reserve(values.len());
|
||||||
scopes.reserve(values.len());
|
scopes.reserve(values.len());
|
||||||
highlights.reserve(values.len());
|
highlights.reserve(values.len());
|
||||||
|
|
||||||
|
for (i, style) in values
|
||||||
|
.remove("rainbow")
|
||||||
|
.and_then(|value| match palette.parse_style_array(value) {
|
||||||
|
Ok(styles) => Some(styles),
|
||||||
|
Err(err) => {
|
||||||
|
warnings.push(err);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or_else(default_rainbow)
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
let name = format!("rainbow.{i}");
|
||||||
|
styles.insert(name.clone(), style);
|
||||||
|
scopes.push(name);
|
||||||
|
highlights.push(style);
|
||||||
|
rainbow_length += 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (name, style_value) in values {
|
for (name, style_value) in values {
|
||||||
let mut style = Style::default();
|
let mut style = Style::default();
|
||||||
if let Err(err) = palette.parse_style(&mut style, style_value) {
|
if let Err(err) = palette.parse_style(&mut style, style_value) {
|
||||||
|
@ -289,9 +319,19 @@ fn build_theme_values(
|
||||||
highlights.push(style);
|
highlights.push(style);
|
||||||
}
|
}
|
||||||
|
|
||||||
(styles, scopes, highlights, warnings)
|
(styles, scopes, highlights, rainbow_length, warnings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_rainbow() -> Vec<Style> {
|
||||||
|
vec![
|
||||||
|
Style::default().fg(Color::Red),
|
||||||
|
Style::default().fg(Color::Yellow),
|
||||||
|
Style::default().fg(Color::Green),
|
||||||
|
Style::default().fg(Color::Blue),
|
||||||
|
Style::default().fg(Color::Cyan),
|
||||||
|
Style::default().fg(Color::Magenta),
|
||||||
|
]
|
||||||
|
}
|
||||||
impl Theme {
|
impl Theme {
|
||||||
/// To allow `Highlight` to represent arbitrary RGB colors without turning it into an enum,
|
/// To allow `Highlight` to represent arbitrary RGB colors without turning it into an enum,
|
||||||
/// we interpret the last 256^3 numbers as RGB.
|
/// we interpret the last 256^3 numbers as RGB.
|
||||||
|
@ -382,6 +422,10 @@ impl Theme {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rainbow_length(&self) -> usize {
|
||||||
|
self.rainbow_length
|
||||||
|
}
|
||||||
|
|
||||||
fn from_toml(value: Value) -> (Self, Vec<String>) {
|
fn from_toml(value: Value) -> (Self, Vec<String>) {
|
||||||
if let Value::Table(table) = value {
|
if let Value::Table(table) = value {
|
||||||
Theme::from_keys(table)
|
Theme::from_keys(table)
|
||||||
|
@ -392,12 +436,14 @@ impl Theme {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_keys(toml_keys: Map<String, Value>) -> (Self, Vec<String>) {
|
fn from_keys(toml_keys: Map<String, Value>) -> (Self, Vec<String>) {
|
||||||
let (styles, scopes, highlights, load_errors) = build_theme_values(toml_keys);
|
let (styles, scopes, highlights, rainbow_length, load_errors) =
|
||||||
|
build_theme_values(toml_keys);
|
||||||
|
|
||||||
let theme = Self {
|
let theme = Self {
|
||||||
styles,
|
styles,
|
||||||
scopes,
|
scopes,
|
||||||
highlights,
|
highlights,
|
||||||
|
rainbow_length,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
(theme, load_errors)
|
(theme, load_errors)
|
||||||
|
@ -541,6 +587,21 @@ impl ThemePalette {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_style_array(&self, value: Value) -> Result<Vec<Style>, String> {
|
||||||
|
let mut styles = Vec::new();
|
||||||
|
|
||||||
|
for v in value
|
||||||
|
.as_array()
|
||||||
|
.ok_or_else(|| format!("Could not parse value as an array: '{value}'"))?
|
||||||
|
{
|
||||||
|
let mut style = Style::default();
|
||||||
|
self.parse_style(&mut style, v.clone())?;
|
||||||
|
styles.push(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(styles)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Value> for ThemePalette {
|
impl TryFrom<Value> for ThemePalette {
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
[
|
||||||
|
(function_definition)
|
||||||
|
(compound_statement)
|
||||||
|
(subshell)
|
||||||
|
(test_command)
|
||||||
|
(subscript)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(array)
|
||||||
|
(expansion)
|
||||||
|
(command_substitution)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"((" "))"
|
||||||
|
"${" "$("
|
||||||
|
"{" "}"
|
||||||
|
"[" "]"
|
||||||
|
"[[" "]]"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,29 @@
|
||||||
|
[
|
||||||
|
(preproc_params)
|
||||||
|
(preproc_defined)
|
||||||
|
(argument_list)
|
||||||
|
(attribute_specifier)
|
||||||
|
(ms_declspec_modifier)
|
||||||
|
(declaration_list)
|
||||||
|
(parenthesized_declarator)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(abstract_parenthesized_declarator)
|
||||||
|
(array_declarator)
|
||||||
|
(compound_statement)
|
||||||
|
(initializer_list)
|
||||||
|
(compound_literal_expression)
|
||||||
|
(enumerator_list)
|
||||||
|
(field_declaration_list)
|
||||||
|
(parameter_list)
|
||||||
|
(for_statement)
|
||||||
|
(macro_type_specifier)
|
||||||
|
(subscript_expression)
|
||||||
|
(subscript_designator)
|
||||||
|
(cast_expression)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"{" "}"
|
||||||
|
"[" "]"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,13 @@
|
||||||
|
[
|
||||||
|
(list_lit)
|
||||||
|
(map_lit)
|
||||||
|
(vec_lit)
|
||||||
|
(anon_fn_lit)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"#"
|
||||||
|
"{" "}"
|
||||||
|
"[" "]"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1 @@
|
||||||
|
; inherits: scheme
|
|
@ -0,0 +1,49 @@
|
||||||
|
[
|
||||||
|
; c
|
||||||
|
(preproc_params)
|
||||||
|
(preproc_defined)
|
||||||
|
(argument_list)
|
||||||
|
(attribute_specifier)
|
||||||
|
(ms_declspec_modifier)
|
||||||
|
(declaration_list)
|
||||||
|
(parenthesized_declarator)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(abstract_parenthesized_declarator)
|
||||||
|
(array_declarator)
|
||||||
|
(compound_statement)
|
||||||
|
(initializer_list)
|
||||||
|
(compound_literal_expression)
|
||||||
|
(enumerator_list)
|
||||||
|
(field_declaration_list)
|
||||||
|
(parameter_list)
|
||||||
|
(for_statement)
|
||||||
|
; (macro_type_specifier) - not part of cpp
|
||||||
|
(subscript_expression)
|
||||||
|
(subscript_designator)
|
||||||
|
(cast_expression)
|
||||||
|
|
||||||
|
; cpp
|
||||||
|
(decltype)
|
||||||
|
(explicit_function_specifier)
|
||||||
|
(template_parameter_list)
|
||||||
|
(template_argument_list)
|
||||||
|
(parameter_list)
|
||||||
|
(argument_list)
|
||||||
|
(structured_binding_declarator)
|
||||||
|
(noexcept)
|
||||||
|
(throw_specifier)
|
||||||
|
(static_assert_declaration)
|
||||||
|
(condition_clause)
|
||||||
|
(for_range_loop)
|
||||||
|
(new_declarator)
|
||||||
|
(delete_expression "[" "]")
|
||||||
|
(lambda_capture_specifier)
|
||||||
|
(sizeof_expression)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"{" "}"
|
||||||
|
"[" "]"
|
||||||
|
"<" ">"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,15 @@
|
||||||
|
[
|
||||||
|
(keyframe_block_list)
|
||||||
|
(block)
|
||||||
|
(attribute_selector)
|
||||||
|
(feature_query)
|
||||||
|
(parenthesized_query)
|
||||||
|
(selector_query)
|
||||||
|
(parenthesized_value)
|
||||||
|
(arguments)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"{" "}"
|
||||||
|
"(" ")"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,28 @@
|
||||||
|
[
|
||||||
|
(export_clause)
|
||||||
|
(named_imports)
|
||||||
|
(statement_block)
|
||||||
|
(for_statement)
|
||||||
|
(for_in_statement)
|
||||||
|
(switch_body)
|
||||||
|
(catch_clause "(" ")")
|
||||||
|
(parenthesized_expression)
|
||||||
|
(object)
|
||||||
|
(object_pattern)
|
||||||
|
(array)
|
||||||
|
(array_pattern)
|
||||||
|
(subscript_expression)
|
||||||
|
(template_substitution)
|
||||||
|
(arguments)
|
||||||
|
(class_body)
|
||||||
|
(formal_parameters)
|
||||||
|
(computed_property_name)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"${" "{" "}"
|
||||||
|
"[" "]"
|
||||||
|
] @rainbow.bracket
|
||||||
|
|
||||||
|
(regex "/" @rainbow.bracket) @rainbow.scope
|
|
@ -0,0 +1,24 @@
|
||||||
|
[
|
||||||
|
(block)
|
||||||
|
(interpolation)
|
||||||
|
(list)
|
||||||
|
(tuple)
|
||||||
|
(bitstring)
|
||||||
|
(map)
|
||||||
|
; short-hand function captures like &(&1 + &2)
|
||||||
|
(unary_operator
|
||||||
|
operator: "&")
|
||||||
|
(arguments "(" ")")
|
||||||
|
(access_call)
|
||||||
|
(sigil)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"%"
|
||||||
|
"{" "}"
|
||||||
|
"[" "]"
|
||||||
|
"<<" ">>"
|
||||||
|
"#{"
|
||||||
|
"|"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,24 @@
|
||||||
|
[
|
||||||
|
; ()
|
||||||
|
(arguments "(" ")")
|
||||||
|
(parenthesized_expression)
|
||||||
|
(function_type)
|
||||||
|
; #{}
|
||||||
|
(record)
|
||||||
|
(map)
|
||||||
|
; {}
|
||||||
|
(map_update)
|
||||||
|
(tuple)
|
||||||
|
; <<>>
|
||||||
|
(bitstring)
|
||||||
|
; []
|
||||||
|
(list)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"#"
|
||||||
|
"{" "}"
|
||||||
|
"(" ")"
|
||||||
|
"[" "]"
|
||||||
|
"<<" ">>"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,32 @@
|
||||||
|
[
|
||||||
|
(target_group)
|
||||||
|
(unqualified_imports)
|
||||||
|
(tuple)
|
||||||
|
(list)
|
||||||
|
(function)
|
||||||
|
(function_parameters)
|
||||||
|
(todo)
|
||||||
|
(tuple)
|
||||||
|
(list)
|
||||||
|
(anonymous_function)
|
||||||
|
(block)
|
||||||
|
(case)
|
||||||
|
(record_update)
|
||||||
|
(arguments)
|
||||||
|
(record_pattern_arguments)
|
||||||
|
(tuple_pattern)
|
||||||
|
(list_pattern)
|
||||||
|
(type_definition)
|
||||||
|
(data_constructor_arguments)
|
||||||
|
(tuple_type)
|
||||||
|
(function_parameter_types)
|
||||||
|
(type_arguments)
|
||||||
|
(type_parameters)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
"#"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,33 @@
|
||||||
|
[
|
||||||
|
(import_spec_list)
|
||||||
|
(const_declaration)
|
||||||
|
(var_declaration)
|
||||||
|
(type_parameter_list)
|
||||||
|
(parameter_list)
|
||||||
|
(type_declaration)
|
||||||
|
(parenthesized_type)
|
||||||
|
(type_arguments)
|
||||||
|
(array_type)
|
||||||
|
(implicit_length_array_type)
|
||||||
|
(slice_type)
|
||||||
|
(field_declaration_list)
|
||||||
|
(interface_type)
|
||||||
|
(map_type)
|
||||||
|
(block)
|
||||||
|
(expression_switch_statement)
|
||||||
|
(type_switch_statement)
|
||||||
|
(select_statement)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(argument_list)
|
||||||
|
(index_expression)
|
||||||
|
(slice_expression)
|
||||||
|
(type_assertion_expression)
|
||||||
|
(type_conversion_expression)
|
||||||
|
(literal_value)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,13 @@
|
||||||
|
[
|
||||||
|
(doctype)
|
||||||
|
(erroneous_end_tag)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
([
|
||||||
|
(element)
|
||||||
|
(script_element)
|
||||||
|
(style_element)
|
||||||
|
] @rainbow.scope
|
||||||
|
(#set! rainbow.include-children))
|
||||||
|
|
||||||
|
["<" ">" "<!" "</" "/>"] @rainbow.bracket
|
|
@ -0,0 +1,35 @@
|
||||||
|
[
|
||||||
|
(cast_expression)
|
||||||
|
(inferred_parameters)
|
||||||
|
(dimensions_expr)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(array_access)
|
||||||
|
(argument_list)
|
||||||
|
(type_arguments)
|
||||||
|
(dimensions)
|
||||||
|
(block)
|
||||||
|
(switch_block)
|
||||||
|
(catch_clause)
|
||||||
|
(resource_specification)
|
||||||
|
(for_statement)
|
||||||
|
(enhanced_for_statement)
|
||||||
|
(annotation_argument_list)
|
||||||
|
(element_value_array_initializer)
|
||||||
|
(module_body)
|
||||||
|
(enum_body)
|
||||||
|
(type_parameters)
|
||||||
|
(class_body)
|
||||||
|
(constructor_body)
|
||||||
|
(annotation_type_body)
|
||||||
|
(annotation_type_element_declaration)
|
||||||
|
(interface_body)
|
||||||
|
(array_initializer)
|
||||||
|
(formal_parameters)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"{" "}"
|
||||||
|
"[" "]"
|
||||||
|
"<" ">"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1 @@
|
||||||
|
; inherits: ecma
|
|
@ -0,0 +1,9 @@
|
||||||
|
[
|
||||||
|
(object)
|
||||||
|
(array)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,9 @@
|
||||||
|
; inherits: ecma
|
||||||
|
|
||||||
|
[
|
||||||
|
(jsx_expression)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
(jsx_opening_element ["<" ">"] @rainbow.bracket) @rainbow.scope
|
||||||
|
(jsx_closing_element ["</" ">"] @rainbow.bracket) @rainbow.scope
|
||||||
|
(jsx_self_closing_element ["<" "/>"] @rainbow.bracket) @rainbow.scope
|
|
@ -0,0 +1,17 @@
|
||||||
|
[
|
||||||
|
(formals)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(attrset_expression)
|
||||||
|
(let_attrset_expression)
|
||||||
|
(rec_attrset_expression)
|
||||||
|
(inherit_from)
|
||||||
|
(interpolation)
|
||||||
|
(list_expression)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"${"
|
||||||
|
"{" "}"
|
||||||
|
"(" ")"
|
||||||
|
"[" "]"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,30 @@
|
||||||
|
[
|
||||||
|
(future_import_statement)
|
||||||
|
(import_from_statement)
|
||||||
|
(with_clause)
|
||||||
|
(parameters)
|
||||||
|
(parenthesized_list_splat)
|
||||||
|
(argument_list)
|
||||||
|
(tuple_pattern)
|
||||||
|
(list_pattern)
|
||||||
|
(subscript)
|
||||||
|
(list)
|
||||||
|
(set)
|
||||||
|
(tuple)
|
||||||
|
(dictionary)
|
||||||
|
(dictionary_comprehension)
|
||||||
|
(set_comprehension)
|
||||||
|
(list_comprehension)
|
||||||
|
(generator_expression)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(interpolation)
|
||||||
|
(format_expression)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(" ")"
|
||||||
|
"{" "}"
|
||||||
|
"[" "]"
|
||||||
|
] @rainbow.bracket
|
||||||
|
|
||||||
|
; (string ["{{" "}}"] @rainbow.bracket) @rainbow.scope
|
|
@ -0,0 +1 @@
|
||||||
|
; inherits: scheme
|
|
@ -0,0 +1,17 @@
|
||||||
|
[
|
||||||
|
(lookahead_assertion)
|
||||||
|
(character_class)
|
||||||
|
(anonymous_capturing_group)
|
||||||
|
(named_capturing_group)
|
||||||
|
(non_capturing_group)
|
||||||
|
(count_quantifier)
|
||||||
|
(character_class_escape)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"(?" "(?:"
|
||||||
|
"(?<" ">"
|
||||||
|
"(" ")"
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,28 @@
|
||||||
|
[
|
||||||
|
(begin_block)
|
||||||
|
(end_block)
|
||||||
|
(singleton_method)
|
||||||
|
(block_parameters)
|
||||||
|
(parenthesized_statements)
|
||||||
|
(element_reference)
|
||||||
|
(argument_list "(" ")")
|
||||||
|
(block)
|
||||||
|
(destructured_left_assignment)
|
||||||
|
(interpolation)
|
||||||
|
(string_array)
|
||||||
|
(symbol_array)
|
||||||
|
(regex)
|
||||||
|
(array)
|
||||||
|
(hash)
|
||||||
|
(method_parameters)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"#{"
|
||||||
|
"{" "}"
|
||||||
|
"(" ")"
|
||||||
|
"%w(" "%i("
|
||||||
|
"[" "]"
|
||||||
|
"|"
|
||||||
|
"/"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,60 @@
|
||||||
|
[
|
||||||
|
; {/}
|
||||||
|
(declaration_list)
|
||||||
|
(field_declaration_list)
|
||||||
|
(field_initializer_list)
|
||||||
|
(enum_variant_list)
|
||||||
|
(block)
|
||||||
|
(match_block)
|
||||||
|
(use_list)
|
||||||
|
(struct_pattern)
|
||||||
|
|
||||||
|
; (/)
|
||||||
|
(ordered_field_declaration_list)
|
||||||
|
(arguments)
|
||||||
|
(parameters)
|
||||||
|
(tuple_type)
|
||||||
|
(tuple_expression)
|
||||||
|
(tuple_pattern)
|
||||||
|
(tuple_struct_pattern)
|
||||||
|
(unit_type)
|
||||||
|
(unit_expression)
|
||||||
|
(visibility_modifier)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(token_repetition_pattern)
|
||||||
|
|
||||||
|
; </>
|
||||||
|
(type_parameters)
|
||||||
|
(type_arguments)
|
||||||
|
(bracketed_type)
|
||||||
|
(for_lifetimes)
|
||||||
|
|
||||||
|
; [/]
|
||||||
|
(array_type)
|
||||||
|
(array_expression)
|
||||||
|
(index_expression)
|
||||||
|
(slice_pattern)
|
||||||
|
|
||||||
|
; attributes #[]
|
||||||
|
(attribute_item)
|
||||||
|
(inner_attribute_item)
|
||||||
|
|
||||||
|
; macros
|
||||||
|
(token_tree_pattern)
|
||||||
|
(macro_definition)
|
||||||
|
|
||||||
|
; closures
|
||||||
|
(closure_parameters)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
; attributes like `#[serde(rename_all = "kebab-case")]`
|
||||||
|
(attribute arguments: (token_tree) @rainbow.scope)
|
||||||
|
|
||||||
|
[
|
||||||
|
"#"
|
||||||
|
"[" "]"
|
||||||
|
"(" ")"
|
||||||
|
"{" "}"
|
||||||
|
"<" ">"
|
||||||
|
"|"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,12 @@
|
||||||
|
[
|
||||||
|
(list)
|
||||||
|
(vector)
|
||||||
|
(byte_vector)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"#(" "#vu8("
|
||||||
|
"(" ")"
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,3 @@
|
||||||
|
; inherits: css
|
||||||
|
|
||||||
|
(parameters) @rainbow.scope
|
|
@ -0,0 +1 @@
|
||||||
|
; inherits: python
|
|
@ -0,0 +1,12 @@
|
||||||
|
[
|
||||||
|
(table_array_element)
|
||||||
|
(table)
|
||||||
|
(array)
|
||||||
|
(inline_table)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"[[" "]]"
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,2 @@
|
||||||
|
; inherits: typescript
|
||||||
|
; inherits: jsx
|
|
@ -0,0 +1,19 @@
|
||||||
|
; inherits: ecma
|
||||||
|
|
||||||
|
[
|
||||||
|
(import_require_clause)
|
||||||
|
(enum_body)
|
||||||
|
(lookup_type)
|
||||||
|
(parenthesized_type)
|
||||||
|
(object_type)
|
||||||
|
(type_parameters)
|
||||||
|
(index_signature)
|
||||||
|
(array_type)
|
||||||
|
(tuple_type)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
(type_arguments ["<" ">"] @rainbow.bracket) @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"{|" "|}"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,29 @@
|
||||||
|
[
|
||||||
|
(processing_instructions)
|
||||||
|
(cdata_sect)
|
||||||
|
(xml_decl)
|
||||||
|
(doctype_decl)
|
||||||
|
(element_decl)
|
||||||
|
(element_choice)
|
||||||
|
(element_seq)
|
||||||
|
(mixed)
|
||||||
|
(attlist_decl)
|
||||||
|
(notation_type)
|
||||||
|
(enumeration)
|
||||||
|
(ge_decl)
|
||||||
|
(pe_decl)
|
||||||
|
(notation_decl)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
((element) @rainbow.scope
|
||||||
|
(#set! rainbow.include-children))
|
||||||
|
|
||||||
|
[
|
||||||
|
"<?" "?>"
|
||||||
|
"<" ">"
|
||||||
|
"</" "/>"
|
||||||
|
"<!"
|
||||||
|
"(" ")"
|
||||||
|
")*"
|
||||||
|
"[" "]"
|
||||||
|
] @rainbow.bracket
|
|
@ -0,0 +1,9 @@
|
||||||
|
[
|
||||||
|
(flow_sequence)
|
||||||
|
(flow_mapping)
|
||||||
|
] @rainbow.scope
|
||||||
|
|
||||||
|
[
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
] @rainbow.bracket
|
|
@ -36,6 +36,7 @@ pub mod tasks {
|
||||||
let grammar = syntax_config.grammar;
|
let grammar = syntax_config.grammar;
|
||||||
LanguageData::compile_indent_query(grammar, config)?;
|
LanguageData::compile_indent_query(grammar, config)?;
|
||||||
LanguageData::compile_textobject_query(grammar, config)?;
|
LanguageData::compile_textobject_query(grammar, config)?;
|
||||||
|
LanguageData::compile_rainbow_query(grammar, config)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Query check succeeded");
|
println!("Query check succeeded");
|
||||||
|
|
Loading…
Reference in New Issue