feat(highlight): migrate to tree-house with Helix queries

Replace tree-sitter-highlight dep with tree-house crate from Helix
editor. Add ropey dependency required by tree-house.

Reorganize query files from Helix's runtime/queries/ for all 14
supported languages:
- bash, c, css, go, html, javascript, json, markdown, nix, python,
  rust, toml, typescript, yaml
- Include ecma, _javascript, _typescript base dirs for JS/TS inheritance
- Copy highlights.scm, injections.scm, locals.scm where available

This commit establishes the foundation; highlight.rs implementation
will follow in subsequent commits.
This commit is contained in:
Timothy DeHerrera
2026-02-04 16:49:04 -07:00
parent 98977136c8
commit 136be19533
43 changed files with 3310 additions and 85 deletions

161
Cargo.lock generated
View File

@@ -56,6 +56,15 @@ version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "arc-swap"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ded5f9a03ac8f24d1b8a25101ee812cd32cdc8c50a4c50237de2c4915850e73"
dependencies = [
"rustversion",
]
[[package]]
name = "arraydeque"
version = "0.5.1"
@@ -409,6 +418,12 @@ version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04"
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "digest"
version = "0.10.7"
@@ -477,6 +492,12 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "funty"
version = "2.0.0"
@@ -499,7 +520,7 @@ version = "0.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df"
dependencies = [
"unicode-width",
"unicode-width 0.2.2",
]
[[package]]
@@ -589,6 +610,17 @@ dependencies = [
"allocator-api2",
]
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
]
[[package]]
name = "hashbrown"
version = "0.16.1"
@@ -731,6 +763,15 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "kstring"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1"
dependencies = [
"static_assertions",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
@@ -743,6 +784,16 @@ version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
[[package]]
name = "libloading"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
dependencies = [
"cfg-if",
"windows-link",
]
[[package]]
name = "libm"
version = "0.2.16"
@@ -1099,6 +1150,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "pretty_assertions"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
dependencies = [
"diff",
"yansi",
]
[[package]]
name = "prettyplease"
version = "0.2.37"
@@ -1269,6 +1330,19 @@ dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-cursor"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0497c781d2f982ae8284d2932aee6a877e58a4541daa5e8fadc18cc75c23a61d"
dependencies = [
"log",
"memchr",
"regex-automata",
"regex-syntax",
"ropey",
]
[[package]]
name = "regex-syntax"
version = "0.8.8"
@@ -1313,6 +1387,16 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "ropey"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93411e420bcd1a75ddd1dc3caf18c23155eda2c090631a85af21ba19e97093b5"
dependencies = [
"smallvec",
"str_indices",
]
[[package]]
name = "rustc-hash"
version = "2.1.1"
@@ -1459,6 +1543,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]]
name = "slab"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "slug"
version = "0.1.6"
@@ -1475,6 +1565,18 @@ version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "str_indices"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6"
[[package]]
name = "streaming-iterator"
version = "0.1.9"
@@ -1517,17 +1619,18 @@ dependencies = [
"lightningcss",
"mermaid-rs-renderer",
"pulldown-cmark",
"ropey",
"serde",
"tempfile",
"tera",
"thiserror 2.0.18",
"toml 0.8.23",
"tree-house",
"tree-sitter",
"tree-sitter-bash",
"tree-sitter-c",
"tree-sitter-css",
"tree-sitter-go",
"tree-sitter-highlight",
"tree-sitter-html",
"tree-sitter-javascript",
"tree-sitter-json",
@@ -1709,6 +1812,36 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
[[package]]
name = "tree-house"
version = "0.3.0"
source = "git+https://github.com/helix-editor/tree-house#f05d27cb52b02209962cc0a2f87de303a2bec870"
dependencies = [
"arc-swap",
"hashbrown 0.15.5",
"kstring",
"once_cell",
"pretty_assertions",
"regex",
"regex-cursor",
"ropey",
"slab",
"tree-house-bindings",
"unicode-width 0.1.12",
]
[[package]]
name = "tree-house-bindings"
version = "0.2.2"
source = "git+https://github.com/helix-editor/tree-house#f05d27cb52b02209962cc0a2f87de303a2bec870"
dependencies = [
"cc",
"libloading",
"regex-cursor",
"ropey",
"thiserror 2.0.18",
]
[[package]]
name = "tree-sitter"
version = "0.26.3"
@@ -1763,18 +1896,6 @@ dependencies = [
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-highlight"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0636662a03005d9289649e0b4a89ff37b75df5033e8d4a16398740ae6496d2"
dependencies = [
"regex",
"streaming-iterator",
"thiserror 2.0.18",
"tree-sitter",
]
[[package]]
name = "tree-sitter-html"
version = "0.23.2"
@@ -1920,6 +2041,12 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unicode-width"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
[[package]]
name = "unicode-width"
version = "0.2.2"
@@ -2130,6 +2257,12 @@ dependencies = [
"hashlink",
]
[[package]]
name = "yansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "zerocopy"
version = "0.8.33"

View File

@@ -12,12 +12,13 @@ thiserror = "2"
walkdir = "2"
# Syntax highlighting
ropey = "1.6"
tree-house = { git = "https://github.com/helix-editor/tree-house", package = "tree-house" }
tree-sitter = "0.26"
tree-sitter-bash = "0.23"
tree-sitter-c = "0.24"
tree-sitter-css = "0.25"
tree-sitter-go = "0.25"
tree-sitter-highlight = "0.26"
tree-sitter-html = "0.23"
tree-sitter-javascript = "0.25"
tree-sitter-json = "0.24"

View File

@@ -0,0 +1,36 @@
; Function and method parameters
;-------------------------------
; Javascript and Typescript Treesitter grammars deviate when defining the
; tree structure for parameters, so we need to address them in each specific
; language instead of ecma.
; (p)
(formal_parameters
(identifier) @variable.parameter)
; (...p)
(formal_parameters
(rest_pattern
(identifier) @variable.parameter))
; ({ p })
(formal_parameters
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter))
; ({ a: p })
(formal_parameters
(object_pattern
(pair_pattern
value: (identifier) @variable.parameter)))
; ([ p ])
(formal_parameters
(array_pattern
(identifier) @variable.parameter))
; (p = 1)
(formal_parameters
(assignment_pattern
left: (identifier) @variable.parameter))

View File

@@ -0,0 +1,14 @@
; Definitions
;------------
; Javascript and Typescript Treesitter grammars deviate when defining the
; tree structure for parameters, so we need to address them in each specific
; language instead of ecma.
; (i)
(formal_parameters
(identifier) @local.definition.variable.parameter)
; (i = 1)
(formal_parameters
(assignment_pattern
left: (identifier) @local.definition.variable.parameter))

View File

@@ -0,0 +1,148 @@
; Namespaces
; ----------
(internal_module
[((identifier) @namespace) ((nested_identifier (identifier) @namespace))])
(ambient_declaration "global" @namespace)
; Parameters
; ----------
; Javascript and Typescript Treesitter grammars deviate when defining the
; tree structure for parameters, so we need to address them in each specific
; language instead of ecma.
; (p: t)
; (p: t = 1)
(required_parameter
(identifier) @variable.parameter)
; (...p: t)
(required_parameter
(rest_pattern
(identifier) @variable.parameter))
; ({ p }: { p: t })
(required_parameter
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter))
; ({ a: p }: { a: t })
(required_parameter
(object_pattern
(pair_pattern
value: (identifier) @variable.parameter)))
; ([ p ]: t[])
(required_parameter
(array_pattern
(identifier) @variable.parameter))
; (p?: t)
; (p?: t = 1) // Invalid but still possible to highlight.
(optional_parameter
(identifier) @variable.parameter)
; (...p?: t) // Invalid but still possible to highlight.
(optional_parameter
(rest_pattern
(identifier) @variable.parameter))
; ({ p }: { p?: t})
(optional_parameter
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter))
; ({ a: p }: { a?: t })
(optional_parameter
(object_pattern
(pair_pattern
value: (identifier) @variable.parameter)))
; ([ p ]?: t[]) // Invalid but still possible to highlight.
(optional_parameter
(array_pattern
(identifier) @variable.parameter))
(public_field_definition) @punctuation.special
(this_type) @variable.builtin
(type_predicate) @keyword.operator
; Punctuation
; -----------
[
":"
] @punctuation.delimiter
(optional_parameter "?" @punctuation.special)
(property_signature "?" @punctuation.special)
(conditional_type ["?" ":"] @operator)
(ternary_expression ["?" ":"] @operator)
; Keywords
; --------
[
"abstract"
"declare"
"module"
"export"
"infer"
"implements"
"keyof"
"namespace"
"override"
"satisfies"
] @keyword
[
"type"
"interface"
"enum"
] @keyword.storage.type
[
"public"
"private"
"protected"
"readonly"
] @keyword.storage.modifier
; Types
; -----
(type_identifier) @type
(type_parameter
name: (type_identifier) @type.parameter)
(predefined_type) @type.builtin
; Type arguments and parameters
; -----------------------------
(type_arguments
[
"<"
">"
] @punctuation.bracket)
(type_parameters
[
"<"
">"
] @punctuation.bracket)
(omitting_type_annotation) @punctuation.special
(opting_type_annotation) @punctuation.special
; Literals
; --------
[
(template_literal_type)
] @string
(import_require_clause
(identifier) "="
("require") @keyword)

View File

@@ -0,0 +1,34 @@
; Scopes
;-------
[
(type_alias_declaration)
(class_declaration)
(interface_declaration)
] @local.scope
; Definitions
;------------
(type_parameter
name: (type_identifier) @local.definition.type.parameter)
; Javascript and Typescript Treesitter grammars deviate when defining the
; tree structure for parameters, so we need to address them in each specific
; language instead of ecma.
; (i: t)
; (i: t = 1)
(required_parameter
(identifier) @local.definition.variable.parameter)
; (i?: t)
; (i?: t = 1) // Invalid but still possible to highlight.
(optional_parameter
(identifier) @local.definition.variable.parameter)
; References
;-----------
(type_identifier) @local.reference
(identifier) @local.reference

250
queries/bash/highlights.scm Normal file
View File

@@ -0,0 +1,250 @@
[
"("
")"
"{"
"}"
"["
"]"
"[["
"]]"
"(("
"))"
] @punctuation.bracket
[
";"
";;"
";&"
";;&"
"&"
] @punctuation.delimiter
[
">"
">>"
"<"
"<<"
"&&"
"|"
"|&"
"||"
"="
"+="
"=~"
"=="
"!="
"&>"
"&>>"
"<&"
">&"
">|"
"<&-"
">&-"
"<<-"
"<<<"
".."
"!"
] @operator
[
(string)
(raw_string)
(ansi_c_string)
(heredoc_body)
] @string
[
(heredoc_start)
(heredoc_end)
] @label
(variable_assignment
(word) @string)
(command
argument: "$" @string) ; bare dollar
(concatenation
(word) @string)
[
"if"
"then"
"else"
"elif"
"fi"
"case"
"in"
"esac"
] @keyword.control.conditional
[
"for"
"do"
"done"
"select"
"until"
"while"
] @keyword.control.repeat
[
"declare"
"typeset"
"readonly"
"local"
"unset"
"unsetenv"
] @keyword
"export" @keyword.control.import
"function" @keyword.function
(special_variable_name) @constant
; trap -l
((word) @constant.builtin
(#any-of? @constant.builtin
"SIGHUP" "SIGINT" "SIGQUIT" "SIGILL" "SIGTRAP" "SIGABRT" "SIGBUS" "SIGFPE" "SIGKILL" "SIGUSR1"
"SIGSEGV" "SIGUSR2" "SIGPIPE" "SIGALRM" "SIGTERM" "SIGSTKFLT" "SIGCHLD" "SIGCONT" "SIGSTOP"
"SIGTSTP" "SIGTTIN" "SIGTTOU" "SIGURG" "SIGXCPU" "SIGXFSZ" "SIGVTALRM" "SIGPROF" "SIGWINCH"
"SIGIO" "SIGPWR" "SIGSYS" "SIGRTMIN" "SIGRTMIN+1" "SIGRTMIN+2" "SIGRTMIN+3" "SIGRTMIN+4"
"SIGRTMIN+5" "SIGRTMIN+6" "SIGRTMIN+7" "SIGRTMIN+8" "SIGRTMIN+9" "SIGRTMIN+10" "SIGRTMIN+11"
"SIGRTMIN+12" "SIGRTMIN+13" "SIGRTMIN+14" "SIGRTMIN+15" "SIGRTMAX-14" "SIGRTMAX-13"
"SIGRTMAX-12" "SIGRTMAX-11" "SIGRTMAX-10" "SIGRTMAX-9" "SIGRTMAX-8" "SIGRTMAX-7" "SIGRTMAX-6"
"SIGRTMAX-5" "SIGRTMAX-4" "SIGRTMAX-3" "SIGRTMAX-2" "SIGRTMAX-1" "SIGRTMAX"))
((word) @constant.builtin.boolean
(#any-of? @constant.builtin.boolean "true" "false"))
(comment) @comment
(test_operator) @operator
(command_substitution
"$(" @punctuation.special
")" @punctuation.special)
(process_substitution
[
"<("
">("
] @punctuation.special
")" @punctuation.special)
(arithmetic_expansion
[
"$(("
"(("
] @punctuation.special
"))" @punctuation.special)
(arithmetic_expansion
"," @punctuation.delimiter)
(ternary_expression
[
"?"
":"
] @keyword.control.conditional)
(binary_expression
operator: _ @operator)
(unary_expression
operator: _ @operator)
(postfix_expression
operator: _ @operator)
(function_definition
name: (word) @function)
(command_name
(word) @function)
(command_name
(word) @function.builtin
(#any-of? @function.builtin
"." ":" "alias" "bg" "bind" "break" "builtin" "caller" "cd" "command" "compgen" "complete"
"compopt" "continue" "coproc" "dirs" "disown" "echo" "enable" "eval" "exec" "exit" "false" "fc"
"fg" "getopts" "hash" "help" "history" "jobs" "kill" "let" "logout" "mapfile" "popd" "printf"
"pushd" "pwd" "read" "readarray" "return" "set" "shift" "shopt" "source" "suspend" "test" "time"
"times" "trap" "true" "type" "typeset" "ulimit" "umask" "unalias" "wait"))
(command
argument: [
(word) @variable.parameter
(concatenation
(word) @variable.parameter)
])
(declaration_command
(word) @variable.parameter)
(unset_command
(word) @variable.parameter)
(number) @constant.numeric
(file_redirect
(word) @string.special.path)
(herestring_redirect
(word) @string)
(file_descriptor) @operator
(simple_expansion
"$" @punctuation.special) @none
(expansion
"${" @punctuation.special
"}" @punctuation.special) @none
(expansion
operator: _ @punctuation.special)
(expansion
"@"
.
operator: _ @constant.character)
((expansion
(subscript
index: (word) @constant.character))
(#any-of? @constant.character "@" "*"))
"``" @punctuation.special
(variable_name) @variable
((variable_name) @constant
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
((variable_name) @variable.builtin
(#any-of? @variable.builtin
; https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Variables.html
"CDPATH" "HOME" "IFS" "MAIL" "MAILPATH" "OPTARG" "OPTIND" "PATH" "PS1" "PS2"
; https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html
"_" "BASH" "BASHOPTS" "BASHPID" "BASH_ALIASES" "BASH_ARGC" "BASH_ARGV" "BASH_ARGV0" "BASH_CMDS"
"BASH_COMMAND" "BASH_COMPAT" "BASH_ENV" "BASH_EXECUTION_STRING" "BASH_LINENO"
"BASH_LOADABLES_PATH" "BASH_REMATCH" "BASH_SOURCE" "BASH_SUBSHELL" "BASH_VERSINFO"
"BASH_VERSION" "BASH_XTRACEFD" "CHILD_MAX" "COLUMNS" "COMP_CWORD" "COMP_LINE" "COMP_POINT"
"COMP_TYPE" "COMP_KEY" "COMP_WORDBREAKS" "COMP_WORDS" "COMPREPLY" "COPROC" "DIRSTACK" "EMACS"
"ENV" "EPOCHREALTIME" "EPOCHSECONDS" "EUID" "EXECIGNORE" "FCEDIT" "FIGNORE" "FUNCNAME"
"FUNCNEST" "GLOBIGNORE" "GROUPS" "histchars" "HISTCMD" "HISTCONTROL" "HISTFILE" "HISTFILESIZE"
"HISTIGNORE" "HISTSIZE" "HISTTIMEFORMAT" "HOSTFILE" "HOSTNAME" "HOSTTYPE" "IGNOREEOF" "INPUTRC"
"INSIDE_EMACS" "LANG" "LC_ALL" "LC_COLLATE" "LC_CTYPE" "LC_MESSAGES" "LC_NUMERIC" "LC_TIME"
"LINENO" "LINES" "MACHTYPE" "MAILCHECK" "MAPFILE" "OLDPWD" "OPTERR" "OSTYPE" "PIPESTATUS"
"POSIXLY_CORRECT" "PPID" "PROMPT_COMMAND" "PROMPT_DIRTRIM" "PS0" "PS3" "PS4" "PWD" "RANDOM"
"READLINE_ARGUMENT" "READLINE_LINE" "READLINE_MARK" "READLINE_POINT" "REPLY" "SECONDS" "SHELL"
"SHELLOPTS" "SHLVL" "SRANDOM" "TIMEFORMAT" "TMOUT" "TMPDIR" "UID"))
(case_item
value: (word) @variable.parameter)
[
(regex)
(extglob_pattern)
] @string.regexp

View File

@@ -0,0 +1,38 @@
((comment) @injection.content
(#set! injection.language "comment"))
(command
name: (command_name (word) @_command)
argument: (raw_string) @injection.content
(#match? @_command "^[gnm]?awk$")
(#set! injection.language "awk"))
((regex) @injection.content
(#set! injection.language "regex"))
(command
name: (command_name (word) @_command (#any-of? @_command "jq" "jaq"))
argument: [
(raw_string) @injection.content
(string (string_content) @injection.content)
]
(#set! injection.language "jq"))
(command
name: (command_name (word) @_command (#eq? @_command "alias"))
argument: (concatenation
(word)
[
(raw_string) @injection.content
(string (string_content) @injection.content)
])
(#set! injection.language "bash"))
(command
name: (command_name (word) @_command (#any-of? @_command "eval" "trap"))
.
argument: [
(raw_string) @injection.content
(string (string_content) @injection.content)
]
(#set! injection.language "bash"))

167
queries/c/highlights.scm Normal file
View File

@@ -0,0 +1,167 @@
(identifier) @variable
((identifier) @constant
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
"sizeof" @keyword
[
"enum"
"struct"
"typedef"
"union"
] @keyword.storage.type
[
(type_qualifier)
(storage_class_specifier)
] @keyword.storage.modifier
[
"goto"
"break"
"continue"
] @keyword.control
[
"do"
"for"
"while"
] @keyword.control.repeat
[
"if"
"else"
"switch"
"case"
"default"
] @keyword.control.conditional
"return" @keyword.control.return
[
"defined"
"#define"
"#elif"
"#else"
"#endif"
"#if"
"#ifdef"
"#ifndef"
"#include"
(preproc_directive)
] @keyword.directive
"..." @punctuation
["," "." ":" "::" ";" "->"] @punctuation.delimiter
["(" ")" "[" "]" "{" "}" "[[" "]]"] @punctuation.bracket
[
"+"
"-"
"*"
"/"
"++"
"--"
"%"
"=="
"!="
">"
"<"
">="
"<="
"&&"
"||"
"!"
"&"
"|"
"^"
"~"
"<<"
">>"
"="
"+="
"-="
"*="
"/="
"%="
"<<="
">>="
"&="
"^="
"|="
"?"
] @operator
(conditional_expression ":" @operator) ; After punctuation
(pointer_declarator "*" @type.builtin) ; After Operators
(abstract_pointer_declarator "*" @type.builtin)
[(true) (false)] @constant.builtin.boolean
(enumerator name: (identifier) @type.enum.variant)
(string_literal) @string
(system_lib_string) @string
(null) @constant
(number_literal) @constant.numeric
(char_literal) @constant.character
(escape_sequence) @constant.character.escape
(field_identifier) @variable.other.member
(statement_identifier) @label
(type_identifier) @type
(primitive_type) @type.builtin
(sized_type_specifier) @type.builtin
(call_expression
function: (identifier) @function)
(call_expression
function: (field_expression
field: (field_identifier) @function))
(call_expression (argument_list (identifier) @variable))
(function_declarator
declarator: [(identifier) (field_identifier)] @function)
; Up to 6 layers of declarators
(parameter_declaration
declarator: (identifier) @variable.parameter)
(parameter_declaration
(_
(identifier) @variable.parameter))
(parameter_declaration
(_
(_
(identifier) @variable.parameter)))
(parameter_declaration
(_
(_
(_
(identifier) @variable.parameter))))
(parameter_declaration
(_
(_
(_
(_
(identifier) @variable.parameter)))))
(parameter_declaration
(_
(_
(_
(_
(_
(identifier) @variable.parameter))))))
(preproc_function_def
name: (identifier) @function.special)
(attribute
name: (identifier) @attribute)
(comment) @comment

2
queries/c/injections.scm Normal file
View File

@@ -0,0 +1,2 @@
((comment) @injection.content
(#set! injection.language "comment"))

38
queries/c/locals.scm Normal file
View File

@@ -0,0 +1,38 @@
;; Scopes
(function_definition) @local.scope
;; Definitions
; Parameters
; Up to 6 layers of declarators
(parameter_declaration
(identifier) @local.definition.variable.parameter)
(parameter_declaration
(_
(identifier) @local.definition.variable.parameter))
(parameter_declaration
(_
(_
(identifier) @local.definition.variable.parameter)))
(parameter_declaration
(_
(_
(_
(identifier) @local.definition.variable.parameter))))
(parameter_declaration
(_
(_
(_
(_
(identifier) @local.definition.variable.parameter)))))
(parameter_declaration
(_
(_
(_
(_
(_
(identifier) @local.definition.variable.parameter))))))
;; References
(identifier) @local.reference

View File

@@ -0,0 +1,99 @@
(comment) @comment
[
(tag_name)
(nesting_selector)
(universal_selector)
] @tag
[
"~"
">"
"+"
"-"
"*"
"/"
"="
"^="
"|="
"~="
"$="
"*="
] @operator
[
"and"
"not"
"only"
"or"
] @keyword.operator
(attribute_selector (plain_value) @string)
(property_name) @variable.other.member
(plain_value) @constant
((property_name) @variable
(#match? @variable "^--"))
((plain_value) @variable
(#match? @variable "^--"))
(class_name) @label
(feature_name) @variable.other.member
(function_name) @function
(id_name) @label
(namespace_name) @namespace
(attribute_name) @attribute
(pseudo_element_selector (tag_name) @attribute)
(pseudo_class_selector (class_name) @attribute)
[
"@charset"
"@import"
"@keyframes"
"@media"
"@namespace"
"@supports"
(at_keyword)
(from)
(important)
(to)
(keyword_query)
(keyframes_name)
(unit)
] @keyword
; @apply something;
(at_rule
. (at_keyword) @keyword
. (keyword_query) @constant
(#eq? @keyword "@apply"))
[
"#"
"."
] @punctuation
(string_value) @string
(color_value "#" @string.special)
(color_value) @string.special
(integer_value) @constant.numeric.integer
(float_value) @constant.numeric.float
[
")"
"("
"["
"]"
"{"
"}"
] @punctuation.bracket
[
","
";"
":"
"::"
] @punctuation.delimiter

View File

@@ -0,0 +1,2 @@
((comment) @injection.content
(#set! injection.language "comment"))

288
queries/ecma/highlights.scm Normal file
View File

@@ -0,0 +1,288 @@
; Tokens
;-------
[
";"
(optional_chain) ; ?.
"."
","
] @punctuation.delimiter
[
"-"
"--"
"-="
"+"
"++"
"+="
"*"
"*="
"**"
"**="
"/"
"/="
"%"
"%="
"<"
"<="
"<<"
"<<="
"="
"=="
"==="
"!"
"!="
"!=="
"=>"
">"
">="
">>"
">>="
">>>"
">>>="
"~"
"^"
"&"
"|"
"^="
"&="
"|="
"&&"
"||"
"??"
"&&="
"||="
"??="
"..."
] @operator
(ternary_expression ["?" ":"] @operator)
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
(template_substitution
"${" @punctuation.special
"}" @punctuation.special) @embedded
[
"async"
"debugger"
"extends"
"from"
"get"
"new"
"set"
"target"
"with"
] @keyword
[
"of"
"as"
"in"
"delete"
"typeof"
"instanceof"
"void"
] @keyword.operator
[
"function"
] @keyword.function
[
"class"
"let"
"var"
] @keyword.storage.type
[
"const"
"static"
] @keyword.storage.modifier
[
"default"
"yield"
"finally"
"do"
"await"
] @keyword.control
[
"if"
"else"
"switch"
"case"
] @keyword.control.conditional
[
"while"
"for"
] @keyword.control.repeat
[
"import"
"export"
] @keyword.control.import
[
"return"
"break"
"continue"
] @keyword.control.return
[
"throw"
"try"
"catch"
] @keyword.control.exception
; Variables
;----------
(identifier) @variable
; Properties
;-----------
(property_identifier) @variable.other.member
(private_property_identifier) @variable.other.member.private
(shorthand_property_identifier) @variable.other.member
(shorthand_property_identifier_pattern) @variable.other.member
; Function and method definitions
;--------------------------------
(function_expression
name: (identifier) @function)
(function_declaration
name: (identifier) @function)
(method_definition
name: (property_identifier) @function.method)
(method_definition
name: (private_property_identifier) @function.method.private)
(pair
key: (property_identifier) @function.method
value: [(function_expression) (arrow_function)])
(pair
key: (private_property_identifier) @function.method.private
value: [(function_expression) (arrow_function)])
(assignment_expression
left: (member_expression
property: (property_identifier) @function.method)
right: [(function_expression) (arrow_function)])
(assignment_expression
left: (member_expression
property: (private_property_identifier) @function.method.private)
right: [(function_expression) (arrow_function)])
(variable_declarator
name: (identifier) @function
value: [(function_expression) (arrow_function)])
(assignment_expression
left: (identifier) @function
right: [(function_expression) (arrow_function)])
; Function and method parameters
;-------------------------------
; Arrow function parameters in the form `p => ...` are supported by both
; javascript and typescript grammars without conflicts.
(arrow_function
parameter: (identifier) @variable.parameter)
; Function and method calls
;--------------------------
(call_expression
function: (identifier) @function)
(call_expression
function: (member_expression
property: (property_identifier) @function.method))
(call_expression
function: (member_expression
property: (private_property_identifier) @function.method.private))
; Literals
;---------
(this) @variable.builtin
(super) @variable.builtin
[
(null)
(undefined)
] @constant.builtin
[
(true)
(false)
] @constant.builtin.boolean
(comment) @comment
[
(string)
(template_string)
] @string
(escape_sequence) @constant.character.escape
(regex) @string.regexp
(number) @constant.numeric.integer
; Special identifiers
;--------------------
((identifier) @constructor
(#match? @constructor "^[A-Z]"))
([
(identifier)
(shorthand_property_identifier)
(shorthand_property_identifier_pattern)
] @constant
(#match? @constant "^[A-Z_][A-Z\\d_]+$"))
((identifier) @variable.builtin
(#match? @variable.builtin "^(arguments|module|console|window|document)$")
(#is-not? local))
(call_expression
(identifier) @function.builtin
(#any-of? @function.builtin
"eval"
"fetch"
"isFinite"
"isNaN"
"parseFloat"
"parseInt"
"decodeURI"
"decodeURIComponent"
"encodeURI"
"encodeURIComponent"
"require"
"alert"
"prompt"
"btoa"
"atob"
"confirm"
"structuredClone"
"setTimeout"
"clearTimeout"
"setInterval"
"clearInterval"
"queueMicrotask")
(#is-not? local))

100
queries/ecma/injections.scm Normal file
View File

@@ -0,0 +1,100 @@
; Parse the contents of tagged template literals using
; a language inferred from the tag.
(call_expression
function: [
(identifier) @injection.language
(member_expression
property: (property_identifier) @injection.language)
]
arguments: (template_string) @injection.content
(#any-of? @injection.language "html" "css" "json" "sql" "js" "ts" "bash"))
; Parse the contents of $ template literals as shell commands
(call_expression
function: [
(identifier) @_template_function_name
(member_expression
property: (property_identifier) @_template_function_name)
]
arguments: (template_string) @injection.content
(#eq? @_template_function_name "$")
(#set! injection.language "bash"))
; GraphQL detection generally matches the rules provided by the 'GraphQL: Syntax Highlighting'
; VSCode extension: https://github.com/graphql/graphiql/blob/8f25b38f4ab14dc99c046109f255fb283bccde52/packages/vscode-graphql-syntax/grammars/graphql.js.json
; Parse the contents of 'gql' and 'graphql' template literals and function calls
(
(call_expression
function: (identifier) @_template_function_name
arguments: [
; Tagged template literal: NAME``
(template_string (string_fragment) @injection.content)
(
arguments . [
; Function call containing a string literal: NAME('')
(string (string_fragment) @injection.content)
; Function call containing a template literal: NAME(``)
(template_string (string_fragment) @injection.content)
]
)
]
)
(#any-of? @_template_function_name "gql" "graphql")
(#set! injection.language "graphql")
)
; Parse the contents of strings and tagged template literals that begin with a GraphQL comment '#graphql'
(
[
(string (string_fragment) @injection.content)
(template_string (string_fragment) @injection.content)
]
(#match? @injection.content "^\\s*#graphql")
(#set! injection.language "graphql")
)
; Parse the contents of strings and tagged template literals with leading ECMAScript comments '/* GraphQL */'
(
((comment) @_ecma_comment [
(string (string_fragment) @injection.content)
(template_string (string_fragment) @injection.content)
])
(#eq? @_ecma_comment "/* GraphQL */")
(#set! injection.language "graphql")
)
; Parse regex syntax within regex literals
((regex_pattern) @injection.content
(#set! injection.language "regex"))
; Parse JSDoc annotations in multiline comments
((comment) @injection.content
(#set! injection.language "jsdoc")
(#match? @injection.content "^/\\*+"))
; Parse general tags in single line comments
((comment) @injection.content
(#set! injection.language "comment")
(#match? @injection.content "^//"))
; Match string literals passed to standard browser API methods that expects a
; css selector as argument.
; - https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
; - https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
; - https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
; - https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
; e.g.
; `const el = document.querySelector("div.user-panel.main input[name='login']");`
(call_expression
function: (member_expression
object: (identifier) @_object
property: (property_identifier) @_property (#any-of? @_property "querySelector" "querySelectorAll" "closest" "matches"))
arguments: (arguments
(string (string_fragment) @injection.content))
(#set! injection.language "css"))

26
queries/ecma/locals.scm Normal file
View File

@@ -0,0 +1,26 @@
; Scopes
;-------
[
(statement_block)
(arrow_function)
(function_expression)
(function_declaration)
(method_definition)
(for_statement)
(for_in_statement)
(catch_clause)
(finally_clause)
] @local.scope
; Definitions
;------------
; i => ...
(arrow_function
parameter: (identifier) @local.definition.variable.parameter)
; References
;------------
(identifier) @local.reference

236
queries/go/highlights.scm Normal file
View File

@@ -0,0 +1,236 @@
; Identifiers
(field_identifier) @variable.other.member
(identifier) @variable
(package_identifier) @namespace
(const_spec
name: (identifier) @constant)
(type_spec
name: (type_identifier) @constructor)
(keyed_element . (literal_element (identifier) @variable.other.member))
(field_declaration
name: (field_identifier) @variable.other.member)
(parameter_declaration (identifier) @variable.parameter)
(variadic_parameter_declaration (identifier) @variable.parameter)
(label_name) @label
(const_spec
name: (identifier) @constant)
; Function calls
(call_expression
function: (identifier) @function)
(call_expression
function: (selector_expression
field: (field_identifier) @function.method))
(call_expression
function: (identifier) @function.builtin
(#match? @function.builtin "^(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover|min|max|clear)$"))
; Types
(type_identifier) @type
(type_parameter_list
(type_parameter_declaration
name: (identifier) @type.parameter))
((type_identifier) @type.builtin
(#match? @type.builtin "^(any|bool|byte|comparable|complex128|complex64|error|float32|float64|int|int16|int32|int64|int8|rune|string|uint|uint16|uint32|uint64|uint8|uintptr)$"))
; Function definitions
(function_declaration
name: (identifier) @function)
(method_declaration
name: (field_identifier) @function.method)
(method_elem
name: (field_identifier) @function.method)
; Operators
[
"--"
"-"
"-="
":="
"!"
"!="
"..."
"*"
"*"
"*="
"/"
"/="
"&"
"&&"
"&="
"%"
"%="
"^"
"^="
"+"
"++"
"+="
"<-"
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"|"
"|="
"||"
"&^"
"&^="
"~"
] @operator
; Keywords
[
"default"
"type"
] @keyword
[
"defer"
"go"
"goto"
] @keyword.control
[
"if"
"else"
"switch"
"select"
"case"
] @keyword.control.conditional
[
"for"
"range"
] @keyword.control.repeat
[
"import"
"package"
] @keyword.control.import
[
"return"
"continue"
"break"
"fallthrough"
] @keyword.control.return
[
"func"
] @keyword.function
[
"var"
"chan"
"interface"
"map"
"struct"
] @keyword.storage.type
[
"const"
] @keyword.storage.modifier
; Delimiters
[
":"
"."
","
";"
] @punctuation.delimiter
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
; Literals
[
(interpreted_string_literal)
(raw_string_literal)
] @string
(rune_literal) @constant.character
(escape_sequence) @constant.character.escape
[
(int_literal)
] @constant.numeric.integer
[
(float_literal)
(imaginary_literal)
] @constant.numeric.float
[
(true)
(false)
] @constant.builtin.boolean
[
(nil)
(iota)
] @constant.builtin
; Comments
(comment) @comment
; Doc Comments
(source_file
.
(comment)+ @comment.block.documentation)
(source_file
(comment)+ @comment.block.documentation
.
(const_declaration))
(source_file
(comment)+ @comment.block.documentation
.
(function_declaration))
(source_file
(comment)+ @comment.block.documentation
.
(type_declaration))
(source_file
(comment)+ @comment.block.documentation
.
(var_declaration))

92
queries/go/injections.scm Normal file
View File

@@ -0,0 +1,92 @@
((comment) @injection.content
(#set! injection.language "comment"))
; Inject markdown into documentation comments
;
; Go's comments are documentation comments when they are directly followed
; by one of Go's statements (e.g. `type`, `func`, `const`)
;
; This is only a partial implementation, which covers only
; block comments. For line comments (which are more common),
; upstream changes to the grammar are required.
(
(comment) @injection.content . (comment)* . [
(package_clause) ; `package`
(type_declaration) ; `type`
(function_declaration) ; `func`
(method_declaration) ; `func`
(var_declaration) ; `var`
(const_declaration) ; `const`
; var (
; A = 1
; B = 2
; )
(const_spec)
; const (
; A = 1
; B = 2
; )
(var_spec)
]
(#set! injection.language "markdown"))
((comment) @injection.content
(#match? @injection.content "^//go:generate")
(#set! injection.language "bash"))
(call_expression
(selector_expression) @_function
(#any-of? @_function "regexp.Match" "regexp.MatchReader" "regexp.MatchString" "regexp.Compile" "regexp.CompilePOSIX" "regexp.MustCompile" "regexp.MustCompilePOSIX")
(argument_list
.
[
(raw_string_literal)
(interpreted_string_literal)
] @injection.content
(#set! injection.language "regex")))
; https://pkg.go.dev/fmt#Printf
; https://pkg.go.dev/fmt#Sprintf
; https://pkg.go.dev/fmt#Scanf
; https://pkg.go.dev/fmt#Errorf
((call_expression
function: (selector_expression
operand: (identifier) @_module
field: (field_identifier) @_func)
arguments: (argument_list
. (interpreted_string_literal) @injection.content))
(#eq? @_module "fmt")
(#any-of? @_func "Printf" "Sprintf" "Scanf" "Errorf")
(#set! injection.language "go-format-string"))
; https://pkg.go.dev/fmt#Fprintf
; https://pkg.go.dev/fmt#Fscanf
; https://pkg.go.dev/fmt#Sscanf
((call_expression
function: (selector_expression
operand: (identifier) @_module
field: (field_identifier) @_func)
arguments: (argument_list
; [(identifier) (interpreted_string_literal)]
(_)
; (identifier)
.
(interpreted_string_literal) @injection.content))
(#eq? @_module "fmt")
(#any-of? @_func "Fprintf" "Fscanf" "Sscanf")
(#set! injection.language "go-format-string"))
; https://pkg.go.dev/log#Printf
; https://pkg.go.dev/log#Fatalf
; https://pkg.go.dev/log#Panicf
; https://pkg.go.dev/log#Logger.Printf
; https://pkg.go.dev/log#Logger.Fatalf
; https://pkg.go.dev/log#Logger.Panicf
((call_expression
function: (selector_expression
operand: (identifier)
field: (field_identifier) @_func)
arguments: (argument_list
. (interpreted_string_literal) @injection.content))
(#any-of? @_func "Printf" "Fatalf" "Panicf")
(#set! injection.language "go-format-string"))

25
queries/go/locals.scm Normal file
View File

@@ -0,0 +1,25 @@
; Scopes
[
(function_declaration)
(method_declaration)
(type_declaration)
(block)
] @local.scope
; Definitions
(parameter_declaration (identifier) @local.definition.variable.parameter)
(variadic_parameter_declaration (identifier) @local.definition.variable.parameter)
(const_declaration
(const_spec
name: (identifier) @local.definition.constant))
; References
(identifier) @local.reference
; Field names in struct literals are identifier rather than field_identifier,
; these cannot be locals.
(keyed_element . (literal_element (identifier) @variable.other.member))

View File

@@ -0,0 +1,47 @@
(tag_name) @tag
(erroneous_end_tag_name) @error
(doctype) @constant
(attribute_name) @attribute
(entity) @string.special.symbol
(comment) @comment
((attribute
(attribute_name) @attribute
(quoted_attribute_value (attribute_value) @markup.link.url))
(#any-of? @attribute "href" "src"))
((element
(start_tag
(tag_name) @tag)
(text) @markup.link.label)
(#eq? @tag "a"))
(attribute [(attribute_value) (quoted_attribute_value)] @string)
((element
(start_tag
(tag_name) @tag)
(text) @markup.bold)
(#any-of? @tag "strong" "b"))
((element
(start_tag
(tag_name) @tag)
(text) @markup.italic)
(#any-of? @tag "em" "i"))
((element
(start_tag
(tag_name) @tag)
(text) @markup.strikethrough)
(#any-of? @tag "s" "del"))
[
"<"
">"
"</"
"/>"
"<!"
] @punctuation.bracket
"=" @punctuation.delimiter

View File

@@ -0,0 +1,10 @@
((comment) @injection.content
(#set! injection.language "comment"))
((script_element
(raw_text) @injection.content)
(#set! injection.language "javascript"))
((style_element
(raw_text) @injection.content)
(#set! injection.language "css"))

View File

@@ -0,0 +1,3 @@
; See runtime/queries/ecma/README.md for more info.
; inherits: ecma,_javascript

View File

@@ -0,0 +1,3 @@
; See runtime/queries/ecma/README.md for more info.
; inherits: _javascript,ecma

View File

@@ -0,0 +1,3 @@
; See runtime/queries/ecma/README.md for more info.
; inherits: _javascript,ecma

View File

@@ -0,0 +1,20 @@
[
(true)
(false)
] @constant.builtin.boolean
(null) @constant.builtin
(number) @constant.numeric
(string) @string
(escape_sequence) @constant.character.escape
(pair
key: (_) @variable.other.member)
"," @punctuation.delimiter
[
"["
"]"
"{"
"}"
] @punctuation.bracket

View File

@@ -0,0 +1,62 @@
(setext_heading (paragraph) @markup.heading.1 (setext_h1_underline) @markup.heading.marker)
(setext_heading (paragraph) @markup.heading.2 (setext_h2_underline) @markup.heading.marker)
(atx_heading (atx_h1_marker) @markup.heading.marker) @markup.heading.1
(atx_heading (atx_h2_marker) @markup.heading.marker) @markup.heading.2
(atx_heading (atx_h3_marker) @markup.heading.marker) @markup.heading.3
(atx_heading (atx_h4_marker) @markup.heading.marker) @markup.heading.4
(atx_heading (atx_h5_marker) @markup.heading.marker) @markup.heading.5
(atx_heading (atx_h6_marker) @markup.heading.marker) @markup.heading.6
[
(indented_code_block)
(fenced_code_block)
] @markup.raw.block
(info_string) @label
[
(fenced_code_block_delimiter)
] @punctuation.bracket
[
(link_destination)
] @markup.link.url
[
(link_label)
] @markup.link.label
[
(list_marker_plus)
(list_marker_minus)
(list_marker_star)
] @markup.list.unnumbered
[
(list_marker_dot)
(list_marker_parenthesis)
] @markup.list.numbered
(task_list_marker_checked) @markup.list.checked
(task_list_marker_unchecked) @markup.list.unchecked
(thematic_break) @punctuation.special
[
(block_continuation)
(block_quote_marker)
] @punctuation.special
[
(backslash_escape)
] @string.escape
(block_quote) @markup.quote
(pipe_table_row
"|" @punctuation.special)
(pipe_table_header
"|" @punctuation.special)
(pipe_table_delimiter_row) @punctuation.special

View File

@@ -0,0 +1,22 @@
; From nvim-treesitter/nvim-treesitter
(fenced_code_block
(code_fence_content) @injection.shebang @injection.content
(#set! injection.include-unnamed-children))
(fenced_code_block
(info_string
(language) @injection.language)
(code_fence_content) @injection.content (#set! injection.include-unnamed-children))
((html_block) @injection.content
(#set! injection.language "html")
(#set! injection.include-unnamed-children)
(#set! injection.combined))
((pipe_table_cell) @injection.content (#set! injection.language "markdown.inline") (#set! injection.include-unnamed-children))
((minus_metadata) @injection.content (#set! injection.language "yaml") (#set! injection.include-unnamed-children))
((plus_metadata) @injection.content (#set! injection.language "toml") (#set! injection.include-unnamed-children))
((inline) @injection.content (#set! injection.language "markdown.inline") (#set! injection.include-unnamed-children))

View File

@@ -1,24 +0,0 @@
; Markdown injection queries with include-children directive
; Enables proper highlighting of embedded languages in code blocks and frontmatter
; Fenced code blocks - inject language specified in info string
(fenced_code_block
(info_string
(language) @injection.language)
(code_fence_content) @injection.content
(#set! injection.include-children))
; YAML frontmatter (--- delimited at start of document)
((minus_metadata) @injection.content
(#set! injection.language "yaml")
(#set! injection.include-children))
; TOML frontmatter (+++ delimited)
((plus_metadata) @injection.content
(#set! injection.language "toml")
(#set! injection.include-children))
; HTML blocks
((html_block) @injection.content
(#set! injection.language "html")
(#set! injection.include-children))

View File

@@ -1,9 +1,5 @@
; Nix syntax highlighting queries (adapted from Helix editor)
; Maps to standard tree-sitter capture names for compatibility with tree-sitter-highlight
(comment) @comment
; Punctuation
[
";"
"."
@@ -22,16 +18,15 @@
"}"
] @punctuation.bracket
; Keywords
"assert" @keyword
"or" @keyword
"rec" @keyword
"assert" @keyword.control.exception
"or" @keyword.operator
"rec" @keyword.control.repeat
[
"if"
"then"
"else"
] @keyword
] @keyword.control.conditional
[
"let"
@@ -40,14 +35,11 @@
"with"
] @keyword
; Variables and identifiers
(variable_expression name: (identifier) @variable)
; Attribute access (properties)
(select_expression
attrpath: (attrpath attr: (identifier)) @property)
attrpath: (attrpath attr: (identifier)) @variable.other.member)
; Function calls
(apply_expression
function: [
(variable_expression name: (identifier) @function)
@@ -55,23 +47,19 @@
attrpath: (attrpath
attr: (identifier) @function .))])
; Builtin variables
((identifier) @variable.builtin
(#match? @variable.builtin "^(__currentSystem|__currentTime|__nixPath|__nixVersion|__storeDir|builtins)$")
(#is-not? local))
; Builtin functions
((identifier) @function.builtin
(#match? @function.builtin "^(__add|__addErrorContext|__all|__any|__appendContext|__attrNames|__attrValues|__bitAnd|__bitOr|__bitXor|__catAttrs|__compareVersions|__concatLists|__concatMap|__concatStringsSep|__deepSeq|__div|__elem|__elemAt|__fetchurl|__filter|__filterSource|__findFile|__foldl'|__fromJSON|__functionArgs|__genList|__genericClosure|__getAttr|__getContext|__getEnv|__hasAttr|__hasContext|__hashFile|__hashString|__head|__intersectAttrs|__isAttrs|__isBool|__isFloat|__isFunction|__isInt|__isList|__isPath|__isString|__langVersion|__length|__lessThan|__listToAttrs|__mapAttrs|__match|__mul|__parseDrvName|__partition|__path|__pathExists|__readDir|__readFile|__replaceStrings|__seq|__sort|__split|__splitVersion|__storePath|__stringLength|__sub|__substring|__tail|__toFile|__toJSON|__toPath|__toXML|__trace|__tryEval|__typeOf|__unsafeDiscardOutputDependency|__unsafeDiscardStringContext|__unsafeGetAttrPos|__valueSize|abort|baseNameOf|derivation|derivationStrict|dirOf|fetchGit|fetchMercurial|fetchTarball|fromTOML|import|isNull|map|placeholder|removeAttrs|scopedImport|throw|toString)$")
(#is-not? local))
; Strings
[
(string_expression)
(indented_string_expression)
] @string
; Special string types (paths, URIs)
[
(path_expression)
(hpath_expression)
@@ -80,21 +68,17 @@
(uri_expression) @string.special.uri
; Boolean constants
((identifier) @constant.builtin (#match? @constant.builtin "^(true|false)$"))
; boolean
((identifier) @constant.builtin.boolean (#match? @constant.builtin.boolean "^(true|false)$")) @constant.builtin.boolean
; null
((identifier) @constant.builtin (#eq? @constant.builtin "null")) @constant.builtin
; Null constant
((identifier) @constant.builtin (#eq? @constant.builtin "null"))
(integer_expression) @constant.numeric.integer
(float_expression) @constant.numeric.float
; Numbers
(integer_expression) @number
(float_expression) @number
(escape_sequence) @constant.character.escape
(dollar_escape) @constant.character.escape
; Escape sequences
(escape_sequence) @escape
(dollar_escape) @escape
; Function parameters
(function_expression
"@"? @punctuation.delimiter
universal: (identifier) @variable.parameter
@@ -105,29 +89,24 @@
name: (identifier) @variable.parameter
"?"? @punctuation.delimiter)
; String interpolation
(interpolation
"${" @punctuation.special
"}" @punctuation.special) @embedded
; Operators
(unary_expression
operator: _ @operator)
(binary_expression
operator: _ @operator)
; Attribute bindings
(binding
attrpath: (attrpath attr: (identifier)) @property)
attrpath: (attrpath attr: (identifier)) @variable.other.member)
; Inherit expressions
(inherit_from attrs: (inherited_attrs attr: (identifier) @property))
(inherit_from attrs: (inherited_attrs attr: (identifier) @variable.other.member))
(inherited_attrs attr: (identifier) @variable)
; Has attribute expression
(has_attr_expression
expression: (_)
"?" @operator
attrpath: (attrpath
attr: (identifier) @property))
attr: (identifier) @variable.other.member))

View File

@@ -1,7 +1,3 @@
; Nix injection queries for embedded language highlighting
; Adapted from Helix editor queries for tree-sitter-highlight compatibility
; Removed Helix-specific predicates: #is-not?, #any-of?, @injection.shebang, @injection.filename
((comment) @injection.content
(#set! injection.language "comment"))
@@ -37,6 +33,7 @@
(#set! injection.combined))
; builtins.{match,split} regex str
; Example: nix/tests/lang/eval-okay-regex-{match,split}.nix
((apply_expression
function: (_) @_func
argument: (indented_string_expression (string_fragment) @injection.content))
@@ -45,6 +42,7 @@
(#set! injection.combined))
; builtins.fromJSON json
; Example: nix/tests/lang/eval-okay-fromjson.nix
((apply_expression
function: (_) @_func
argument: (indented_string_expression (string_fragment) @injection.content))
@@ -53,6 +51,7 @@
(#set! injection.combined))
; builtins.fromTOML toml
; Example: https://github.com/NixOS/nix/blob/3e8cd2ffe6c2c6ed8aae7853ddcfcc6d2a49b0ce/tests/functional/lang/eval-okay-fromTOML.nix
((apply_expression
function: (_) @_func
argument: (indented_string_expression (string_fragment) @injection.content))
@@ -99,6 +98,8 @@
(#set! injection.language "c")
(#set! injection.combined))
; pkgs.writers.* usage examples: nixpkgs/pkgs/build-support/writers/test.nix
; pkgs.writers.write{Bash,Dash}[Bin] name content
((apply_expression
function: (apply_expression function: (_) @_func)
@@ -135,6 +136,16 @@
(#set! injection.language "haskell")
(#set! injection.combined))
; pkgs.writers.writeNim[Bin] name attrs content
(apply_expression
(apply_expression
function: (apply_expression
function: ((_) @_func)))
argument: (indented_string_expression (string_fragment) @injection.content)
(#match? @_func "(^|\\.)writeNim(Bin)?$")
(#set! injection.language "nim")
(#set! injection.combined))
; pkgs.writers.writeJS[Bin] name attrs content
(apply_expression
(apply_expression
@@ -145,6 +156,16 @@
(#set! injection.language "javascript")
(#set! injection.combined))
; pkgs.writers.writePerl[Bin] name attrs content
(apply_expression
(apply_expression
function: (apply_expression
function: ((_) @_func)))
argument: (indented_string_expression (string_fragment) @injection.content)
(#match? @_func "(^|\\.)writePerl(Bin)?$")
(#set! injection.language "perl")
(#set! injection.combined))
; pkgs.writers.write{Python,PyPy}{2,3}[Bin] name attrs content
(apply_expression
(apply_expression
@@ -155,6 +176,16 @@
(#set! injection.language "python")
(#set! injection.combined))
; pkgs.writers.writeNu[Bin] name attrs content
(apply_expression
(apply_expression
function: (apply_expression
function: ((_) @_func)))
argument: (indented_string_expression (string_fragment) @injection.content)
(#match? @_func "(^|\\.)writeNu(Bin)?$")
(#set! injection.language "nu")
(#set! injection.combined))
; pkgs.writers.writeRuby[Bin] name attrs content
(apply_expression
(apply_expression
@@ -175,16 +206,67 @@
(#set! injection.language "lua")
(#set! injection.combined))
; pkgs.writers.writeNginxConfig name attrs content
(apply_expression
(apply_expression
function: (apply_expression
function: ((_) @_func)))
argument: (indented_string_expression (string_fragment) @injection.content)
(#match? @_func "(^|\\.)writeNginxConfig$")
(#set! injection.language "nginx")
(#set! injection.combined))
; pkgs.writers.writeGuile[Bin] name attrs content
(apply_expression
(apply_expression
function: (apply_expression
function: ((_) @_func)))
argument: (indented_string_expression (string_fragment) @injection.content)
(#match? @_func "(^|\\.)writeGuile(Bin)?$")
(#set! injection.language "scheme") ; Guile is a GNU specific implementation of scheme
(#set! injection.combined))
; pkgs.writers.writeBabashka[Bin] name attrs content
(apply_expression
(apply_expression
function: (apply_expression
function: ((_) @_func)))
argument: (indented_string_expression (string_fragment) @injection.content)
(#match? @_func "(^|\\.)writeBabashka(Bin)?$")
(#set! injection.language "clojure")
(#set! injection.combined))
; pkgs.writers.writeFSharp[Bin] name content
; No query available for f-sharp as of the time of writing
; See: https://github.com/helix-editor/helix/issues/4943
; ((apply_expression
; function: (apply_expression function: (_) @_func)
; argument: (indented_string_expression (string_fragment) @injection.content))
; (#match? @_func "(^|\\.)writeFSharp(Bin)?$")
; (#set! injection.language "f-sharp")
; (#set! injection.combined))
((apply_expression
function: (apply_expression function: (_) @_func
argument: (string_expression (string_fragment) @injection.filename))
argument: (indented_string_expression (string_fragment) @injection.content))
(#match? @_func "(^|\\.)write(Text|Script(Bin)?)$")
(#set! injection.combined))
((indented_string_expression (string_fragment) @injection.shebang @injection.content)
(#set! injection.combined))
; string contents of lib.literalExpression is nix code
((apply_expression
function: [
(select_expression)
(variable_expression)
(select_expression) ; `lib.literalExpression`
(variable_expression) ; `literalExpression` this is the case when the symbol is brougth into scope e.g. `let inherit (lib) literalExpression; in`
] @_func
argument: [
(indented_string_expression (string_fragment) @injection.content)
(string_expression (string_fragment) @injection.content)
(indented_string_expression (string_fragment) @injection.content) ; lib.literalExpression ''...''
(string_expression (string_fragment) @injection.content) ; lib.literalExpression "..."
])
(#match? @_func "(lib\\.)?literalExpression$")
(#any-of? @_func "lib.literalExpression" "literalExpression")
(#set! injection.language "nix")
(#set! injection.combined))

View File

@@ -0,0 +1,308 @@
; -------
; Punctuation
; -------
["," "." ":" ";" (ellipsis)] @punctuation.delimiter
["(" ")" "[" "]" "{" "}"] @punctuation.bracket
(interpolation
"{" @punctuation.special
"}" @punctuation.special)
; -------
; Operators
; -------
[
"-"
"-="
"!="
"*"
"**"
"**="
"*="
"/"
"//"
"//="
"/="
"&"
"&="
"%"
"%="
"^"
"^="
"+"
"->"
"+="
"<"
"<<"
"<<="
"<="
"<>"
"="
":="
"=="
">"
">="
">>"
">>="
"|"
"|="
"~"
"@="
] @operator
; -------
; Variables
; -------
(identifier) @variable
; - Member
(attribute attribute: (identifier) @variable.other.member)
; - Parameter
(parameters (identifier) @variable.parameter)
(parameters (typed_parameter (identifier) @variable.parameter))
(parameters (default_parameter name: (identifier) @variable.parameter))
(parameters (typed_default_parameter name: (identifier) @variable.parameter))
(parameters
(list_splat_pattern ; *args
(identifier) @variable.parameter))
(parameters
(dictionary_splat_pattern ; **kwargs
(identifier) @variable.parameter))
(lambda_parameters
(identifier) @variable.parameter)
(keyword_argument
name: (identifier) @variable.parameter)
; - Builtin
((identifier) @variable.builtin
(#any-of? @variable.builtin "self" "cls"))
; -------
; Keywords
; -------
[
"async"
"class"
"exec"
"global"
"nonlocal"
"print"
"type"
] @keyword
; Operators
[
"and"
"or"
"not in"
"in" ; Has to be before loop keywords because "in" is overloaded
"not"
"del"
"is not"
"is"
] @keyword.operator
; Control
[
"as"
"assert"
"await"
"from"
"pass"
"with"
] @keyword.control
; Conditionals
[
"if"
"elif"
"else"
"match"
"case"
] @keyword.control.conditional
; Exceptions
[
"raise"
"try"
"except"
"finally"
] @keyword.control.exception
(raise_statement "from" @keyword.control.exception)
; Functions
[
"def"
"lambda"
] @keyword.function
; Import
"import" @keyword.control.import
; Loops
[
"while"
"for"
"break"
"continue"
] @keyword.control.repeat
(for_statement "in" @keyword.control.repeat)
(for_in_clause "in" @keyword.control.repeat)
; Return
[
"return"
"yield"
] @keyword.control.return
(yield "from" @keyword.control.return)
; -------
; Imports
; -------
(dotted_name
(identifier)* @namespace)
(aliased_import
alias: (identifier) @namespace)
; - Builtins
(none) @constant.builtin ; Has to be before types
; -------
; Types
; -------
((identifier) @type
(#match? @type "^[A-Z]")) ; Has to be before constructor due to this being a more general match
; In type hints make everything types to catch non-conforming identifiers
; (e.g., datetime.datetime) and None
(type [(identifier) (none)] @type)
; Handle [] . and | nesting 4 levels deep
(type
(_ [(identifier) (none)]? @type
(_ [(identifier) (none)]? @type
(_ [(identifier) (none)]? @type
(_ [(identifier) (none)]? @type)))))
; Classes
(class_definition name: (identifier) @type)
(class_definition superclasses: (argument_list (identifier) @type))
; -------
; Functions
; -------
(function_definition
name: (identifier) @function)
(call
function: (identifier) @function)
; Decorators
(decorator) @function
(decorator (identifier) @function)
(decorator (attribute attribute: (identifier) @function))
(decorator (call
function: (attribute attribute: (identifier) @function)))
; Methods
(call
function: (attribute attribute: (identifier) @function.method))
; Builtin functions
((call
function: (identifier) @function.builtin)
(#any-of?
@function.builtin
"abs" "all" "any" "ascii" "bin" "breakpoint" "bytearray" "callable" "chr"
"classmethod" "compile" "complex" "delattr" "dir" "divmod" "enumerate"
"eval" "exec" "filter" "format" "getattr" "globals" "hasattr" "hash" "help"
"hex" "id" "input" "isinstance" "issubclass" "iter" "len" "locals" "map"
"max" "memoryview" "min" "next" "object" "oct" "open" "ord" "pow" "print"
"property" "range" "repr" "reversed" "round" "setattr" "slice" "sorted"
"staticmethod" "sum" "super" "type" "vars" "zip" "__import__"))
; Constructors
(call
function: (attribute attribute: (identifier) @constructor)
(#any-of?
@constructor
"__new__" "__init__"))
((call
function: (identifier) @constructor)
(#any-of?
@constructor
"__new__" "__init__"))
(function_definition
name: (identifier) @constructor
(#any-of? @constructor "__new__" "__init__"))
(call
function: (attribute attribute: (identifier) @constructor)
(#match? @constructor "^[A-Z]"))
(call
function: (identifier) @constructor
(#match? @constructor "^[A-Z]"))
; Builtin types
((identifier) @type.builtin ; Has to be after functions due to broad matching
(#any-of?
@type.builtin
"bool" "bytes" "dict" "float" "frozenset" "int" "list" "set" "str" "tuple"))
; Builtin error types
((identifier) @type.builtin ; Has to be after constructors due to broad matching of constructor
(#any-of? @type.builtin
"BaseException" "Exception" "ArithmeticError" "BufferError" "LookupError"
"AssertionError" "AttributeError" "EOFError" "FloatingPointError" "GeneratorExit"
"ImportError" "ModuleNotFoundError" "IndexError" "KeyError" "KeyboardInterrupt"
"MemoryError" "NameError" "NotImplementedError" "OSError" "OverflowError"
"RecursionError" "ReferenceError" "RuntimeError" "StopIteration" "StopAsyncIteration"
"SyntaxError" "IndentationError" "TabError" "SystemError" "SystemExit" "TypeError"
"UnboundLocalError" "UnicodeError" "UnicodeEncodeError" "UnicodeDecodeError"
"UnicodeTranslateError" "ValueError" "ZeroDivisionError" "EnvironmentError"
"IOError" "WindowsError" "BlockingIOError" "ChildProcessError" "ConnectionError"
"BrokenPipeError" "ConnectionAbortedError" "ConnectionRefusedError"
"ConnectionResetError" "FileExistsError" "FileNotFoundError" "InterruptedError"
"IsADirectoryError" "NotADirectoryError" "PermissionError" "ProcessLookupError"
"TimeoutError" "Warning" "UserWarning" "DeprecationWarning" "PendingDeprecationWarning"
"SyntaxWarning" "RuntimeWarning" "FutureWarning" "ImportWarning" "UnicodeWarning"
"BytesWarning" "ResourceWarning"))
; -------
; Constants
; -------
((identifier) @constant
(#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
(escape_sequence) @constant.character.escape
[
(true)
(false)
] @constant.builtin.boolean
; - Numbers
(integer) @constant.numeric.integer
(float) @constant.numeric.float
; -------
; Other literals
; -------
(comment) @comment
(string) @string

View File

@@ -0,0 +1,14 @@
((comment) @injection.content
(#set! injection.language "comment"))
; Match all 9 functions in the `re` module from the standard library that
; that takes a regex pattern as first argument.
; https://docs.python.org/3/library/re.html#functions
(call
function: (attribute
object: (identifier) @_module (#eq? @_module "re")
attribute: (identifier) @_function (#any-of? @_function "compile" "search" "match" "fullmatch" "sub" "subn" "findall" "finditer" "split"))
arguments: (argument_list
. (string
(string_content) @injection.content))
(#set! injection.language "regex"))

50
queries/python/locals.scm Normal file
View File

@@ -0,0 +1,50 @@
;; Scopes
[
(module)
(function_definition)
(lambda)
] @local.scope
;; Definitions
; Parameters
(parameters
(identifier) @local.definition.variable.parameter)
(parameters
(typed_parameter
(identifier) @local.definition.variable.parameter))
(parameters
(default_parameter
name: (identifier) @local.definition.variable.parameter))
(parameters
(typed_default_parameter
name: (identifier) @local.definition.variable.parameter))
(parameters
(list_splat_pattern ; *args
(identifier) @local.definition.variable.parameter))
(parameters
(dictionary_splat_pattern ; **kwargs
(identifier) @local.definition.variable.parameter))
(parameters
(identifier) @local.definition.variable.builtin
(#any-of? @local.definition.variable.builtin "self" "cls")) ; label self/cls as builtin
(lambda_parameters
(identifier) @local.definition.variable.parameter)
; Imports
(import_statement
name: (dotted_name
(identifier) @local.definition.namespace))
(aliased_import
alias: (identifier) @local.definition.namespace)
;; References
(identifier) @local.reference
; don't make the name of kwargs locals
(keyword_argument
name: (identifier) @variable.parameter)

514
queries/rust/highlights.scm Normal file
View File

@@ -0,0 +1,514 @@
; -------
; Basic identifiers
; -------
; We do not style ? as an operator on purpose as it allows styling ? differently, as many highlighters do. @operator.special might have been a better scope, but @special is already documented so the change would break themes (including the intent of the default theme)
"?" @special
(type_identifier) @type
(identifier) @variable
(field_identifier) @variable.other.member
; -------
; Operators
; -------
[
"*"
"'"
"->"
"=>"
"<="
"="
"=="
"!"
"!="
"%"
"%="
"&"
"&="
"&&"
"|"
"|="
"||"
"^"
"^="
"*"
"*="
"-"
"-="
"+"
"+="
"/"
"/="
">"
"<"
">="
">>"
"<<"
">>="
"<<="
"@"
".."
"..="
"'"
] @operator
; -------
; Paths
; -------
(use_declaration
argument: (identifier) @namespace)
(use_wildcard
(identifier) @namespace)
(extern_crate_declaration
name: (identifier) @namespace
alias: (identifier)? @namespace)
(mod_item
name: (identifier) @namespace)
(scoped_use_list
path: (identifier)? @namespace)
(use_list
(identifier) @namespace)
(use_as_clause
path: (identifier)? @namespace
alias: (identifier) @namespace)
; -------
; Types
; -------
(type_parameter
name: (type_identifier) @type.parameter)
((type_arguments (type_identifier) @constant)
(#match? @constant "^[A-Z_]+$"))
(type_arguments (type_identifier) @type)
; `_` in `(_, _)`
(tuple_struct_pattern "_" @comment.unused)
; `_` in `Vec<_>`
((type_arguments (type_identifier) @comment.unused)
(#eq? @comment.unused "_"))
; `_` in `Rc<[_]>`
((array_type (type_identifier) @comment.unused)
(#eq? @comment.unused "_"))
; ---
; Primitives
; ---
(escape_sequence) @constant.character.escape
(primitive_type) @type.builtin
(boolean_literal) @constant.builtin.boolean
(integer_literal) @constant.numeric.integer
(float_literal) @constant.numeric.float
(char_literal) @constant.character
[
(string_literal)
(raw_string_literal)
] @string
; -------
; Comments
; -------
(shebang) @comment
(line_comment) @comment.line
(block_comment) @comment.block
; Doc Comments
(line_comment
(outer_doc_comment_marker "/" @comment.line.documentation)
(doc_comment)) @comment.line.documentation
(line_comment
(inner_doc_comment_marker "!" @comment.line.documentation)
(doc_comment)) @comment.line.documentation
(block_comment
(outer_doc_comment_marker) @comment.block.documentation
(doc_comment) "*/" @comment.block.documentation) @comment.block.documentation
(block_comment
(inner_doc_comment_marker) @comment.block.documentation
(doc_comment) "*/" @comment.block.documentation) @comment.block.documentation
; ---
; Extraneous
; ---
(self) @variable.builtin
(field_initializer
(field_identifier) @variable.other.member)
(shorthand_field_initializer
(identifier) @variable.other.member)
(shorthand_field_identifier) @variable.other.member
(lifetime
"'" @label
(identifier) @label)
(label
"'" @label
(identifier) @label)
; ---
; Punctuation
; ---
[
"::"
"."
";"
","
":"
] @punctuation.delimiter
[
"("
")"
"["
"]"
"{"
"}"
"#"
] @punctuation.bracket
(type_arguments
[
"<"
">"
] @punctuation.bracket)
(type_parameters
[
"<"
">"
] @punctuation.bracket)
(for_lifetimes ["<" ">"] @punctuation.bracket)
(closure_parameters
"|" @punctuation.bracket)
(bracketed_type ["<" ">"] @punctuation.bracket)
; ---
; Variables
; ---
(let_declaration
pattern: [
((identifier) @variable)
((tuple_pattern
(identifier) @variable))
])
; It needs to be anonymous to not conflict with `call_expression` further below.
(_
value: (field_expression
value: (identifier)? @variable
field: (field_identifier) @variable.other.member))
(parameter
pattern: (identifier) @variable.parameter)
(closure_parameters
(identifier) @variable.parameter)
; -------
; Keywords
; -------
"in" @keyword.control
[
"match"
"if"
"else"
"try"
] @keyword.control.conditional
[
"while"
"loop"
] @keyword.control.repeat
[
"break"
"continue"
"return"
"await"
"yield"
] @keyword.control.return
"use" @keyword.control.import
(mod_item "mod" @keyword.control.import !body)
(use_as_clause "as" @keyword.control.import)
(type_cast_expression "as" @keyword.operator)
[
(crate)
(super)
"as"
"pub"
"mod"
"extern"
"impl"
"where"
"trait"
"for"
"default"
"async"
] @keyword
(for_expression
"for" @keyword.control.repeat)
(gen_block "gen" @keyword.control)
[
"struct"
"enum"
"union"
"type"
] @keyword.storage.type
"let" @keyword.storage
"fn" @keyword.function
"unsafe" @keyword.special
"macro_rules!" @function.macro
(mutable_specifier) @keyword.storage.modifier.mut
(reference_type "&" @keyword.storage.modifier.ref)
(self_parameter "&" @keyword.storage.modifier.ref)
[
"static"
"const"
"raw"
"ref"
"move"
"dyn"
] @keyword.storage.modifier
; TODO: variable.mut to highlight mutable identifiers via locals.scm
; ---
; Remaining Paths
; ---
(scoped_identifier
path: (identifier)? @namespace
name: (identifier) @namespace)
(scoped_type_identifier
path: (identifier) @namespace)
; -------
; Functions
; -------
; highlight `baz` in `any_function(foo::bar::baz)` as function
; This generically works for an unlimited number of path segments:
;
; - `f(foo::bar)`
; - `f(foo::bar::baz)`
; - `f(foo::bar::baz::quux)`
;
; We know that in the above examples, the last component of each path is a function
; as the only other valid thing (following Rust naming conventions) would be a module at
; that position, however you cannot pass modules as arguments
(call_expression
function: _
arguments: (arguments
(scoped_identifier
path: _
name: (identifier) @function)))
(call_expression
function: [
((identifier) @function)
(scoped_identifier
name: (identifier) @function)
(field_expression
field: (field_identifier) @function)
])
(generic_function
function: [
((identifier) @function)
(scoped_identifier
name: (identifier) @function)
(field_expression
field: (field_identifier) @function.method)
])
(function_item
name: (identifier) @function)
(function_signature_item
name: (identifier) @function)
; -------
; Guess Other Types
; -------
; Other PascalCase identifiers are assumed to be structs.
((identifier) @type
(#match? @type "^[A-Z]"))
(never_type "!" @type)
((identifier) @constant
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
; ---
; PascalCase identifiers in call_expressions (e.g. `Ok()`)
; are assumed to be enum constructors.
; ---
(call_expression
function: [
((identifier) @constructor
(#match? @constructor "^[A-Z]"))
(scoped_identifier
name: ((identifier) @constructor
(#match? @constructor "^[A-Z]")))
])
; ---
; PascalCase identifiers under a path which is also PascalCase
; are assumed to be constructors if they have methods or fields.
; ---
(field_expression
value: (scoped_identifier
path: [
(identifier) @type
(scoped_identifier
name: (identifier) @type)
]
name: (identifier) @constructor
(#match? @type "^[A-Z]")
(#match? @constructor "^[A-Z]")))
(enum_variant (identifier) @type.enum.variant)
; -------
; Constructors
; -------
; TODO: this is largely guesswork, remove it once we get actual info from locals.scm or r-a
(struct_expression
name: (type_identifier) @constructor)
(tuple_struct_pattern
type: [
(identifier) @constructor
(scoped_identifier
name: (identifier) @constructor)
])
(struct_pattern
type: [
((type_identifier) @constructor)
(scoped_type_identifier
name: (type_identifier) @constructor)
])
(match_pattern
((identifier) @constructor) (#match? @constructor "^[A-Z]"))
(or_pattern
((identifier) @constructor)
((identifier) @constructor)
(#match? @constructor "^[A-Z]"))
; ---
; Macros
; ---
(attribute
(identifier) @function.macro)
(inner_attribute_item "!" @punctuation)
(attribute
[
(identifier) @function.macro
(scoped_identifier
name: (identifier) @function.macro)
]
(token_tree (identifier) @function.macro)?)
(inner_attribute_item) @attribute
(macro_definition
name: (identifier) @function.macro)
(macro_invocation
macro: [
((identifier) @function.macro)
(scoped_identifier
name: (identifier) @function.macro)
]
"!" @function.macro)
(metavariable) @variable.parameter
(fragment_specifier) @type
(attribute
(identifier) @special
arguments: (token_tree (identifier) @type)
(#eq? @special "derive")
)
(token_repetition_pattern) @punctuation.delimiter
(token_repetition_pattern [")" "(" "$"] @punctuation.special)
(token_repetition_pattern "?" @operator)
; ---
; Prelude
; ---
((identifier) @type.enum.variant.builtin
(#any-of? @type.enum.variant.builtin "Some" "None" "Ok" "Err"))
(call_expression
(identifier) @function.builtin
(#any-of? @function.builtin
"drop"
"size_of"
"size_of_val"
"align_of"
"align_of_val"))
((type_identifier) @type.builtin
(#any-of?
@type.builtin
"Send"
"Sized"
"Sync"
"Unpin"
"Drop"
"Fn"
"FnMut"
"FnOnce"
"AsMut"
"AsRef"
"From"
"Into"
"DoubleEndedIterator"
"ExactSizeIterator"
"Extend"
"IntoIterator"
"Iterator"
"Option"
"Result"
"Clone"
"Copy"
"Debug"
"Default"
"Eq"
"Hash"
"Ord"
"PartialEq"
"PartialOrd"
"ToOwned"
"Box"
"String"
"ToString"
"Vec"
"FromIterator"
"TryFrom"
"TryInto"))

217
queries/rust/injections.scm Normal file
View File

@@ -0,0 +1,217 @@
([(line_comment !doc) (block_comment !doc)] @injection.content
(#set! injection.language "comment"))
((doc_comment) @injection.content
(#set! injection.language "markdown-rustdoc")
(#set! injection.combined))
((macro_invocation
(token_tree) @injection.content)
(#set! injection.language "rust")
(#set! injection.include-children))
((macro_rule
(token_tree) @injection.content)
(#set! injection.language "rust")
(#set! injection.include-children))
((macro_invocation
macro:
[
(scoped_identifier
name: (_) @_macro_name)
(identifier) @_macro_name
]
(token_tree) @injection.content)
(#eq? @_macro_name "html")
(#set! injection.language "html")
(#set! injection.include-children))
((macro_invocation
macro:
[
(scoped_identifier
name: (_) @_macro_name)
(identifier) @_macro_name
]
(token_tree) @injection.content)
(#eq? @_macro_name "slint")
(#set! injection.language "slint")
(#set! injection.include-children))
((macro_invocation
macro:
[
(scoped_identifier name: (_) @_macro_name)
(identifier) @_macro_name
]
(token_tree
(token_tree . "{" "}" .) @injection.content))
(#eq? @_macro_name "json")
(#set! injection.language "json")
(#set! injection.include-children))
(call_expression
function: (scoped_identifier
path: (identifier) @_regex (#any-of? @_regex "Regex" "RegexBuilder")
name: (identifier) @_new (#eq? @_new "new"))
arguments:
(arguments
[
(string_literal (string_content) @injection.content)
(raw_string_literal (string_content) @injection.content)
])
(#set! injection.language "regex"))
(call_expression
function: (scoped_identifier
path: (scoped_identifier (identifier) @_regex (#any-of? @_regex "Regex" "RegexBuilder") .)
name: (identifier) @_new (#eq? @_new "new"))
arguments:
(arguments
[
(string_literal (string_content) @injection.content)
(raw_string_literal (string_content) @injection.content)
])
(#set! injection.language "regex"))
; Highlight SQL in `sqlx::query!()`, `sqlx::query_scalar!()`, and `sqlx::query_scalar_unchecked!()`
(macro_invocation
macro: (scoped_identifier
path: (identifier) @_sqlx (#eq? @_sqlx "sqlx")
name: (identifier) @_query (#match? @_query "^query(_scalar|_scalar_unchecked)?$"))
(token_tree
; Only the first argument is SQL
.
[
(string_literal (string_content) @injection.content)
(raw_string_literal (string_content) @injection.content)
]
)
(#set! injection.language "sql"))
; Highlight SQL in `sqlx::query_as!()` and `sqlx::query_as_unchecked!()`
(macro_invocation
macro: (scoped_identifier
path: (identifier) @_sqlx (#eq? @_sqlx "sqlx")
name: (identifier) @_query_as (#match? @_query_as "^query_as(_unchecked)?$"))
(token_tree
; Only the second argument is SQL
.
; Allow anything as the first argument in case the user has lower case type
; names for some reason
(_)
[
(string_literal (string_content) @injection.content)
(raw_string_literal (string_content) @injection.content)
]
)
(#set! injection.language "sql"))
; Highlight SQL in `sqlx::query*` and `sqlx::raw_sql` functions
(call_expression
function: (scoped_identifier
path: (identifier) @_sqlx
(#eq? @_sqlx "sqlx")
name: (identifier) @_query_function)
(#match? @_query_function "^query.*|raw_sql$")
arguments: (arguments
.
[
(string_literal
(string_content) @injection.content)
(raw_string_literal
(string_content) @injection.content)
])
(#set! injection.language "sql"))
; Special language `tree-sitter-rust-format-args` for Rust macros,
; which use `format_args!` under the hood and therefore have
; the `format_args!` syntax.
;
; This language is injected into a hard-coded set of macros.
(
(macro_invocation
macro:
[
(scoped_identifier
name: (_) @_macro_name)
(identifier) @_macro_name
]
(token_tree) @injection.content
)
(#any-of? @_macro_name
; 1st argument is `format_args!`
; std
"print" "println" "eprint" "eprintln"
"format" "format_args" "todo" "panic"
"unreachable" "unimplemented" "compile_error"
; log
"crit" "trace" "debug" "info" "warn" "error"
; anyhow
"anyhow" "bail"
; syn
"format_ident"
; indoc
"formatdoc" "printdoc" "eprintdoc" "writedoc"
; iced
"text"
; ratatui
"span"
; eyre
"eyre"
; miette
"miette"
; 2nd argument is `format_args!`
; std
"write" "writeln" "assert" "debug_assert"
; defmt
"expect" "unwrap"
; ratatui
"span"
; 3rd argument is `format_args!`
; std
"assert_eq" "debug_assert_eq" "assert_ne" "debug_assert_ne"
; Dioxus's rsx! macro accepts string interpolation in all
; strings, across the entire token tree
"rsx"
)
(#set! injection.language "rust-format-args-macro")
(#set! injection.include-children)
)
; for some queries (e.g. when you have generic table names) you need to wrap it in `AssertSqlSafe`
; after `format!` so it can overwrite `format!` formatting correctly.
(call_expression
function: [
(scoped_identifier
path: (identifier) @_sqlx
(#eq? @_sqlx "sqlx")
name: (identifier) @_AssertSqlSafe)
(identifier) @_AssertSqlSafe
]
(#eq? @_AssertSqlSafe "AssertSqlSafe")
arguments: (arguments
[
(string_literal
(string_content) @injection.content)
(raw_string_literal
(string_content) @injection.content)
(macro_invocation
macro: (identifier) @_format
(#eq? @_format "format")
(token_tree
[
(string_literal
(string_content) @injection.content)
(raw_string_literal
(string_content) @injection.content)
]))
])
(#set! injection.language "sql"))

28
queries/rust/locals.scm Normal file
View File

@@ -0,0 +1,28 @@
; Scopes
[
(function_item)
(struct_item)
(enum_item)
(union_item)
(type_item)
(trait_item)
(impl_item)
(closure_expression)
(block)
] @local.scope
; Definitions
(function_item
(parameters
(parameter
pattern: (identifier) @local.definition.variable.parameter)))
(closure_parameters (identifier) @local.definition.variable.parameter)
; References
(identifier) @local.reference
; lifetimes / labels
(lifetime (identifier) @label)
(label (identifier) @label)

View File

@@ -0,0 +1,48 @@
; Properties
;-----------
(table [
(bare_key)
(dotted_key)
(quoted_key)
] @type)
(table_array_element [
(bare_key)
(dotted_key)
(quoted_key)
] @type)
(pair [
(bare_key)
(dotted_key)
(quoted_key)
] @variable.other.member)
; Literals
;---------
(boolean) @constant.builtin.boolean
(comment) @comment
(string) @string
(integer) @constant.numeric.integer
(float) @constant.numeric.float
(offset_date_time) @string.special
(local_date_time) @string.special
(local_date) @string.special
(local_time) @string.special
; Punctuation
;------------
"." @punctuation.delimiter
"," @punctuation.delimiter
"=" @operator
"[" @punctuation.bracket
"]" @punctuation.bracket
"[[" @punctuation.bracket
"]]" @punctuation.bracket
"{" @punctuation.bracket
"}" @punctuation.bracket

View File

@@ -0,0 +1,2 @@
((comment) @injection.content
(#set! injection.language "comment"))

View File

@@ -0,0 +1,3 @@
; See runtime/queries/ecma/README.md for more info.
; inherits: ecma,_typescript

View File

@@ -0,0 +1,3 @@
; See runtime/queries/ecma/README.md for more info.
; inherits: _typescript,ecma

View File

@@ -0,0 +1,3 @@
; See runtime/queries/ecma/README.md for more info.
; inherits: _typescript,ecma

View File

@@ -0,0 +1,42 @@
(boolean_scalar) @constant.builtin.boolean
(null_scalar) @constant.builtin
(double_quote_scalar) @string
(single_quote_scalar) @string
(block_scalar) @string
(string_scalar) @string
(escape_sequence) @constant.character.escape
(integer_scalar) @constant.numeric.integer
(float_scalar) @constant.numeric.float
(comment) @comment
(anchor_name) @type
(alias_name) @type
(tag) @type
(yaml_directive) @keyword
(block_mapping_pair
key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member))
(block_mapping_pair
key: (flow_node (plain_scalar (string_scalar) @variable.other.member)))
(flow_mapping
(_ key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member)))
(flow_mapping
(_ key: (flow_node (plain_scalar (string_scalar) @variable.other.member))))
[
","
"-"
":"
">"
"?"
"|"
] @punctuation.delimiter
[
"["
"]"
"{"
"}"
] @punctuation.bracket
["*" "&" "---" "..."] @punctuation.special

View File

@@ -0,0 +1,57 @@
((comment) @injection.content
(#set! injection.language "comment"))
; The following code in this file until the ";;; END nvim-treesitter LICENSED CODE"
; marker incorporates work covered by the following copyright and permission notice:
;
; Copyright 2023 the nvim-treesitter authors
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
; Modified for Helix from https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/yaml/injections.scm
;; GitHub actions: run
;; Buildkite: command, commands
(block_mapping_pair
key: (flow_node) @_run (#any-of? @_run "run" "command" "commands")
value: (flow_node
(plain_scalar
(string_scalar) @injection.content)
(#set! injection.language "bash")))
(block_mapping_pair
key: (flow_node) @_run (#any-of? @_run "run" "command" "commands")
value: (block_node
(block_scalar) @injection.content
(#set! injection.language "bash")))
(block_mapping_pair
key: (flow_node) @_run (#any-of? @_run "run" "command" "commands")
value: (block_node
(block_sequence
(block_sequence_item
(flow_node
(plain_scalar
(string_scalar) @injection.content))
(#set! injection.language "bash")))))
(block_mapping_pair
key: (flow_node) @_run (#any-of? @_run "run" "command" "commands")
value: (block_node
(block_sequence
(block_sequence_item
(block_node
(block_scalar) @injection.content
(#set! injection.language "bash"))))))
;;; END nvim-treesitter LICENSED CODE