Compare commits

..

5 commits

Author SHA1 Message Date
tobjend
70300ff917 chore: add Gemini session chat logs as reference
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2026-07-03 20:48:50 +02:00
tobjend
ee5ebc9eb4 feat: universal AST preprocessor with nvim-treesitter queries
- Replace old per-language query files with unified tag-preprocessor
- Universal preprocessor uses nvim-treesitter highlights.scm for 10 langs
- Resolves ; inherits: directives (ecma, jsx) for JS/TS
- ts-kotlin bundled query for Kotlin compatibility
- Strips unsupported #set! 3-arg predicates for jsx
- archive old community queries
2026-07-03 20:48:47 +02:00
tobjend
986eaa7f83 feat: add community tags findings audit and kotlin tags query 2026-07-03 18:40:53 +02:00
tobjend
8d06ac2d52 chore: add downloaded community queries for kotlin + typescript
Kotlin (fwcd/tree-sitter-kotlin) and TypeScript packages
don't bundle queries. These are downloaded from upstream repos.
2026-07-03 18:05:19 +02:00
tobjend
069c63f2c8 feat: inspect TreeSitter tag queries for Dervish universal AST extraction
- Fetch TAGS_QUERY and HIGHLIGHTS_QUERY from 8 official TreeSitter language packages
- Save all curated queries as .scm files
- Analysis confirms universal query approach is viable
- TreeSitter silently ignores non-existent node types per language
- Add full conversation references (gemini chat markdown files)
- Add comprehensive conversation summary with roadmap
2026-07-03 17:46:33 +02:00
51 changed files with 24998 additions and 0 deletions

View file

View file

@ -0,0 +1,188 @@
"""Universal tree-sitter tag preprocessor.
Usage:
python -m bex.tag-preprocessor.code <file>
Emits an ordered sequence of behavioral tokens using community highlights.scm
queries from nvim-treesitter. One code path for all languages.
"""
import importlib
import os
import re
import sys
from pathlib import Path
from tree_sitter import Language, Parser, Query, QueryCursor
QUERIES_DIR = Path(__file__).parent / "queries"
# (query_name, module_name, func_name)
EXTENSION_MAP = {
".py": ("python", "tree_sitter_python", "language"),
".js": ("javascript", "tree_sitter_javascript", "language"),
".mjs": ("javascript", "tree_sitter_javascript", "language"),
".cjs": ("javascript", "tree_sitter_javascript", "language"),
".ts": ("typescript", "tree_sitter_typescript", "language_typescript"),
".tsx": ("typescript", "tree_sitter_typescript", "language_tsx"),
".rb": ("ruby", "tree_sitter_ruby", "language"),
".go": ("go", "tree_sitter_go", "language"),
".rs": ("rust", "tree_sitter_rust", "language"),
".java": ("java", "tree_sitter_java", "language"),
".kt": ("kotlin", "tree_sitter_kotlin", "language"),
".kts": ("kotlin", "tree_sitter_kotlin", "language"),
".c": ("c", "tree_sitter_c", "language"),
".h": ("c", "tree_sitter_c", "language"),
".cpp": ("cpp", "tree_sitter_cpp", "language"),
".cc": ("cpp", "tree_sitter_cpp", "language"),
".cxx": ("cpp", "tree_sitter_cpp", "language"),
".hpp": ("cpp", "tree_sitter_cpp", "language"),
}
BEHAVIORAL_PREFIXES = (
"definition.",
"reference.",
"keyword.",
"function",
"attribute",
"constructor",
"label",
"type.definition",
"module",
)
_grammar_cache = {}
_query_cache = {}
def _load_grammar(ext):
entry = EXTENSION_MAP.get(ext)
if entry is None:
raise ValueError(f"Unsupported extension: {ext}")
query_name, module_name, func_name = entry
cache_key = f"{module_name}.{func_name}"
if cache_key in _grammar_cache:
return _grammar_cache[cache_key], query_name
mod = importlib.import_module(module_name)
lang = Language(getattr(mod, func_name)())
_grammar_cache[cache_key] = lang
return lang, query_name
INHERIT_RE = re.compile(r"^;\s*inherits:\s*(.+)$", re.MULTILINE)
def _resolve_inherits(src, query_name, seen=None):
if seen is None:
seen = set()
if query_name in seen:
return ""
seen.add(query_name)
qpath = QUERIES_DIR / f"{query_name}.scm"
if not qpath.exists():
return ""
content = qpath.read_text()
m = INHERIT_RE.search(content)
if m:
parents = m.group(1)
parent_parts = []
for parent in parents.split(","):
parent = parent.strip().strip("()")
if parent:
parent_parts.append(_resolve_inherits(parent, parent, seen))
parent_src = "\n".join(p for p in parent_parts if p)
body = INHERIT_RE.sub("", content)
return parent_src + "\n" + body if parent_src else body
return content
def _load_query(query_name):
if query_name in _query_cache:
return _query_cache[query_name]
src = _resolve_inherits(query_name, query_name)
if not src:
raise FileNotFoundError(f"Query file not found: {query_name}")
_query_cache[query_name] = src
return src
def preprocess(file_path: str, code: str):
ext = os.path.splitext(file_path)[1].lower()
lang, query_name = _load_grammar(ext)
query_src = _load_query(query_name)
parser = Parser(lang)
tree = parser.parse(code.encode())
try:
query = Query(lang, query_src)
except Exception as e:
print(f"Query error for {query_name}: {e}", file=sys.stderr)
return
cursor = QueryCursor(query)
captures = cursor.captures(tree.root_node)
items = []
for capname, nodes in captures.items():
if not capname.startswith(BEHAVIORAL_PREFIXES):
continue
for node in nodes:
items.append((node.start_byte, capname, node, code[node.start_byte:node.end_byte].strip()))
items.sort(key=lambda x: x[0])
return [(capname, text, code[:start].count("\n") + 1) for start, capname, _, text in items]
def main():
if len(sys.argv) < 2:
print("Usage: python -m bex.tag-preprocessor.code <file>", file=sys.stderr)
sys.exit(1)
file_path = sys.argv[1]
if not os.path.exists(file_path):
print(f"File not found: {file_path}", file=sys.stderr)
sys.exit(1)
try:
with open(file_path) as f:
code = f.read()
except Exception as e:
print(f"Error reading {file_path}: {e}", file=sys.stderr)
sys.exit(1)
try:
seq = preprocess(file_path, code)
except ValueError as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
except FileNotFoundError as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Error preprocessing {file_path}: {e}", file=sys.stderr)
sys.exit(1)
if not seq:
print("(no behavioral tokens)")
return
print(f"{'CAPTURE':35s} {'TEXT':50s} LINE")
print("-" * 88)
for capname, text, line in seq:
print(f"{capname:35s} '{text[:48]:48s}' L{line}")
print(f"\nSequence ({len(seq)} tokens):")
print(" -> ".join(c for c, _, _ in seq))
if __name__ == "__main__":
main()

View file

@ -0,0 +1,341 @@
; Lower priority to prefer @variable.parameter when identifier appears in parameter_declaration.
((identifier) @variable
(#set! priority 95))
(preproc_def
(preproc_arg) @variable)
[
"default"
"goto"
"asm"
"__asm__"
] @keyword
[
"enum"
"struct"
"union"
"typedef"
] @keyword.type
[
"sizeof"
"offsetof"
] @keyword.operator
(alignof_expression
.
_ @keyword.operator)
"return" @keyword.return
[
"while"
"for"
"do"
"continue"
"break"
] @keyword.repeat
[
"if"
"else"
"case"
"switch"
] @keyword.conditional
[
"#if"
"#ifdef"
"#ifndef"
"#else"
"#elif"
"#endif"
"#elifdef"
"#elifndef"
(preproc_directive)
] @keyword.directive
"#define" @keyword.directive.define
"#include" @keyword.import
[
";"
":"
","
"."
"::"
] @punctuation.delimiter
"..." @punctuation.special
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
[
"="
"-"
"*"
"/"
"+"
"%"
"~"
"|"
"&"
"^"
"<<"
">>"
"->"
"<"
"<="
">="
">"
"=="
"!="
"!"
"&&"
"||"
"-="
"+="
"*="
"/="
"%="
"|="
"&="
"^="
">>="
"<<="
"--"
"++"
] @operator
; Make sure the comma operator is given a highlight group after the comma
; punctuator so the operator is highlighted properly.
(comma_expression
"," @operator)
[
(true)
(false)
] @boolean
(conditional_expression
[
"?"
":"
] @keyword.conditional.ternary)
(string_literal) @string
(system_lib_string) @string
(escape_sequence) @string.escape
(null) @constant.builtin
(number_literal) @number
(char_literal) @character
(preproc_defined) @function.macro
((field_expression
(field_identifier) @property) @_parent
(#not-has-parent? @_parent template_method function_declarator call_expression))
(field_designator) @property
((field_identifier) @property
(#has-ancestor? @property field_declaration)
(#not-has-ancestor? @property function_declarator))
(statement_identifier) @label
(declaration
type: (type_identifier) @_type
declarator: (identifier) @label
(#eq? @_type "__label__"))
[
(type_identifier)
(type_descriptor)
] @type
(storage_class_specifier) @keyword.modifier
[
(type_qualifier)
(gnu_asm_qualifier)
"__extension__"
] @keyword.modifier
(linkage_specification
"extern" @keyword.modifier)
(type_definition
declarator: (type_identifier) @type.definition)
(primitive_type) @type.builtin
(sized_type_specifier
_ @type.builtin
type: _?)
((identifier) @constant
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
(preproc_def
(preproc_arg) @constant
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
(enumerator
name: (identifier) @constant)
(case_statement
value: (identifier) @constant)
((identifier) @constant.builtin
; format-ignore
(#any-of? @constant.builtin
"stderr" "stdin" "stdout"
"__FILE__" "__LINE__" "__DATE__" "__TIME__"
"__STDC__" "__STDC_VERSION__" "__STDC_HOSTED__"
"__cplusplus" "__OBJC__" "__ASSEMBLER__"
"__BASE_FILE__" "__FILE_NAME__" "__INCLUDE_LEVEL__"
"__TIMESTAMP__" "__clang__" "__clang_major__"
"__clang_minor__" "__clang_patchlevel__"
"__clang_version__" "__clang_literal_encoding__"
"__clang_wide_literal_encoding__"
"__FUNCTION__" "__func__" "__PRETTY_FUNCTION__"
"__VA_ARGS__" "__VA_OPT__"))
(preproc_def
(preproc_arg) @constant.builtin
; format-ignore
(#any-of? @constant.builtin
"stderr" "stdin" "stdout"
"__FILE__" "__LINE__" "__DATE__" "__TIME__"
"__STDC__" "__STDC_VERSION__" "__STDC_HOSTED__"
"__cplusplus" "__OBJC__" "__ASSEMBLER__"
"__BASE_FILE__" "__FILE_NAME__" "__INCLUDE_LEVEL__"
"__TIMESTAMP__" "__clang__" "__clang_major__"
"__clang_minor__" "__clang_patchlevel__"
"__clang_version__" "__clang_literal_encoding__"
"__clang_wide_literal_encoding__"
"__FUNCTION__" "__func__" "__PRETTY_FUNCTION__"
"__VA_ARGS__" "__VA_OPT__"))
(attribute_specifier
(argument_list
(identifier) @variable.builtin))
(attribute_specifier
(argument_list
(call_expression
function: (identifier) @variable.builtin)))
((call_expression
function: (identifier) @function.builtin)
(#lua-match? @function.builtin "^__builtin_"))
((call_expression
function: (identifier) @function.builtin)
(#has-ancestor? @function.builtin attribute_specifier))
; Preproc def / undef
(preproc_def
name: (_) @constant.macro)
(preproc_call
directive: (preproc_directive) @_u
argument: (_) @constant.macro
(#eq? @_u "#undef"))
(preproc_ifdef
name: (identifier) @constant.macro)
(preproc_elifdef
name: (identifier) @constant.macro)
(preproc_defined
(identifier) @constant.macro)
(call_expression
function: (identifier) @function.call)
(call_expression
function: (field_expression
field: (field_identifier) @function.call))
(function_declarator
declarator: (identifier) @function)
(function_declarator
declarator: (parenthesized_declarator
(pointer_declarator
declarator: (field_identifier) @function)))
(preproc_function_def
name: (identifier) @function.macro)
(comment) @comment @spell
((comment) @comment.documentation
(#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$"))
; Parameters
(parameter_declaration
declarator: (identifier) @variable.parameter)
(parameter_declaration
declarator: (array_declarator) @variable.parameter)
(parameter_declaration
declarator: (pointer_declarator) @variable.parameter)
; K&R functions
; To enable support for K&R functions,
; add the following lines to your own query config and uncomment them.
; They are commented out as they'll conflict with C++
; Note that you'll need to have `; extends` at the top of your query file.
;
; (parameter_list (identifier) @variable.parameter)
;
; (function_definition
; declarator: _
; (declaration
; declarator: (identifier) @variable.parameter))
;
; (function_definition
; declarator: _
; (declaration
; declarator: (array_declarator) @variable.parameter))
;
; (function_definition
; declarator: _
; (declaration
; declarator: (pointer_declarator) @variable.parameter))
(preproc_params
(identifier) @variable.parameter)
[
"__attribute__"
"__declspec"
"__based"
"__cdecl"
"__clrcall"
"__stdcall"
"__fastcall"
"__thiscall"
"__vectorcall"
(ms_pointer_modifier)
(attribute_declaration)
] @attribute

View file

@ -0,0 +1,268 @@
; inherits: c
((identifier) @variable.member
(#lua-match? @variable.member "^m_.*$"))
(parameter_declaration
declarator: (reference_declarator) @variable.parameter)
; function(Foo ...foo)
(variadic_parameter_declaration
declarator: (variadic_declarator
(_) @variable.parameter))
; int foo = 0
(optional_parameter_declaration
declarator: (_) @variable.parameter)
;(field_expression) @variable.parameter ;; How to highlight this?
((field_expression
(field_identifier) @function.method) @_parent
(#has-parent? @_parent template_method function_declarator))
(field_declaration
(field_identifier) @variable.member)
(field_initializer
(field_identifier) @property)
(function_declarator
declarator: (field_identifier) @function.method)
(concept_definition
name: (identifier) @type.definition)
(alias_declaration
name: (type_identifier) @type.definition)
(auto) @type.builtin
(namespace_identifier) @module
((namespace_identifier) @type
(#lua-match? @type "^[%u]"))
(case_statement
value: (qualified_identifier
(identifier) @constant))
(using_declaration
.
"using"
.
"namespace"
.
[
(qualified_identifier)
(identifier)
] @module)
(destructor_name
(identifier) @function.method)
; functions
(function_declarator
(qualified_identifier
(identifier) @function))
(function_declarator
(qualified_identifier
(qualified_identifier
(identifier) @function)))
(function_declarator
(qualified_identifier
(qualified_identifier
(qualified_identifier
(identifier) @function))))
((qualified_identifier
(qualified_identifier
(qualified_identifier
(qualified_identifier
(identifier) @function)))) @_parent
(#has-ancestor? @_parent function_declarator))
(function_declarator
(template_function
(identifier) @function))
(operator_name) @function
"operator" @function
"static_assert" @function.builtin
(call_expression
(qualified_identifier
(identifier) @function.call))
(call_expression
(qualified_identifier
(qualified_identifier
(identifier) @function.call)))
(call_expression
(qualified_identifier
(qualified_identifier
(qualified_identifier
(identifier) @function.call))))
((qualified_identifier
(qualified_identifier
(qualified_identifier
(qualified_identifier
(identifier) @function.call)))) @_parent
(#has-ancestor? @_parent call_expression))
(call_expression
(template_function
(identifier) @function.call))
(call_expression
(qualified_identifier
(template_function
(identifier) @function.call)))
(call_expression
(qualified_identifier
(qualified_identifier
(template_function
(identifier) @function.call))))
(call_expression
(qualified_identifier
(qualified_identifier
(qualified_identifier
(template_function
(identifier) @function.call)))))
((qualified_identifier
(qualified_identifier
(qualified_identifier
(qualified_identifier
(template_function
(identifier) @function.call))))) @_parent
(#has-ancestor? @_parent call_expression))
; methods
(function_declarator
(template_method
(field_identifier) @function.method))
(call_expression
(field_expression
(field_identifier) @function.method.call))
; constructors
((function_declarator
(qualified_identifier
(identifier) @constructor))
(#lua-match? @constructor "^%u"))
((call_expression
function: (identifier) @constructor)
(#lua-match? @constructor "^%u"))
((call_expression
function: (qualified_identifier
name: (identifier) @constructor))
(#lua-match? @constructor "^%u"))
((call_expression
function: (field_expression
field: (field_identifier) @constructor))
(#lua-match? @constructor "^%u"))
; constructing a type in an initializer list: Constructor (): **SuperType (1)**
((field_initializer
(field_identifier) @constructor
(argument_list))
(#lua-match? @constructor "^%u"))
; Constants
(this) @variable.builtin
(null
"nullptr" @constant.builtin)
(true) @boolean
(false) @boolean
; Literals
(raw_string_literal) @string
; Keywords
[
"try"
"catch"
"noexcept"
"throw"
] @keyword.exception
[
"decltype"
"explicit"
"friend"
"override"
"using"
"requires"
"constexpr"
] @keyword
[
"class"
"namespace"
"template"
"typename"
"concept"
] @keyword.type
[
"co_await"
"co_yield"
"co_return"
] @keyword.coroutine
[
"public"
"private"
"protected"
"final"
"virtual"
] @keyword.modifier
[
"new"
"delete"
"xor"
"bitand"
"bitor"
"compl"
"not"
"xor_eq"
"and_eq"
"or_eq"
"not_eq"
"and"
"or"
] @keyword.operator
"<=>" @operator
"::" @punctuation.delimiter
(template_argument_list
[
"<"
">"
] @punctuation.bracket)
(template_parameter_list
[
"<"
">"
] @punctuation.bracket)
(literal_suffix) @operator

View file

@ -0,0 +1,254 @@
; Forked from tree-sitter-go
; Copyright (c) 2014 Max Brunsfeld (The MIT License)
;
; Identifiers
(type_identifier) @type
(type_spec
name: (type_identifier) @type.definition)
(field_identifier) @property
(identifier) @variable
(package_identifier) @module
(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)
(call_expression
function: (selector_expression
field: (field_identifier) @function.method.call))
; Function definitions
(function_declaration
name: (identifier) @function)
(method_declaration
name: (field_identifier) @function.method)
(method_elem
name: (field_identifier) @function.method)
; Constructors
((call_expression
(identifier) @constructor)
(#lua-match? @constructor "^[nN]ew.+$"))
((call_expression
(identifier) @constructor)
(#lua-match? @constructor "^[mM]ake.+$"))
; Operators
[
"--"
"-"
"-="
":="
"!"
"!="
"..."
"*"
"*"
"*="
"/"
"/="
"&"
"&&"
"&="
"&^"
"&^="
"%"
"%="
"^"
"^="
"+"
"++"
"+="
"<-"
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"|"
"|="
"||"
"~"
] @operator
; Keywords
[
"break"
"const"
"continue"
"default"
"defer"
"goto"
"range"
"select"
"var"
"fallthrough"
] @keyword
[
"type"
"struct"
"interface"
] @keyword.type
"func" @keyword.function
"return" @keyword.return
"go" @keyword.coroutine
"for" @keyword.repeat
[
"import"
"package"
] @keyword.import
[
"else"
"case"
"switch"
"if"
] @keyword.conditional
; Builtin types
[
"chan"
"map"
] @type.builtin
((type_identifier) @type.builtin
(#any-of? @type.builtin
"any" "bool" "byte" "comparable" "complex128" "complex64" "error" "float32" "float64" "int"
"int16" "int32" "int64" "int8" "rune" "string" "uint" "uint16" "uint32" "uint64" "uint8"
"uintptr"))
; Builtin functions
((identifier) @function.builtin
(#any-of? @function.builtin
"append" "cap" "clear" "close" "complex" "copy" "delete" "imag" "len" "make" "max" "min" "new"
"panic" "print" "println" "real" "recover"))
; Delimiters
"." @punctuation.delimiter
"," @punctuation.delimiter
":" @punctuation.delimiter
";" @punctuation.delimiter
"(" @punctuation.bracket
")" @punctuation.bracket
"{" @punctuation.bracket
"}" @punctuation.bracket
"[" @punctuation.bracket
"]" @punctuation.bracket
; Literals
(interpreted_string_literal) @string
(raw_string_literal) @string
(rune_literal) @string
(escape_sequence) @string.escape
(int_literal) @number
(float_literal) @number.float
(imaginary_literal) @number
[
(true)
(false)
] @boolean
[
(nil)
(iota)
] @constant.builtin
(keyed_element
.
(literal_element
(identifier) @variable.member))
(field_declaration
name: (field_identifier) @variable.member)
; Comments
(comment) @comment @spell
; Doc Comments
(source_file
.
(comment)+ @comment.documentation)
(source_file
(comment)+ @comment.documentation
.
(const_declaration))
(source_file
(comment)+ @comment.documentation
.
(function_declaration))
(source_file
(comment)+ @comment.documentation
.
(type_declaration))
(source_file
(comment)+ @comment.documentation
.
(var_declaration))
; Spell
((interpreted_string_literal) @spell
(#not-has-parent? @spell import_spec))
; Regex
(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
(raw_string_literal_content) @string.regexp)
(interpreted_string_literal
(interpreted_string_literal_content) @string.regexp)
]))

View file

@ -0,0 +1,330 @@
; CREDITS @maxbrunsfeld (maxbrunsfeld@gmail.com)
; Variables
(identifier) @variable
(underscore_pattern) @character.special
; Methods
(method_declaration
name: (identifier) @function.method)
(method_invocation
name: (identifier) @function.method.call)
(super) @function.builtin
; Parameters
(formal_parameter
name: (identifier) @variable.parameter)
(spread_parameter
(variable_declarator
name: (identifier) @variable.parameter)) ; int... foo
; Lambda parameter
(inferred_parameters
(identifier) @variable.parameter) ; (x,y) -> ...
(lambda_expression
parameters: (identifier) @variable.parameter) ; x -> ...
; Operators
[
"+"
":"
"++"
"-"
"--"
"&"
"&&"
"|"
"||"
"!"
"!="
"=="
"*"
"/"
"%"
"<"
"<="
">"
">="
"="
"-="
"+="
"*="
"/="
"%="
"->"
"^"
"^="
"&="
"|="
"~"
">>"
">>>"
"<<"
"::"
] @operator
; Types
(interface_declaration
name: (identifier) @type)
(annotation_type_declaration
name: (identifier) @type)
(class_declaration
name: (identifier) @type)
(record_declaration
name: (identifier) @type)
(enum_declaration
name: (identifier) @type)
(constructor_declaration
name: (identifier) @type)
(compact_constructor_declaration
name: (identifier) @type)
(type_identifier) @type
((type_identifier) @type.builtin
(#eq? @type.builtin "var"))
((method_invocation
object: (identifier) @type)
(#lua-match? @type "^[A-Z]"))
((method_reference
.
(identifier) @type)
(#lua-match? @type "^[A-Z]"))
((field_access
object: (identifier) @type)
(#lua-match? @type "^[A-Z]"))
(scoped_identifier
(identifier) @type
(#lua-match? @type "^[A-Z]"))
; Fields
(field_declaration
declarator: (variable_declarator
name: (identifier) @variable.member))
(field_access
field: (identifier) @variable.member)
[
(boolean_type)
(integral_type)
(floating_point_type)
(void_type)
] @type.builtin
; Variables
((identifier) @constant
(#lua-match? @constant "^[A-Z_][A-Z%d_]+$"))
(this) @variable.builtin
; Annotations
(annotation
"@" @attribute
name: (identifier) @attribute)
(marker_annotation
"@" @attribute
name: (identifier) @attribute)
; Literals
(string_literal) @string
(escape_sequence) @string.escape
(character_literal) @character
[
(hex_integer_literal)
(decimal_integer_literal)
(octal_integer_literal)
(binary_integer_literal)
] @number
[
(decimal_floating_point_literal)
(hex_floating_point_literal)
] @number.float
[
(true)
(false)
] @boolean
(null_literal) @constant.builtin
; Keywords
[
"assert"
"default"
"extends"
"implements"
"instanceof"
"@interface"
"permits"
"to"
"with"
] @keyword
[
"record"
"class"
"enum"
"interface"
] @keyword.type
(synchronized_statement
"synchronized" @keyword)
[
"abstract"
"final"
"native"
"non-sealed"
"open"
"private"
"protected"
"public"
"sealed"
"static"
"strictfp"
"transitive"
] @keyword.modifier
(modifiers
"synchronized" @keyword.modifier)
[
"transient"
"volatile"
] @keyword.modifier
[
"return"
"yield"
] @keyword.return
"new" @keyword.operator
; Conditionals
[
"if"
"else"
"switch"
"case"
"when"
] @keyword.conditional
(ternary_expression
[
"?"
":"
] @keyword.conditional.ternary)
; Loops
[
"for"
"while"
"do"
"continue"
"break"
] @keyword.repeat
; Includes
[
"exports"
"import"
"module"
"opens"
"package"
"provides"
"requires"
"uses"
] @keyword.import
(import_declaration
(asterisk
"*" @character.special))
; Punctuation
[
";"
"."
"..."
","
] @punctuation.delimiter
[
"{"
"}"
] @punctuation.bracket
[
"["
"]"
] @punctuation.bracket
[
"("
")"
] @punctuation.bracket
(type_arguments
[
"<"
">"
] @punctuation.bracket)
(type_parameters
[
"<"
">"
] @punctuation.bracket)
(string_interpolation
[
"\\{"
"}"
] @punctuation.special)
; Exceptions
[
"throw"
"throws"
"finally"
"try"
"catch"
] @keyword.exception
; Labels
(labeled_statement
(identifier) @label)
; Comments
[
(line_comment)
(block_comment)
] @comment @spell
((block_comment) @comment.documentation
(#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$"))
((line_comment) @comment.documentation
(#lua-match? @comment.documentation "^///[^/]"))
((line_comment) @comment.documentation
(#lua-match? @comment.documentation "^///$"))

View file

@ -0,0 +1,56 @@
; inherits: ecma,jsx
; Parameters
(formal_parameters
(identifier) @variable.parameter)
(formal_parameters
(rest_pattern
(identifier) @variable.parameter))
; ({ a }) => null
(formal_parameters
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter))
; ({ a = b }) => null
(formal_parameters
(object_pattern
(object_assignment_pattern
(shorthand_property_identifier_pattern) @variable.parameter)))
; ({ a: b }) => null
(formal_parameters
(object_pattern
(pair_pattern
value: (identifier) @variable.parameter)))
; ([ a ]) => null
(formal_parameters
(array_pattern
(identifier) @variable.parameter))
; ({ a } = { a }) => null
(formal_parameters
(assignment_pattern
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter)))
; ({ a = b } = { a }) => null
(formal_parameters
(assignment_pattern
(object_pattern
(object_assignment_pattern
(shorthand_property_identifier_pattern) @variable.parameter))))
; a => null
(arrow_function
parameter: (identifier) @variable.parameter)
; optional parameters
(formal_parameters
(assignment_pattern
left: (identifier) @variable.parameter))
; punctuation
(optional_chain) @punctuation.delimiter

View file

@ -0,0 +1,398 @@
; Identifiers
(simple_identifier) @variable
; `it` keyword inside lambdas
; FIXME: This will highlight the keyword outside of lambdas since tree-sitter
; does not allow us to check for arbitrary nestation
((simple_identifier) @variable.builtin
(#eq? @variable.builtin "it"))
; `field` keyword inside property getter/setter
; FIXME: This will highlight the keyword outside of getters and setters
; since tree-sitter does not allow us to check for arbitrary nestation
((simple_identifier) @variable.builtin
(#eq? @variable.builtin "field"))
[
"this"
"super"
"this@"
"super@"
] @variable.builtin
; NOTE: for consistency with "super@"
(super_expression
"@" @variable.builtin)
(class_parameter
(simple_identifier) @variable.member)
; NOTE: temporary fix for treesitter bug that causes delay in file opening
;(class_body
; (property_declaration
; (variable_declaration
; (simple_identifier) @variable.member)))
; id_1.id_2.id_3: `id_2` and `id_3` are assumed as object properties
(_
(navigation_suffix
(simple_identifier) @variable.member))
; SCREAMING CASE identifiers are assumed to be constants
((simple_identifier) @constant
(#lua-match? @constant "^[A-Z][A-Z0-9_]*$"))
(_
(navigation_suffix
(simple_identifier) @constant
(#lua-match? @constant "^[A-Z][A-Z0-9_]*$")))
(enum_entry
(simple_identifier) @constant)
(type_identifier) @type
; '?' operator, replacement for Java @Nullable
(nullable_type) @punctuation.special
(type_alias
(type_identifier) @type.definition)
((type_identifier) @type.builtin
(#any-of? @type.builtin
"Byte" "Short" "Int" "Long" "UByte" "UShort" "UInt" "ULong" "Float" "Double" "Boolean" "Char"
"String" "Array" "ByteArray" "ShortArray" "IntArray" "LongArray" "UByteArray" "UShortArray"
"UIntArray" "ULongArray" "FloatArray" "DoubleArray" "BooleanArray" "CharArray" "Map" "Set"
"List" "EmptyMap" "EmptySet" "EmptyList" "MutableMap" "MutableSet" "MutableList"))
(package_header
"package" @keyword
.
(identifier
(simple_identifier) @module))
(import_header
"import" @keyword.import)
(wildcard_import) @character.special
; The last `simple_identifier` in a `import_header` will always either be a function
; or a type. Classes can appear anywhere in the import path, unlike functions
(import_header
(identifier
(simple_identifier) @type @_import)
(import_alias
(type_identifier) @type.definition)?
(#lua-match? @_import "^[A-Z]"))
(import_header
(identifier
(simple_identifier) @function @_import .)
(import_alias
(type_identifier) @function)?
(#lua-match? @_import "^[a-z]"))
(label) @label
; Function definitions
(function_declaration
(simple_identifier) @function)
(getter
"get" @function.builtin)
(setter
"set" @function.builtin)
(primary_constructor) @constructor
(secondary_constructor
"constructor" @constructor)
(constructor_invocation
(user_type
(type_identifier) @constructor))
(anonymous_initializer
"init" @constructor)
(parameter
(simple_identifier) @variable.parameter)
(parameter_with_optional_type
(simple_identifier) @variable.parameter)
; lambda parameters
(lambda_literal
(lambda_parameters
(variable_declaration
(simple_identifier) @variable.parameter)))
; Function calls
; function()
(call_expression
.
(simple_identifier) @function.call)
; ::function
(callable_reference
.
(simple_identifier) @function.call)
; object.function() or object.property.function()
(call_expression
(navigation_expression
(navigation_suffix
(simple_identifier) @function.call) .))
(call_expression
.
(simple_identifier) @function.builtin
(#any-of? @function.builtin
"arrayOf" "arrayOfNulls" "byteArrayOf" "shortArrayOf" "intArrayOf" "longArrayOf" "ubyteArrayOf"
"ushortArrayOf" "uintArrayOf" "ulongArrayOf" "floatArrayOf" "doubleArrayOf" "booleanArrayOf"
"charArrayOf" "emptyArray" "mapOf" "setOf" "listOf" "emptyMap" "emptySet" "emptyList"
"mutableMapOf" "mutableSetOf" "mutableListOf" "print" "println" "error" "TODO" "run"
"runCatching" "repeat" "lazy" "lazyOf" "enumValues" "enumValueOf" "assert" "check"
"checkNotNull" "require" "requireNotNull" "with" "suspend" "synchronized"))
; Literals
[
(line_comment)
(multiline_comment)
] @comment @spell
((multiline_comment) @comment.documentation
(#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$"))
(shebang_line) @keyword.directive
(real_literal) @number.float
[
(integer_literal)
(long_literal)
(hex_literal)
(bin_literal)
(unsigned_literal)
] @number
[
(null_literal)
; should be highlighted the same as booleans
(boolean_literal)
] @boolean
(character_literal) @character
(string_literal) @string
; NOTE: Escapes not allowed in multi-line strings
(character_literal
(character_escape_seq) @string.escape)
; There are 3 ways to define a regex
; - "[abc]?".toRegex()
(call_expression
(navigation_expression
(string_literal) @string.regexp
(navigation_suffix
((simple_identifier) @_function
(#eq? @_function "toRegex")))))
; - Regex("[abc]?")
(call_expression
((simple_identifier) @_function
(#eq? @_function "Regex"))
(call_suffix
(value_arguments
(value_argument
(string_literal) @string.regexp))))
; - Regex.fromLiteral("[abc]?")
(call_expression
(navigation_expression
((simple_identifier) @_class
(#eq? @_class "Regex"))
(navigation_suffix
((simple_identifier) @_function
(#eq? @_function "fromLiteral"))))
(call_suffix
(value_arguments
(value_argument
(string_literal) @string.regexp))))
; Keywords
(type_alias
"typealias" @keyword)
(companion_object
"companion" @keyword)
[
(class_modifier)
(member_modifier)
(function_modifier)
(property_modifier)
(platform_modifier)
(variance_modifier)
(parameter_modifier)
(visibility_modifier)
(reification_modifier)
(inheritance_modifier)
] @keyword.modifier
[
"val"
"var"
; "typeof" ; NOTE: It is reserved for future use
] @keyword
[
"enum"
"class"
"object"
"interface"
] @keyword.type
[
"return"
"return@"
] @keyword.return
"suspend" @keyword.coroutine
"fun" @keyword.function
[
"if"
"else"
"when"
] @keyword.conditional
[
"for"
"do"
"while"
"continue"
"continue@"
"break"
"break@"
] @keyword.repeat
[
"try"
"catch"
"throw"
"finally"
] @keyword.exception
(annotation
"@" @attribute
(use_site_target)? @attribute)
(annotation
(user_type
(type_identifier) @attribute))
(annotation
(constructor_invocation
(user_type
(type_identifier) @attribute)))
(file_annotation
"@" @attribute
"file" @attribute
":" @attribute)
(file_annotation
(user_type
(type_identifier) @attribute))
(file_annotation
(constructor_invocation
(user_type
(type_identifier) @attribute)))
; Operators & Punctuation
[
"!"
"!="
"!=="
"="
"=="
"==="
">"
">="
"<"
"<="
"||"
"&&"
"+"
"++"
"+="
"-"
"--"
"-="
"*"
"*="
"/"
"/="
"%"
"%="
"?."
"?:"
"!!"
"is"
"!is"
"in"
"!in"
"as"
"as?"
".."
"->"
] @operator
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
[
"."
","
";"
":"
"::"
] @punctuation.delimiter
(super_expression
[
"<"
">"
] @punctuation.delimiter)
(type_arguments
[
"<"
">"
] @punctuation.delimiter)
(type_parameters
[
"<"
">"
] @punctuation.delimiter)
; NOTE: `interpolated_identifier`s can be highlighted in any way
(string_literal
"$" @punctuation.special
(interpolated_identifier) @none @variable)
(string_literal
"${" @punctuation.special
(interpolated_expression) @none
"}" @punctuation.special)

View file

@ -0,0 +1,443 @@
; From tree-sitter-python licensed under MIT License
; Copyright (c) 2016 Max Brunsfeld
; Variables
(identifier) @variable
; Reset highlighting in f-string interpolations
(interpolation) @none
; Identifier naming conventions
((identifier) @type
(#lua-match? @type "^[A-Z].*[a-z]"))
((identifier) @constant
(#lua-match? @constant "^[A-Z][A-Z_0-9]*$"))
((identifier) @constant.builtin
(#lua-match? @constant.builtin "^__[a-zA-Z0-9_]*__$"))
((identifier) @constant.builtin
(#any-of? @constant.builtin
; https://docs.python.org/3/library/constants.html
"NotImplemented" "Ellipsis" "quit" "exit" "copyright" "credits" "license"))
"_" @character.special ; match wildcard
((assignment
left: (identifier) @type.definition
(type
(identifier) @_annotation))
(#eq? @_annotation "TypeAlias"))
((assignment
left: (identifier) @type.definition
right: (call
function: (identifier) @_func))
(#any-of? @_func "TypeVar" "NewType"))
; Function definitions
(function_definition
name: (identifier) @function)
(type
(identifier) @type)
(type
(subscript
(identifier) @type)) ; type subscript: Tuple[int]
((call
function: (identifier) @_isinstance
arguments: (argument_list
(_)
(identifier) @type))
(#eq? @_isinstance "isinstance"))
; Literals
(none) @constant.builtin
[
(true)
(false)
] @boolean
(integer) @number
(float) @number.float
(comment) @comment @spell
((module
.
(comment) @keyword.directive @nospell)
(#lua-match? @keyword.directive "^#!/"))
(string) @string
[
(escape_sequence)
(escape_interpolation)
] @string.escape
; doc-strings
(expression_statement
(string
(string_content) @spell) @string.documentation)
; Tokens
[
"-"
"-="
":="
"!="
"*"
"**"
"**="
"*="
"/"
"//"
"//="
"/="
"&"
"&="
"%"
"%="
"^"
"^="
"+"
"+="
"<"
"<<"
"<<="
"<="
"<>"
"="
"=="
">"
">="
">>"
">>="
"@"
"@="
"|"
"|="
"~"
"->"
] @operator
; Keywords
[
"and"
"in"
"is"
"not"
"or"
"is not"
"not in"
"del"
] @keyword.operator
[
"def"
"lambda"
] @keyword.function
[
"assert"
"exec"
"global"
"nonlocal"
"pass"
"print"
"with"
"as"
] @keyword
[
"type"
"class"
] @keyword.type
[
"async"
"await"
] @keyword.coroutine
[
"return"
"yield"
] @keyword.return
(yield
"from" @keyword.return)
(future_import_statement
"from" @keyword.import
"__future__" @module.builtin)
(import_from_statement
"from" @keyword.import)
"import" @keyword.import
(aliased_import
"as" @keyword.import)
(wildcard_import
"*" @character.special)
(import_statement
name: (dotted_name
(identifier) @module))
(import_statement
name: (aliased_import
name: (dotted_name
(identifier) @module)
alias: (identifier) @module))
(import_from_statement
module_name: (dotted_name
(identifier) @module))
(import_from_statement
module_name: (relative_import
(dotted_name
(identifier) @module)))
[
"if"
"elif"
"else"
"match"
"case"
] @keyword.conditional
[
"for"
"while"
"break"
"continue"
] @keyword.repeat
[
"try"
"except"
"except*"
"raise"
"finally"
] @keyword.exception
(raise_statement
"from" @keyword.exception)
(try_statement
(else_clause
"else" @keyword.exception))
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
(interpolation
"{" @punctuation.special
"}" @punctuation.special)
(type_conversion) @function.macro
[
","
"."
":"
";"
(ellipsis)
] @punctuation.delimiter
((identifier) @type.builtin
(#any-of? @type.builtin
; https://docs.python.org/3/library/exceptions.html
"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"
; https://docs.python.org/3/library/stdtypes.html
"bool" "int" "float" "complex" "list" "tuple" "range" "str" "bytes" "bytearray" "memoryview"
"set" "frozenset" "dict" "type" "object"))
; Normal parameters
(parameters
(identifier) @variable.parameter)
; Lambda parameters
(lambda_parameters
(identifier) @variable.parameter)
(lambda_parameters
(tuple_pattern
(identifier) @variable.parameter))
; Default parameters
(keyword_argument
name: (identifier) @variable.parameter)
; Naming parameters on call-site
(default_parameter
name: (identifier) @variable.parameter)
(typed_parameter
(identifier) @variable.parameter)
(typed_default_parameter
name: (identifier) @variable.parameter)
; Variadic parameters *args, **kwargs
(parameters
(list_splat_pattern ; *args
(identifier) @variable.parameter))
(parameters
(dictionary_splat_pattern ; **kwargs
(identifier) @variable.parameter))
; Typed variadic parameters
(parameters
(typed_parameter
(list_splat_pattern ; *args: type
(identifier) @variable.parameter)))
(parameters
(typed_parameter
(dictionary_splat_pattern ; *kwargs: type
(identifier) @variable.parameter)))
; Lambda parameters
(lambda_parameters
(list_splat_pattern
(identifier) @variable.parameter))
(lambda_parameters
(dictionary_splat_pattern
(identifier) @variable.parameter))
((identifier) @variable.builtin
(#eq? @variable.builtin "self"))
((identifier) @variable.builtin
(#eq? @variable.builtin "cls"))
; After @type.builtin bacause builtins (such as `type`) are valid as attribute name
((attribute
attribute: (identifier) @variable.member)
(#lua-match? @variable.member "^[%l_].*$"))
; Class definitions
(class_definition
name: (identifier) @type)
(class_definition
body: (block
(function_definition
name: (identifier) @function.method)))
(class_definition
superclasses: (argument_list
(identifier) @type))
((class_definition
body: (block
(expression_statement
(assignment
left: (identifier) @variable.member))))
(#lua-match? @variable.member "^[%l_].*$"))
((class_definition
body: (block
(expression_statement
(assignment
left: (_
(identifier) @variable.member)))))
(#lua-match? @variable.member "^[%l_].*$"))
((class_definition
(block
(function_definition
name: (identifier) @constructor)))
(#any-of? @constructor "__new__" "__init__"))
; Function calls
(call
function: (identifier) @function.call)
(call
function: (attribute
attribute: (identifier) @function.method.call))
((call
function: (identifier) @constructor)
(#lua-match? @constructor "^%u"))
((call
function: (attribute
attribute: (identifier) @constructor))
(#lua-match? @constructor "^%u"))
; Builtin functions
((call
function: (identifier) @function.builtin)
(#any-of? @function.builtin
"abs" "all" "any" "ascii" "bin" "bool" "breakpoint" "bytearray" "bytes" "callable" "chr"
"classmethod" "compile" "complex" "delattr" "dict" "dir" "divmod" "enumerate" "eval" "exec"
"filter" "float" "format" "frozenset" "getattr" "globals" "hasattr" "hash" "help" "hex" "id"
"input" "int" "isinstance" "issubclass" "iter" "len" "list" "locals" "map" "max" "memoryview"
"min" "next" "object" "oct" "open" "ord" "pow" "print" "property" "range" "repr" "reversed"
"round" "set" "setattr" "slice" "sorted" "staticmethod" "str" "sum" "super" "tuple" "type"
"vars" "zip" "__import__"))
; Regex from the `re` module
(call
function: (attribute
object: (identifier) @_re)
arguments: (argument_list
.
(string
(string_content) @string.regexp))
(#eq? @_re "re"))
; Decorators
((decorator
"@" @attribute)
(#set! priority 101))
(decorator
(identifier) @attribute)
(decorator
(attribute
attribute: (identifier) @attribute))
(decorator
(call
(identifier) @attribute))
(decorator
(call
(attribute
attribute: (identifier) @attribute)))
((decorator
(identifier) @attribute.builtin)
(#any-of? @attribute.builtin "classmethod" "property" "staticmethod"))

View file

@ -0,0 +1,309 @@
; Variables
[
(identifier)
(global_variable)
] @variable
; Keywords
[
"alias"
"begin"
"do"
"end"
"ensure"
"module"
"rescue"
"then"
] @keyword
"class" @keyword.type
[
"return"
"yield"
] @keyword.return
[
"and"
"or"
"in"
"not"
] @keyword.operator
[
"def"
"undef"
] @keyword.function
(method
"end" @keyword.function)
[
"case"
"else"
"elsif"
"if"
"unless"
"when"
"then"
] @keyword.conditional
(if
"end" @keyword.conditional)
[
"for"
"until"
"while"
"break"
"redo"
"retry"
"next"
] @keyword.repeat
(constant) @constant
((identifier) @keyword.modifier
(#any-of? @keyword.modifier "private" "protected" "public"))
[
"rescue"
"ensure"
] @keyword.exception
; Function calls
"defined?" @function
(call
receiver: (constant)? @type
method: [
(identifier)
(constant)
] @function.call)
(program
(call
(identifier) @keyword.import)
(#any-of? @keyword.import "require" "require_relative" "load"))
; Function definitions
(alias
(identifier) @function)
(setter
(identifier) @function)
(method
name: [
(identifier) @function
(constant) @type
])
(singleton_method
name: [
(identifier) @function
(constant) @type
])
(class
name: (constant) @type)
(module
name: (constant) @type)
(superclass
(constant) @type)
; Identifiers
[
(class_variable)
(instance_variable)
] @variable.member
((identifier) @constant.builtin
(#any-of? @constant.builtin
"__callee__" "__dir__" "__id__" "__method__" "__send__" "__ENCODING__" "__FILE__" "__LINE__"))
((identifier) @function.builtin
(#any-of? @function.builtin "attr_reader" "attr_writer" "attr_accessor" "module_function"))
((call
!receiver
method: (identifier) @function.builtin)
(#any-of? @function.builtin "include" "extend" "prepend" "refine" "using"))
((identifier) @keyword.exception
(#any-of? @keyword.exception "raise" "fail" "catch" "throw"))
((constant) @type
(#not-lua-match? @type "^[A-Z0-9_]+$"))
[
(self)
(super)
] @variable.builtin
(method_parameters
(identifier) @variable.parameter)
(lambda_parameters
(identifier) @variable.parameter)
(block_parameters
(identifier) @variable.parameter)
(splat_parameter
(identifier) @variable.parameter)
(hash_splat_parameter
(identifier) @variable.parameter)
(optional_parameter
(identifier) @variable.parameter)
(destructured_parameter
(identifier) @variable.parameter)
(block_parameter
(identifier) @variable.parameter)
(keyword_parameter
(identifier) @variable.parameter)
; TODO: Re-enable this once it is supported
; ((identifier) @function
; (#is-not? local))
; Literals
[
(string_content)
(heredoc_content)
"\""
"`"
] @string
[
(heredoc_beginning)
(heredoc_end)
] @label
[
(bare_symbol)
(simple_symbol)
(delimited_symbol)
(hash_key_symbol)
] @string.special.symbol
(regex
(string_content) @string.regexp)
(escape_sequence) @string.escape
(integer) @number
(float) @number.float
[
(true)
(false)
] @boolean
(nil) @constant.builtin
(comment) @comment @spell
((program
.
(comment) @keyword.directive @nospell)
(#lua-match? @keyword.directive "^#!/"))
(program
(comment)+ @comment.documentation
(class))
(module
(comment)+ @comment.documentation
(body_statement
(class)))
(class
(comment)+ @comment.documentation
(body_statement
(method)))
(body_statement
(comment)+ @comment.documentation
(method))
; Operators
[
"!"
"="
"=="
"==="
"<=>"
"=>"
"->"
">>"
"<<"
">"
"<"
">="
"<="
"**"
"*"
"/"
"%"
"+"
"-"
"&"
"|"
"^"
"&&"
"||"
"||="
"&&="
"!="
"%="
"+="
"-="
"*="
"/="
"=~"
"!~"
"?"
":"
".."
"..."
] @operator
[
","
";"
"."
"&."
"::"
] @punctuation.delimiter
(regex
"/" @punctuation.bracket)
(pair
":" @punctuation.delimiter)
[
"("
")"
"["
"]"
"{"
"}"
"%w("
"%i("
] @punctuation.bracket
(block_parameters
"|" @punctuation.bracket)
(interpolation
"#{" @punctuation.special
"}" @punctuation.special)

View file

@ -0,0 +1,531 @@
; Forked from https://github.com/tree-sitter/tree-sitter-rust
; Copyright (c) 2017 Maxim Sokolov
; Licensed under the MIT license.
; Identifier conventions
(shebang) @keyword.directive
(identifier) @variable
((identifier) @type
(#lua-match? @type "^[A-Z]"))
(const_item
name: (identifier) @constant)
; Assume all-caps names are constants
((identifier) @constant
(#lua-match? @constant "^[A-Z][A-Z%d_]*$"))
; Other identifiers
(type_identifier) @type
(primitive_type) @type.builtin
(field_identifier) @variable.member
(shorthand_field_identifier) @variable.member
(shorthand_field_initializer
(identifier) @variable.member)
(mod_item
name: (identifier) @module)
(self) @variable.builtin
"_" @character.special
(label
[
"'"
(identifier)
] @label)
; Function definitions
(function_item
(identifier) @function)
(function_signature_item
(identifier) @function)
(parameter
[
(identifier)
"_"
] @variable.parameter)
(parameter
(ref_pattern
[
(mut_pattern
(identifier) @variable.parameter)
(identifier) @variable.parameter
]))
(closure_parameters
(_) @variable.parameter)
; Function calls
(call_expression
function: (identifier) @function.call)
(call_expression
function: (scoped_identifier
(identifier) @function.call .))
(call_expression
function: (field_expression
field: (field_identifier) @function.call))
(generic_function
function: (identifier) @function.call)
(generic_function
function: (scoped_identifier
name: (identifier) @function.call))
(generic_function
function: (field_expression
field: (field_identifier) @function.call))
; Assume other uppercase names are enum constructors
((field_identifier) @constant
(#lua-match? @constant "^[A-Z]"))
(enum_variant
name: (identifier) @constant)
; Assume that uppercase names in paths are types
(scoped_identifier
path: (identifier) @module)
(scoped_identifier
(scoped_identifier
name: (identifier) @module))
(scoped_type_identifier
path: (identifier) @module)
(scoped_type_identifier
path: (identifier) @type
(#lua-match? @type "^[A-Z]"))
(scoped_type_identifier
(scoped_identifier
name: (identifier) @module))
((scoped_identifier
path: (identifier) @type)
(#lua-match? @type "^[A-Z]"))
((scoped_identifier
name: (identifier) @type)
(#lua-match? @type "^[A-Z]"))
((scoped_identifier
name: (identifier) @constant)
(#lua-match? @constant "^[A-Z][A-Z%d_]*$"))
((scoped_identifier
path: (identifier) @type
name: (identifier) @constant)
(#lua-match? @type "^[A-Z]")
(#lua-match? @constant "^[A-Z]"))
((scoped_type_identifier
path: (identifier) @type
name: (type_identifier) @constant)
(#lua-match? @type "^[A-Z]")
(#lua-match? @constant "^[A-Z]"))
[
(crate)
(super)
] @module
(scoped_use_list
path: (identifier) @module)
(scoped_use_list
path: (scoped_identifier
(identifier) @module))
(use_list
(scoped_identifier
(identifier) @module
.
(_)))
(use_list
(identifier) @type
(#lua-match? @type "^[A-Z]"))
(use_as_clause
alias: (identifier) @type
(#lua-match? @type "^[A-Z]"))
; Correct enum constructors
(call_expression
function: (scoped_identifier
"::"
name: (identifier) @constant)
(#lua-match? @constant "^[A-Z]"))
; Assume uppercase names in a match arm are constants.
((match_arm
pattern: (match_pattern
(identifier) @constant))
(#lua-match? @constant "^[A-Z]"))
((match_arm
pattern: (match_pattern
(scoped_identifier
name: (identifier) @constant)))
(#lua-match? @constant "^[A-Z]"))
((identifier) @constant.builtin
(#any-of? @constant.builtin "Some" "None" "Ok" "Err"))
; Macro definitions
"$" @function.macro
(metavariable) @function.macro
(macro_definition
"macro_rules!" @function.macro)
; Attribute macros
(attribute_item
(attribute
(identifier) @function.macro))
(inner_attribute_item
(attribute
(identifier) @function.macro))
(attribute
(scoped_identifier
(identifier) @function.macro .))
; Derive macros (assume all arguments are types)
; (attribute
; (identifier) @_name
; arguments: (attribute (attribute (identifier) @type))
; (#eq? @_name "derive"))
; Function-like macros
(macro_invocation
macro: (identifier) @function.macro)
(macro_invocation
macro: (scoped_identifier
(identifier) @function.macro .))
; Literals
(boolean_literal) @boolean
(integer_literal) @number
(float_literal) @number.float
[
(raw_string_literal)
(string_literal)
] @string
(escape_sequence) @string.escape
(char_literal) @character
; Keywords
[
"use"
"mod"
] @keyword.import
(use_as_clause
"as" @keyword.import)
[
"default"
"impl"
"let"
"move"
"unsafe"
"where"
] @keyword
[
"enum"
"struct"
"union"
"trait"
"type"
] @keyword.type
[
"async"
"await"
"gen"
] @keyword.coroutine
"try" @keyword.exception
[
"ref"
"pub"
"raw"
(mutable_specifier)
"const"
"static"
"dyn"
"extern"
] @keyword.modifier
(lifetime
"'" @keyword.modifier)
(lifetime
(identifier) @attribute)
(lifetime
(identifier) @attribute.builtin
(#any-of? @attribute.builtin "static" "_"))
"fn" @keyword.function
[
"return"
"yield"
] @keyword.return
(type_cast_expression
"as" @keyword.operator)
(qualified_type
"as" @keyword.operator)
(use_list
(self) @module)
(scoped_use_list
(self) @module)
(scoped_identifier
[
(crate)
(super)
(self)
] @module)
(visibility_modifier
[
(crate)
(super)
(self)
] @module)
[
"if"
"else"
"match"
] @keyword.conditional
[
"break"
"continue"
"in"
"loop"
"while"
] @keyword.repeat
"for" @keyword
(for_expression
"for" @keyword.repeat)
; Operators
[
"!"
"!="
"%"
"%="
"&"
"&&"
"&="
"*"
"*="
"+"
"+="
"-"
"-="
".."
"..="
"..."
"/"
"/="
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"?"
"@"
"^"
"^="
"|"
"|="
"||"
] @operator
(use_wildcard
"*" @character.special)
(remaining_field_pattern
".." @character.special)
(range_pattern
[
".."
"..="
"..."
] @character.special)
; Punctuation
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
(closure_parameters
"|" @punctuation.bracket)
(type_arguments
[
"<"
">"
] @punctuation.bracket)
(type_parameters
[
"<"
">"
] @punctuation.bracket)
(bracketed_type
[
"<"
">"
] @punctuation.bracket)
(for_lifetimes
[
"<"
">"
] @punctuation.bracket)
[
","
"."
":"
"::"
";"
"->"
"=>"
] @punctuation.delimiter
(attribute_item
"#" @punctuation.special)
(inner_attribute_item
[
"!"
"#"
] @punctuation.special)
(macro_invocation
"!" @function.macro)
(never_type
"!" @type.builtin)
(macro_invocation
macro: (identifier) @_identifier @keyword.exception
"!" @keyword.exception
(#eq? @_identifier "panic"))
(macro_invocation
macro: (identifier) @_identifier @keyword.exception
"!" @keyword.exception
(#contains? @_identifier "assert"))
(macro_invocation
macro: (identifier) @_identifier @keyword.debug
"!" @keyword.debug
(#eq? @_identifier "dbg"))
; Comments
[
(line_comment)
(block_comment)
(outer_doc_comment_marker)
(inner_doc_comment_marker)
] @comment @spell
(line_comment
(doc_comment)) @comment.documentation
(block_comment
(doc_comment)) @comment.documentation
(call_expression
function: (scoped_identifier
path: (identifier) @_regex
(#any-of? @_regex "Regex" "ByteRegexBuilder")
name: (identifier) @_new
(#eq? @_new "new"))
arguments: (arguments
(raw_string_literal
(string_content) @string.regexp)))
(call_expression
function: (scoped_identifier
path: (scoped_identifier
(identifier) @_regex
(#any-of? @_regex "Regex" "ByteRegexBuilder") .)
name: (identifier) @_new
(#eq? @_new "new"))
arguments: (arguments
(raw_string_literal
(string_content) @string.regexp)))
(call_expression
function: (scoped_identifier
path: (identifier) @_regex
(#any-of? @_regex "RegexSet" "RegexSetBuilder")
name: (identifier) @_new
(#eq? @_new "new"))
arguments: (arguments
(array_expression
(raw_string_literal
(string_content) @string.regexp))))
(call_expression
function: (scoped_identifier
path: (scoped_identifier
(identifier) @_regex
(#any-of? @_regex "RegexSet" "RegexSetBuilder") .)
name: (identifier) @_new
(#eq? @_new "new"))
arguments: (arguments
(array_expression
(raw_string_literal
(string_content) @string.regexp))))

View file

@ -0,0 +1,208 @@
; inherits: ecma
"require" @keyword.import
(import_require_clause
source: (string) @string.special.url)
[
"declare"
"implements"
"type"
"override"
"module"
"asserts"
"infer"
"is"
"using"
] @keyword
[
"namespace"
"interface"
"enum"
] @keyword.type
[
"keyof"
"satisfies"
] @keyword.operator
(as_expression
"as" @keyword.operator)
(mapped_type_clause
"as" @keyword.operator)
[
"abstract"
"private"
"protected"
"public"
"readonly"
] @keyword.modifier
; types
(type_identifier) @type
(predefined_type) @type.builtin
(import_statement
"type"
(import_clause
(named_imports
(import_specifier
name: (identifier) @type))))
(template_literal_type) @string
(non_null_expression
"!" @operator)
; punctuation
(type_arguments
[
"<"
">"
] @punctuation.bracket)
(type_parameters
[
"<"
">"
] @punctuation.bracket)
(object_type
[
"{|"
"|}"
] @punctuation.bracket)
(union_type
"|" @punctuation.delimiter)
(intersection_type
"&" @punctuation.delimiter)
(type_annotation
":" @punctuation.delimiter)
(type_predicate_annotation
":" @punctuation.delimiter)
(index_signature
":" @punctuation.delimiter)
(omitting_type_annotation
"-?:" @punctuation.delimiter)
(adding_type_annotation
"+?:" @punctuation.delimiter)
(opting_type_annotation
"?:" @punctuation.delimiter)
"?." @punctuation.delimiter
(abstract_method_signature
"?" @punctuation.special)
(method_signature
"?" @punctuation.special)
(method_definition
"?" @punctuation.special)
(property_signature
"?" @punctuation.special)
(optional_parameter
"?" @punctuation.special)
(optional_type
"?" @punctuation.special)
(public_field_definition
[
"?"
"!"
] @punctuation.special)
(flow_maybe_type
"?" @punctuation.special)
(template_type
[
"${"
"}"
] @punctuation.special)
(conditional_type
[
"?"
":"
] @keyword.conditional.ternary)
; Parameters
(required_parameter
pattern: (identifier) @variable.parameter)
(optional_parameter
pattern: (identifier) @variable.parameter)
(required_parameter
(rest_pattern
(identifier) @variable.parameter))
; ({ a }) => null
(required_parameter
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter))
; ({ a = b }) => null
(required_parameter
(object_pattern
(object_assignment_pattern
(shorthand_property_identifier_pattern) @variable.parameter)))
; ({ a: b }) => null
(required_parameter
(object_pattern
(pair_pattern
value: (identifier) @variable.parameter)))
; ([ a ]) => null
(required_parameter
(array_pattern
(identifier) @variable.parameter))
; a => null
(arrow_function
parameter: (identifier) @variable.parameter)
; global declaration
(ambient_declaration
"global" @module)
; function signatures
(ambient_declaration
(function_signature
name: (identifier) @function))
; method signatures
(method_signature
name: (_) @function.method)
(abstract_method_signature
name: (property_identifier) @function.method)
; property signatures
(property_signature
name: (property_identifier) @function.method
type: (type_annotation
[
(union_type
(parenthesized_type
(function_type)))
(function_type)
]))

View file

@ -0,0 +1,341 @@
; Lower priority to prefer @variable.parameter when identifier appears in parameter_declaration.
((identifier) @variable
(#set! priority 95))
(preproc_def
(preproc_arg) @variable)
[
"default"
"goto"
"asm"
"__asm__"
] @keyword
[
"enum"
"struct"
"union"
"typedef"
] @keyword.type
[
"sizeof"
"offsetof"
] @keyword.operator
(alignof_expression
.
_ @keyword.operator)
"return" @keyword.return
[
"while"
"for"
"do"
"continue"
"break"
] @keyword.repeat
[
"if"
"else"
"case"
"switch"
] @keyword.conditional
[
"#if"
"#ifdef"
"#ifndef"
"#else"
"#elif"
"#endif"
"#elifdef"
"#elifndef"
(preproc_directive)
] @keyword.directive
"#define" @keyword.directive.define
"#include" @keyword.import
[
";"
":"
","
"."
"::"
] @punctuation.delimiter
"..." @punctuation.special
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
[
"="
"-"
"*"
"/"
"+"
"%"
"~"
"|"
"&"
"^"
"<<"
">>"
"->"
"<"
"<="
">="
">"
"=="
"!="
"!"
"&&"
"||"
"-="
"+="
"*="
"/="
"%="
"|="
"&="
"^="
">>="
"<<="
"--"
"++"
] @operator
; Make sure the comma operator is given a highlight group after the comma
; punctuator so the operator is highlighted properly.
(comma_expression
"," @operator)
[
(true)
(false)
] @boolean
(conditional_expression
[
"?"
":"
] @keyword.conditional.ternary)
(string_literal) @string
(system_lib_string) @string
(escape_sequence) @string.escape
(null) @constant.builtin
(number_literal) @number
(char_literal) @character
(preproc_defined) @function.macro
((field_expression
(field_identifier) @property) @_parent
(#not-has-parent? @_parent function_declarator call_expression))
(field_designator) @property
((field_identifier) @property
(#has-ancestor? @property field_declaration)
(#not-has-ancestor? @property function_declarator))
(statement_identifier) @label
(declaration
type: (type_identifier) @_type
declarator: (identifier) @label
(#eq? @_type "__label__"))
[
(type_identifier)
(type_descriptor)
] @type
(storage_class_specifier) @keyword.modifier
[
(type_qualifier)
(gnu_asm_qualifier)
"__extension__"
] @keyword.modifier
(linkage_specification
"extern" @keyword.modifier)
(type_definition
declarator: (type_identifier) @type.definition)
(primitive_type) @type.builtin
(sized_type_specifier
_ @type.builtin
type: _?)
((identifier) @constant
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
(preproc_def
(preproc_arg) @constant
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
(enumerator
name: (identifier) @constant)
(case_statement
value: (identifier) @constant)
((identifier) @constant.builtin
; format-ignore
(#any-of? @constant.builtin
"stderr" "stdin" "stdout"
"__FILE__" "__LINE__" "__DATE__" "__TIME__"
"__STDC__" "__STDC_VERSION__" "__STDC_HOSTED__"
"__cplusplus" "__OBJC__" "__ASSEMBLER__"
"__BASE_FILE__" "__FILE_NAME__" "__INCLUDE_LEVEL__"
"__TIMESTAMP__" "__clang__" "__clang_major__"
"__clang_minor__" "__clang_patchlevel__"
"__clang_version__" "__clang_literal_encoding__"
"__clang_wide_literal_encoding__"
"__FUNCTION__" "__func__" "__PRETTY_FUNCTION__"
"__VA_ARGS__" "__VA_OPT__"))
(preproc_def
(preproc_arg) @constant.builtin
; format-ignore
(#any-of? @constant.builtin
"stderr" "stdin" "stdout"
"__FILE__" "__LINE__" "__DATE__" "__TIME__"
"__STDC__" "__STDC_VERSION__" "__STDC_HOSTED__"
"__cplusplus" "__OBJC__" "__ASSEMBLER__"
"__BASE_FILE__" "__FILE_NAME__" "__INCLUDE_LEVEL__"
"__TIMESTAMP__" "__clang__" "__clang_major__"
"__clang_minor__" "__clang_patchlevel__"
"__clang_version__" "__clang_literal_encoding__"
"__clang_wide_literal_encoding__"
"__FUNCTION__" "__func__" "__PRETTY_FUNCTION__"
"__VA_ARGS__" "__VA_OPT__"))
(attribute_specifier
(argument_list
(identifier) @variable.builtin))
(attribute_specifier
(argument_list
(call_expression
function: (identifier) @variable.builtin)))
((call_expression
function: (identifier) @function.builtin)
(#lua-match? @function.builtin "^__builtin_"))
((call_expression
function: (identifier) @function.builtin)
(#has-ancestor? @function.builtin attribute_specifier))
; Preproc def / undef
(preproc_def
name: (_) @constant.macro)
(preproc_call
directive: (preproc_directive) @_u
argument: (_) @constant.macro
(#eq? @_u "#undef"))
(preproc_ifdef
name: (identifier) @constant.macro)
(preproc_elifdef
name: (identifier) @constant.macro)
(preproc_defined
(identifier) @constant.macro)
(call_expression
function: (identifier) @function.call)
(call_expression
function: (field_expression
field: (field_identifier) @function.call))
(function_declarator
declarator: (identifier) @function)
(function_declarator
declarator: (parenthesized_declarator
(pointer_declarator
declarator: (field_identifier) @function)))
(preproc_function_def
name: (identifier) @function.macro)
(comment) @comment @spell
((comment) @comment.documentation
(#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$"))
; Parameters
(parameter_declaration
declarator: (identifier) @variable.parameter)
(parameter_declaration
declarator: (array_declarator) @variable.parameter)
(parameter_declaration
declarator: (pointer_declarator) @variable.parameter)
; K&R functions
; To enable support for K&R functions,
; add the following lines to your own query config and uncomment them.
; They are commented out as they'll conflict with C++
; Note that you'll need to have `; extends` at the top of your query file.
;
; (parameter_list (identifier) @variable.parameter)
;
; (function_definition
; declarator: _
; (declaration
; declarator: (identifier) @variable.parameter))
;
; (function_definition
; declarator: _
; (declaration
; declarator: (array_declarator) @variable.parameter))
;
; (function_definition
; declarator: _
; (declaration
; declarator: (pointer_declarator) @variable.parameter))
(preproc_params
(identifier) @variable.parameter)
[
"__attribute__"
"__declspec"
"__based"
"__cdecl"
"__clrcall"
"__stdcall"
"__fastcall"
"__thiscall"
"__vectorcall"
(ms_pointer_modifier)
(attribute_declaration)
] @attribute

View file

@ -0,0 +1,273 @@
; inherits: c
((identifier) @variable.member
(#lua-match? @variable.member "^m_.*$"))
(parameter_declaration
declarator: (reference_declarator) @variable.parameter)
; function(Foo ...foo)
(variadic_parameter_declaration
declarator: (variadic_declarator
(_) @variable.parameter))
; int foo = 0
(optional_parameter_declaration
declarator: (_) @variable.parameter)
;(field_expression) @variable.parameter ;; How to highlight this?
((field_expression
(field_identifier) @function.method) @_parent
(#has-parent? @_parent template_method function_declarator))
(field_declaration
(field_identifier) @variable.member)
(field_initializer
(field_identifier) @property)
(function_declarator
declarator: (field_identifier) @function.method)
(concept_definition
name: (identifier) @type.definition)
(alias_declaration
name: (type_identifier) @type.definition)
(auto) @type.builtin
(namespace_identifier) @module
((namespace_identifier) @type
(#lua-match? @type "^[%u]"))
(case_statement
value: (qualified_identifier
(identifier) @constant))
(using_declaration
.
"using"
.
"namespace"
.
[
(qualified_identifier)
(identifier)
] @module)
(destructor_name
(identifier) @function.method)
; functions
(function_declarator
(qualified_identifier
(identifier) @function))
(function_declarator
(qualified_identifier
(qualified_identifier
(identifier) @function)))
(function_declarator
(qualified_identifier
(qualified_identifier
(qualified_identifier
(identifier) @function))))
((qualified_identifier
(qualified_identifier
(qualified_identifier
(qualified_identifier
(identifier) @function)))) @_parent
(#has-ancestor? @_parent function_declarator))
(function_declarator
(template_function
(identifier) @function))
(operator_name) @function
"operator" @function
"static_assert" @function.builtin
(call_expression
(qualified_identifier
(identifier) @function.call))
(call_expression
(qualified_identifier
(qualified_identifier
(identifier) @function.call)))
(call_expression
(qualified_identifier
(qualified_identifier
(qualified_identifier
(identifier) @function.call))))
((qualified_identifier
(qualified_identifier
(qualified_identifier
(qualified_identifier
(identifier) @function.call)))) @_parent
(#has-ancestor? @_parent call_expression))
(call_expression
(template_function
(identifier) @function.call))
(call_expression
(qualified_identifier
(template_function
(identifier) @function.call)))
(call_expression
(qualified_identifier
(qualified_identifier
(template_function
(identifier) @function.call))))
(call_expression
(qualified_identifier
(qualified_identifier
(qualified_identifier
(template_function
(identifier) @function.call)))))
((qualified_identifier
(qualified_identifier
(qualified_identifier
(qualified_identifier
(template_function
(identifier) @function.call))))) @_parent
(#has-ancestor? @_parent call_expression))
; methods
(function_declarator
(template_method
(field_identifier) @function.method))
(call_expression
(field_expression
(field_identifier) @function.method.call))
(call_expression
(field_expression
(template_method
(field_identifier) @function.method.call)))
; constructors
((function_declarator
(qualified_identifier
(identifier) @constructor))
(#lua-match? @constructor "^%u"))
((call_expression
function: (identifier) @constructor)
(#lua-match? @constructor "^%u"))
((call_expression
function: (qualified_identifier
name: (identifier) @constructor))
(#lua-match? @constructor "^%u"))
((call_expression
function: (field_expression
field: (field_identifier) @constructor))
(#lua-match? @constructor "^%u"))
; constructing a type in an initializer list: Constructor (): **SuperType (1)**
((field_initializer
(field_identifier) @constructor
(argument_list))
(#lua-match? @constructor "^%u"))
; Constants
(this) @variable.builtin
(null
"nullptr" @constant.builtin)
(true) @boolean
(false) @boolean
; Literals
(raw_string_literal) @string
; Keywords
[
"try"
"catch"
"noexcept"
"throw"
] @keyword.exception
[
"decltype"
"explicit"
"friend"
"override"
"using"
"requires"
"constexpr"
] @keyword
[
"class"
"namespace"
"template"
"typename"
"concept"
] @keyword.type
[
"co_await"
"co_yield"
"co_return"
] @keyword.coroutine
[
"public"
"private"
"protected"
"final"
"virtual"
] @keyword.modifier
[
"new"
"delete"
"xor"
"bitand"
"bitor"
"compl"
"not"
"xor_eq"
"and_eq"
"or_eq"
"not_eq"
"and"
"or"
] @keyword.operator
"<=>" @operator
"::" @punctuation.delimiter
(template_argument_list
[
"<"
">"
] @punctuation.bracket)
(template_parameter_list
[
"<"
">"
] @punctuation.bracket)
(literal_suffix) @operator

View file

@ -0,0 +1,392 @@
; Types
; Javascript
; Variables
;-----------
(identifier) @variable
; Properties
;-----------
(property_identifier) @variable.member
(shorthand_property_identifier) @variable.member
(private_property_identifier) @variable.member
(object_pattern
(shorthand_property_identifier_pattern) @variable)
(object_pattern
(object_assignment_pattern
(shorthand_property_identifier_pattern) @variable))
; Special identifiers
;--------------------
((identifier) @type
(#lua-match? @type "^[A-Z]"))
((identifier) @constant
(#lua-match? @constant "^_*[A-Z][A-Z%d_]*$"))
((shorthand_property_identifier) @constant
(#lua-match? @constant "^_*[A-Z][A-Z%d_]*$"))
((identifier) @variable.builtin
(#any-of? @variable.builtin "arguments" "module" "console" "window" "document"))
((identifier) @type.builtin
(#any-of? @type.builtin
"Object" "Function" "Boolean" "Symbol" "Number" "Math" "Date" "String" "RegExp" "Map" "Set"
"WeakMap" "WeakSet" "Promise" "Array" "Int8Array" "Uint8Array" "Uint8ClampedArray" "Int16Array"
"Uint16Array" "Int32Array" "Uint32Array" "Float32Array" "Float64Array" "ArrayBuffer" "DataView"
"Error" "EvalError" "InternalError" "RangeError" "ReferenceError" "SyntaxError" "TypeError"
"URIError"))
(statement_identifier) @label
; Function and method definitions
;--------------------------------
(function_expression
name: (identifier) @function)
(function_declaration
name: (identifier) @function)
(generator_function
name: (identifier) @function)
(generator_function_declaration
name: (identifier) @function)
(method_definition
name: [
(property_identifier)
(private_property_identifier)
] @function.method)
(method_definition
name: (property_identifier) @constructor
(#eq? @constructor "constructor"))
(pair
key: (property_identifier) @function.method
value: (function_expression))
(pair
key: (property_identifier) @function.method
value: (arrow_function))
(assignment_expression
left: (member_expression
property: (property_identifier) @function.method)
right: (arrow_function))
(assignment_expression
left: (member_expression
property: (property_identifier) @function.method)
right: (function_expression))
(variable_declarator
name: (identifier) @function
value: (arrow_function))
(variable_declarator
name: (identifier) @function
value: (function_expression))
(assignment_expression
left: (identifier) @function
right: (arrow_function))
(assignment_expression
left: (identifier) @function
right: (function_expression))
; Function and method calls
;--------------------------
(call_expression
function: (identifier) @function.call)
(call_expression
function: (member_expression
property: [
(property_identifier)
(private_property_identifier)
] @function.method.call))
(call_expression
function: (await_expression
(identifier) @function.call))
(call_expression
function: (await_expression
(member_expression
property: [
(property_identifier)
(private_property_identifier)
] @function.method.call)))
; Builtins
;---------
((identifier) @module.builtin
(#eq? @module.builtin "Intl"))
((identifier) @function.builtin
(#any-of? @function.builtin
"eval" "isFinite" "isNaN" "parseFloat" "parseInt" "decodeURI" "decodeURIComponent" "encodeURI"
"encodeURIComponent" "require"))
; Constructor
;------------
(new_expression
constructor: (identifier) @constructor)
; Decorators
;----------
(decorator
"@" @attribute
(identifier) @attribute)
(decorator
"@" @attribute
(call_expression
(identifier) @attribute))
(decorator
"@" @attribute
(member_expression
(property_identifier) @attribute))
(decorator
"@" @attribute
(call_expression
(member_expression
(property_identifier) @attribute)))
; Literals
;---------
[
(this)
(super)
] @variable.builtin
((identifier) @variable.builtin
(#eq? @variable.builtin "self"))
[
(true)
(false)
] @boolean
[
(null)
(undefined)
] @constant.builtin
[
(comment)
(html_comment)
] @comment @spell
((comment) @comment.documentation
(#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$"))
(hash_bang_line) @keyword.directive
((string_fragment) @keyword.directive
(#eq? @keyword.directive "use strict"))
(string) @string
(template_string) @string
(escape_sequence) @string.escape
(regex_pattern) @string.regexp
(regex_flags) @character.special
(regex
"/" @punctuation.bracket) ; Regex delimiters
(number) @number
((identifier) @number
(#any-of? @number "NaN" "Infinity"))
; Punctuation
;------------
[
";"
"."
","
":"
] @punctuation.delimiter
[
"--"
"-"
"-="
"&&"
"+"
"++"
"+="
"&="
"/="
"**="
"<<="
"<"
"<="
"<<"
"="
"=="
"==="
"!="
"!=="
"=>"
">"
">="
">>"
"||"
"%"
"%="
"*"
"**"
">>>"
"&"
"|"
"^"
"??"
"*="
">>="
">>>="
"^="
"|="
"&&="
"||="
"??="
"..."
] @operator
(binary_expression
"/" @operator)
(ternary_expression
[
"?"
":"
] @keyword.conditional.ternary)
(unary_expression
[
"!"
"~"
"-"
"+"
] @operator)
(unary_expression
[
"delete"
"void"
] @keyword.operator)
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
(template_substitution
[
"${"
"}"
] @punctuation.special) @none
; Imports
;----------
(namespace_import
"*" @character.special
(identifier) @module)
(namespace_export
"*" @character.special
(identifier) @module)
(export_statement
"*" @character.special)
; Keywords
;----------
[
"if"
"else"
"switch"
"case"
] @keyword.conditional
[
"import"
"from"
"as"
"export"
] @keyword.import
[
"for"
"of"
"do"
"while"
"continue"
] @keyword.repeat
[
"break"
"const"
"debugger"
"extends"
"get"
"let"
"set"
"static"
"target"
"var"
"with"
] @keyword
"class" @keyword.type
[
"async"
"await"
] @keyword.coroutine
[
"return"
"yield"
] @keyword.return
"function" @keyword.function
[
"new"
"delete"
"in"
"instanceof"
"typeof"
] @keyword.operator
[
"throw"
"try"
"catch"
"finally"
] @keyword.exception
(export_statement
"default" @keyword)
(switch_default
"default" @keyword.conditional)

View file

@ -0,0 +1,249 @@
; Forked from tree-sitter-go
; Copyright (c) 2014 Max Brunsfeld (The MIT License)
;
; Identifiers
(type_identifier) @type
(type_spec
name: (type_identifier) @type.definition)
(field_identifier) @property
(identifier) @variable
(package_identifier) @module
(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)
(call_expression
function: (selector_expression
field: (field_identifier) @function.method.call))
; Function definitions
(function_declaration
name: (identifier) @function)
(method_declaration
name: (field_identifier) @function.method)
(method_elem
name: (field_identifier) @function.method)
; Constructors
((call_expression
(identifier) @constructor)
(#lua-match? @constructor "^[nN]ew.+$"))
((call_expression
(identifier) @constructor)
(#lua-match? @constructor "^[mM]ake.+$"))
; Operators
[
"--"
"-"
"-="
":="
"!"
"!="
"..."
"*"
"*="
"/"
"/="
"&"
"&&"
"&="
"&^"
"&^="
"%"
"%="
"^"
"^="
"+"
"++"
"+="
"<-"
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"|"
"|="
"||"
"~"
] @operator
; Keywords
[
"break"
"const"
"continue"
"default"
"defer"
"goto"
"range"
"select"
"var"
"fallthrough"
] @keyword
[
"type"
"struct"
"interface"
] @keyword.type
"func" @keyword.function
"return" @keyword.return
"go" @keyword.coroutine
"for" @keyword.repeat
[
"import"
"package"
] @keyword.import
[
"else"
"case"
"switch"
"if"
] @keyword.conditional
; Builtin types
[
"chan"
"map"
] @type.builtin
((type_identifier) @type.builtin
(#any-of? @type.builtin
"any" "bool" "byte" "comparable" "complex128" "complex64" "error" "float32" "float64" "int"
"int16" "int32" "int64" "int8" "rune" "string" "uint" "uint16" "uint32" "uint64" "uint8"
"uintptr"))
; Builtin functions
((identifier) @function.builtin
(#any-of? @function.builtin
"append" "cap" "clear" "close" "complex" "copy" "delete" "imag" "len" "make" "max" "min" "new"
"panic" "print" "println" "real" "recover"))
; Delimiters
[
"."
","
":"
";"
] @punctuation.delimiter
[
"("
")"
"{"
"}"
"["
"]"
] @punctuation.bracket
; Literals
(interpreted_string_literal) @string
(raw_string_literal) @string
(rune_literal) @character
(escape_sequence) @string.escape
(int_literal) @number
(float_literal) @number.float
(imaginary_literal) @number
[
(true)
(false)
] @boolean
[
(nil)
(iota)
] @constant.builtin
(keyed_element
.
(literal_element
(identifier) @variable.member))
(field_declaration
name: (field_identifier) @variable.member)
; Comments
(comment) @comment @spell
; Doc Comments
(source_file
.
(comment)+ @comment.documentation)
(source_file
(comment)+ @comment.documentation
.
(const_declaration))
(source_file
(comment)+ @comment.documentation
.
(function_declaration))
(source_file
(comment)+ @comment.documentation
.
(type_declaration))
(source_file
(comment)+ @comment.documentation
.
(var_declaration))
; Spell
((interpreted_string_literal) @spell
(#not-has-parent? @spell import_spec))
; Regex
(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
(raw_string_literal_content) @string.regexp)
(interpreted_string_literal
(interpreted_string_literal_content) @string.regexp)
]))

View file

@ -0,0 +1,333 @@
; CREDITS @maxbrunsfeld (maxbrunsfeld@gmail.com)
; Variables
(identifier) @variable
(underscore_pattern) @character.special
; Methods
(method_declaration
name: (identifier) @function.method)
(method_invocation
name: (identifier) @function.method.call)
(super) @function.builtin
; Parameters
(formal_parameter
name: (identifier) @variable.parameter)
(spread_parameter
(variable_declarator
name: (identifier) @variable.parameter)) ; int... foo
; Lambda parameter
(inferred_parameters
(identifier) @variable.parameter) ; (x,y) -> ...
(lambda_expression
parameters: (identifier) @variable.parameter) ; x -> ...
; Operators
[
"+"
":"
"++"
"-"
"--"
"&"
"&&"
"|"
"||"
"!"
"!="
"=="
"*"
"/"
"%"
"<"
"<="
">"
">="
"="
"-="
"+="
"*="
"/="
"%="
"->"
"^"
"^="
"&="
"|="
"~"
">>"
">>>"
"<<"
"::"
] @operator
; Types
(interface_declaration
name: (identifier) @type)
(annotation_type_declaration
name: (identifier) @type)
(class_declaration
name: (identifier) @type)
(record_declaration
name: (identifier) @type)
(enum_declaration
name: (identifier) @type)
(constructor_declaration
name: (identifier) @type)
(compact_constructor_declaration
name: (identifier) @type)
(type_identifier) @type
((type_identifier) @type.builtin
(#eq? @type.builtin "var"))
((method_invocation
object: (identifier) @type)
(#lua-match? @type "^[A-Z]"))
((method_reference
.
(identifier) @type)
(#lua-match? @type "^[A-Z]"))
((field_access
object: (identifier) @type)
(#lua-match? @type "^[A-Z]"))
(scoped_identifier
(identifier) @type
(#lua-match? @type "^[A-Z]"))
; Fields
(field_declaration
declarator: (variable_declarator
name: (identifier) @variable.member))
(field_access
field: (identifier) @variable.member)
[
(boolean_type)
(integral_type)
(floating_point_type)
(void_type)
] @type.builtin
; Variables
((identifier) @constant
(#lua-match? @constant "^[A-Z_][A-Z%d_]+$"))
(this) @variable.builtin
; Annotations
(annotation
"@" @attribute
name: (identifier) @attribute)
(marker_annotation
"@" @attribute
name: (identifier) @attribute)
; Literals
(string_literal) @string
(escape_sequence) @string.escape
(character_literal) @character
[
(hex_integer_literal)
(decimal_integer_literal)
(octal_integer_literal)
(binary_integer_literal)
] @number
[
(decimal_floating_point_literal)
(hex_floating_point_literal)
] @number.float
[
(true)
(false)
] @boolean
(null_literal) @constant.builtin
; Keywords
[
"assert"
"default"
"extends"
"implements"
"instanceof"
"@interface"
"permits"
"to"
"with"
] @keyword
[
"record"
"class"
"enum"
"interface"
] @keyword.type
(synchronized_statement
"synchronized" @keyword)
[
"abstract"
"final"
"native"
"non-sealed"
"open"
"private"
"protected"
"public"
"sealed"
"static"
"strictfp"
"transitive"
] @keyword.modifier
(modifiers
"synchronized" @keyword.modifier)
[
"transient"
"volatile"
] @keyword.modifier
[
"return"
"yield"
] @keyword.return
"new" @keyword.operator
; Conditionals
[
"if"
"else"
"switch"
"case"
"when"
] @keyword.conditional
(ternary_expression
[
"?"
":"
] @keyword.conditional.ternary)
(wildcard
"?" @character.special)
; Loops
[
"for"
"while"
"do"
"continue"
"break"
] @keyword.repeat
; Includes
[
"exports"
"import"
"module"
"opens"
"package"
"provides"
"requires"
"uses"
] @keyword.import
(import_declaration
(asterisk
"*" @character.special))
; Punctuation
[
";"
"."
"..."
","
] @punctuation.delimiter
[
"{"
"}"
] @punctuation.bracket
[
"["
"]"
] @punctuation.bracket
[
"("
")"
] @punctuation.bracket
(type_arguments
[
"<"
">"
] @punctuation.bracket)
(type_parameters
[
"<"
">"
] @punctuation.bracket)
(string_interpolation
[
"\\{"
"}"
] @punctuation.special)
; Exceptions
[
"throw"
"throws"
"finally"
"try"
"catch"
] @keyword.exception
; Labels
(labeled_statement
(identifier) @label)
; Comments
[
(line_comment)
(block_comment)
] @comment @spell
((block_comment) @comment.documentation
(#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$"))
((line_comment) @comment.documentation
(#lua-match? @comment.documentation "^///[^/]"))
((line_comment) @comment.documentation
(#lua-match? @comment.documentation "^///$"))

View file

@ -0,0 +1,56 @@
; inherits: ecma,jsx
; Parameters
(formal_parameters
(identifier) @variable.parameter)
(formal_parameters
(rest_pattern
(identifier) @variable.parameter))
; ({ a }) => null
(formal_parameters
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter))
; ({ a = b }) => null
(formal_parameters
(object_pattern
(object_assignment_pattern
(shorthand_property_identifier_pattern) @variable.parameter)))
; ({ a: b }) => null
(formal_parameters
(object_pattern
(pair_pattern
value: (identifier) @variable.parameter)))
; ([ a ]) => null
(formal_parameters
(array_pattern
(identifier) @variable.parameter))
; ({ a } = { a }) => null
(formal_parameters
(assignment_pattern
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter)))
; ({ a = b } = { a }) => null
(formal_parameters
(assignment_pattern
(object_pattern
(object_assignment_pattern
(shorthand_property_identifier_pattern) @variable.parameter))))
; a => null
(arrow_function
parameter: (identifier) @variable.parameter)
; optional parameters
(formal_parameters
(assignment_pattern
left: (identifier) @variable.parameter))
; punctuation
(optional_chain) @punctuation.delimiter

View file

@ -0,0 +1,153 @@
(jsx_element
open_tag: (jsx_opening_element
[
"<"
">"
] @tag.delimiter))
(jsx_element
close_tag: (jsx_closing_element
[
"</"
">"
] @tag.delimiter))
(jsx_self_closing_element
[
"<"
"/>"
] @tag.delimiter)
(jsx_attribute
(property_identifier) @tag.attribute)
(jsx_opening_element
name: (identifier) @tag.builtin)
(jsx_closing_element
name: (identifier) @tag.builtin)
(jsx_self_closing_element
name: (identifier) @tag.builtin)
(jsx_opening_element
((identifier) @tag
(#lua-match? @tag "^[A-Z]")))
; Handle the dot operator effectively - <My.Component>
(jsx_opening_element
(member_expression
(identifier) @tag.builtin
(property_identifier) @tag))
(jsx_closing_element
((identifier) @tag
(#lua-match? @tag "^[A-Z]")))
; Handle the dot operator effectively - </My.Component>
(jsx_closing_element
(member_expression
(identifier) @tag.builtin
(property_identifier) @tag))
(jsx_self_closing_element
((identifier) @tag
(#lua-match? @tag "^[A-Z]")))
; Handle the dot operator effectively - <My.Component />
(jsx_self_closing_element
(member_expression
(identifier) @tag.builtin
(property_identifier) @tag))
(html_character_reference) @tag
(jsx_text) @none @spell
(html_character_reference) @character.special
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading)
(#eq? @_tag "title"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.1)
(#eq? @_tag "h1"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.2)
(#eq? @_tag "h2"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.3)
(#eq? @_tag "h3"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.4)
(#eq? @_tag "h4"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.5)
(#eq? @_tag "h5"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.6)
(#eq? @_tag "h6"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.strong)
(#any-of? @_tag "strong" "b"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.italic)
(#any-of? @_tag "em" "i"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.strikethrough)
(#any-of? @_tag "s" "del"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.underline)
(#eq? @_tag "u"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.raw)
(#any-of? @_tag "code" "kbd"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.link.label)
(#eq? @_tag "a"))
((jsx_attribute
(property_identifier) @_attr
(string
(string_fragment) @string.special.url))
(#any-of? @_attr "href" "src"))

View file

@ -0,0 +1,380 @@
;; Based on the nvim-treesitter highlighting, which is under the Apache license.
;; See https://github.com/nvim-treesitter/nvim-treesitter/blob/f8ab59861eed4a1c168505e3433462ed800f2bae/queries/kotlin/highlights.scm
;;
;; The only difference in this file is that queries using #lua-match?
;; have been removed.
;;; Identifiers
(simple_identifier) @variable
; `it` keyword inside lambdas
; FIXME: This will highlight the keyword outside of lambdas since tree-sitter
; does not allow us to check for arbitrary nestation
((simple_identifier) @variable.builtin
(#eq? @variable.builtin "it"))
; `field` keyword inside property getter/setter
; FIXME: This will highlight the keyword outside of getters and setters
; since tree-sitter does not allow us to check for arbitrary nestation
((simple_identifier) @variable.builtin
(#eq? @variable.builtin "field"))
; `this` this keyword inside classes
(this_expression) @variable.builtin
; `super` keyword inside classes
(super_expression) @variable.builtin
(class_parameter
(simple_identifier) @property)
(class_body
(property_declaration
(variable_declaration
(simple_identifier) @property)))
; id_1.id_2.id_3: `id_2` and `id_3` are assumed as object properties
(_
(navigation_suffix
(simple_identifier) @property))
(enum_entry
(simple_identifier) @constant)
(type_identifier) @type
((type_identifier) @type.builtin
(#any-of? @type.builtin
"Byte"
"Short"
"Int"
"Long"
"UByte"
"UShort"
"UInt"
"ULong"
"Float"
"Double"
"Boolean"
"Char"
"String"
"Array"
"ByteArray"
"ShortArray"
"IntArray"
"LongArray"
"UByteArray"
"UShortArray"
"UIntArray"
"ULongArray"
"FloatArray"
"DoubleArray"
"BooleanArray"
"CharArray"
"Map"
"Set"
"List"
"EmptyMap"
"EmptySet"
"EmptyList"
"MutableMap"
"MutableSet"
"MutableList"
))
(package_header
. (identifier)) @namespace
(import_header
"import" @include)
; TODO: Seperate labeled returns/breaks/continue/super/this
; Must be implemented in the parser first
(label) @label
;;; Function definitions
(function_declaration
. (simple_identifier) @function)
(getter
("get") @function.builtin)
(setter
("set") @function.builtin)
(primary_constructor) @constructor
(secondary_constructor
("constructor") @constructor)
(constructor_invocation
(user_type
(type_identifier) @constructor))
(anonymous_initializer
("init") @constructor)
(parameter
(simple_identifier) @parameter)
(parameter_with_optional_type
(simple_identifier) @parameter)
; lambda parameters
(lambda_literal
(lambda_parameters
(variable_declaration
(simple_identifier) @parameter)))
;;; Function calls
; function()
(call_expression
. (simple_identifier) @function)
; object.function() or object.property.function()
(call_expression
(navigation_expression
(navigation_suffix
(simple_identifier) @function) . ))
(call_expression
. (simple_identifier) @function.builtin
(#any-of? @function.builtin
"arrayOf"
"arrayOfNulls"
"byteArrayOf"
"shortArrayOf"
"intArrayOf"
"longArrayOf"
"ubyteArrayOf"
"ushortArrayOf"
"uintArrayOf"
"ulongArrayOf"
"floatArrayOf"
"doubleArrayOf"
"booleanArrayOf"
"charArrayOf"
"emptyArray"
"mapOf"
"setOf"
"listOf"
"emptyMap"
"emptySet"
"emptyList"
"mutableMapOf"
"mutableSetOf"
"mutableListOf"
"print"
"println"
"error"
"TODO"
"run"
"runCatching"
"repeat"
"lazy"
"lazyOf"
"enumValues"
"enumValueOf"
"assert"
"check"
"checkNotNull"
"require"
"requireNotNull"
"with"
"suspend"
"synchronized"
))
;;; Literals
[
(line_comment)
(multiline_comment)
(shebang_line)
] @comment
(real_literal) @float
[
(integer_literal)
(long_literal)
(hex_literal)
(bin_literal)
(unsigned_literal)
] @number
[
(null_literal) ; should be highlighted the same as booleans
(boolean_literal)
] @boolean
(character_literal) @character
(string_literal) @string
(character_escape_seq) @string.escape
; There are 3 ways to define a regex
; - "[abc]?".toRegex()
(call_expression
(navigation_expression
((string_literal) @string.regex)
(navigation_suffix
((simple_identifier) @_function
(#eq? @_function "toRegex")))))
; - Regex("[abc]?")
(call_expression
((simple_identifier) @_function
(#eq? @_function "Regex"))
(call_suffix
(value_arguments
(value_argument
(string_literal) @string.regex))))
; - Regex.fromLiteral("[abc]?")
(call_expression
(navigation_expression
((simple_identifier) @_class
(#eq? @_class "Regex"))
(navigation_suffix
((simple_identifier) @_function
(#eq? @_function "fromLiteral"))))
(call_suffix
(value_arguments
(value_argument
(string_literal) @string.regex))))
;;; Keywords
(type_alias "typealias" @keyword)
[
(class_modifier)
(member_modifier)
(function_modifier)
(property_modifier)
(platform_modifier)
(variance_modifier)
(parameter_modifier)
(visibility_modifier)
(reification_modifier)
(inheritance_modifier)
]@keyword
[
"val"
"var"
"enum"
"class"
"object"
"interface"
; "typeof" ; NOTE: It is reserved for future use
] @keyword
("fun") @keyword.function
(jump_expression) @keyword.return
[
"if"
"else"
"when"
] @conditional
[
"for"
"do"
"while"
] @repeat
[
"try"
"catch"
"throw"
"finally"
] @exception
(annotation
"@" @attribute (use_site_target)? @attribute)
(annotation
(user_type
(type_identifier) @attribute))
(annotation
(constructor_invocation
(user_type
(type_identifier) @attribute)))
(file_annotation
"@" @attribute "file" @attribute ":" @attribute)
(file_annotation
(user_type
(type_identifier) @attribute))
(file_annotation
(constructor_invocation
(user_type
(type_identifier) @attribute)))
;;; Operators & Punctuation
[
"!"
"!="
"!=="
"="
"=="
"==="
">"
">="
"<"
"<="
"||"
"&&"
"+"
"++"
"+="
"-"
"--"
"-="
"*"
"*="
"/"
"/="
"%"
"%="
"?."
"?:"
"!!"
"is"
"!is"
"in"
"!in"
"as"
"as?"
".."
"->"
] @operator
[
"(" ")"
"[" "]"
"{" "}"
] @punctuation.bracket
[
"."
","
";"
":"
"::"
] @punctuation.delimiter
; NOTE: `interpolated_identifier`s can be highlighted in any way
(string_literal
"$" @punctuation.special
(interpolated_identifier) @none)
(string_literal
"${" @punctuation.special
(interpolated_expression) @none
"}" @punctuation.special)

View file

@ -0,0 +1,456 @@
; From tree-sitter-python licensed under MIT License
; Copyright (c) 2016 Max Brunsfeld
; Variables
(identifier) @variable
; Reset highlighting in f-string interpolations
(interpolation) @none @nospell
; Identifier naming conventions
((identifier) @type
(#lua-match? @type "^[A-Z].*[a-z]"))
((identifier) @constant
(#lua-match? @constant "^[A-Z][A-Z_0-9]*$"))
((identifier) @constant.builtin
(#lua-match? @constant.builtin "^__[a-zA-Z0-9_]*__$"))
((identifier) @constant.builtin
(#any-of? @constant.builtin
; https://docs.python.org/3/library/constants.html
"NotImplemented" "Ellipsis" "quit" "exit" "copyright" "credits" "license"))
"_" @character.special ; match wildcard
((assignment
left: (identifier) @type.definition
(type
(identifier) @_annotation))
(#eq? @_annotation "TypeAlias"))
((assignment
left: (identifier) @type.definition
right: (call
function: (identifier) @_func))
(#any-of? @_func "TypeVar" "NewType"))
; Function definitions
(function_definition
name: (identifier) @function)
(type
(identifier) @type)
(type
(subscript
(identifier) @type)) ; type subscript: Tuple[int]
((call
function: (identifier) @_isinstance
arguments: (argument_list
(_)
(identifier) @type))
(#eq? @_isinstance "isinstance"))
; Literals
(none) @constant.builtin
[
(true)
(false)
] @boolean
(integer) @number
(float) @number.float
(comment) @comment @spell
((module
.
(comment) @keyword.directive @nospell)
(#lua-match? @keyword.directive "^#!/"))
(string) @string
[
(escape_sequence)
(escape_interpolation)
] @string.escape
; doc-strings
(expression_statement
(string
(string_content) @spell) @string.documentation)
; Tokens
[
"-"
"-="
":="
"!="
"*"
"**"
"**="
"*="
"/"
"//"
"//="
"/="
"&"
"&="
"%"
"%="
"^"
"^="
"+"
"+="
"<"
"<<"
"<<="
"<="
"<>"
"="
"=="
">"
">="
">>"
">>="
"@"
"@="
"|"
"|="
"~"
"->"
] @operator
; Keywords
[
"and"
"in"
"is"
"not"
"or"
"is not"
"not in"
"del"
] @keyword.operator
[
"def"
"lambda"
] @keyword.function
[
"assert"
"exec"
"global"
"nonlocal"
"pass"
"print"
"with"
"as"
] @keyword
[
"type"
"class"
] @keyword.type
[
"async"
"await"
] @keyword.coroutine
[
"return"
"yield"
] @keyword.return
(yield
"from" @keyword.return)
(future_import_statement
"from" @keyword.import
"__future__" @module.builtin)
(import_from_statement
"from" @keyword.import)
"import" @keyword.import
(aliased_import
"as" @keyword.import)
(wildcard_import
"*" @character.special)
(import_statement
name: (dotted_name
(identifier) @module))
(import_statement
name: (aliased_import
name: (dotted_name
(identifier) @module)
alias: (identifier) @module))
(import_from_statement
module_name: (dotted_name
(identifier) @module))
(import_from_statement
module_name: (relative_import
(dotted_name
(identifier) @module)))
[
"if"
"elif"
"else"
"match"
"case"
] @keyword.conditional
[
"for"
"while"
"break"
"continue"
] @keyword.repeat
[
"try"
"except"
"raise"
"finally"
] @keyword.exception
(raise_statement
"from" @keyword.exception)
(try_statement
(else_clause
"else" @keyword.exception))
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
(interpolation
"{" @punctuation.special
"}" @punctuation.special)
(format_expression
"{" @punctuation.special
"}" @punctuation.special)
(line_continuation) @punctuation.special
(type_conversion) @function.macro
[
","
"."
":"
";"
(ellipsis)
] @punctuation.delimiter
((identifier) @type.builtin
(#any-of? @type.builtin
; https://docs.python.org/3/library/exceptions.html
"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"
; https://docs.python.org/3/library/stdtypes.html
"bool" "int" "float" "complex" "list" "tuple" "range" "str" "bytes" "bytearray" "memoryview"
"set" "frozenset" "dict" "type" "object"))
; Normal parameters
(parameters
(identifier) @variable.parameter)
; Lambda parameters
(lambda_parameters
(identifier) @variable.parameter)
(lambda_parameters
(tuple_pattern
(identifier) @variable.parameter))
; Default parameters
(keyword_argument
name: (identifier) @variable.parameter)
; Naming parameters on call-site
(default_parameter
name: (identifier) @variable.parameter)
(typed_parameter
(identifier) @variable.parameter)
(typed_default_parameter
name: (identifier) @variable.parameter)
; Variadic parameters *args, **kwargs
(parameters
(list_splat_pattern ; *args
(identifier) @variable.parameter))
(parameters
(dictionary_splat_pattern ; **kwargs
(identifier) @variable.parameter))
; Typed variadic parameters
(parameters
(typed_parameter
(list_splat_pattern ; *args: type
(identifier) @variable.parameter)))
(parameters
(typed_parameter
(dictionary_splat_pattern ; *kwargs: type
(identifier) @variable.parameter)))
; Lambda parameters
(lambda_parameters
(list_splat_pattern
(identifier) @variable.parameter))
(lambda_parameters
(dictionary_splat_pattern
(identifier) @variable.parameter))
((identifier) @variable.builtin
(#eq? @variable.builtin "self"))
((identifier) @variable.builtin
(#eq? @variable.builtin "cls"))
; After @type.builtin bacause builtins (such as `type`) are valid as attribute name
((attribute
attribute: (identifier) @variable.member)
(#lua-match? @variable.member "^[%l_].*$"))
; Class definitions
(class_definition
name: (identifier) @type)
(class_definition
body: (block
(function_definition
name: (identifier) @function.method)))
(class_definition
superclasses: (argument_list
(identifier) @type))
((class_definition
body: (block
(expression_statement
(assignment
left: (identifier) @variable.member))))
(#lua-match? @variable.member "^[%l_].*$"))
((class_definition
body: (block
(expression_statement
(assignment
left: (_
(identifier) @variable.member)))))
(#lua-match? @variable.member "^[%l_].*$"))
((class_definition
(block
(function_definition
name: (identifier) @constructor)))
(#any-of? @constructor "__new__" "__init__"))
; Function calls
(call
function: (identifier) @function.call)
(call
function: (attribute
attribute: (identifier) @function.method.call))
((call
function: (identifier) @constructor)
(#lua-match? @constructor "^%u"))
((call
function: (attribute
attribute: (identifier) @constructor))
(#lua-match? @constructor "^%u"))
; Builtin functions
((call
function: (identifier) @function.builtin)
(#any-of? @function.builtin
"abs" "all" "any" "ascii" "bin" "bool" "breakpoint" "bytearray" "bytes" "callable" "chr"
"classmethod" "compile" "complex" "delattr" "dict" "dir" "divmod" "enumerate" "eval" "exec"
"filter" "float" "format" "frozenset" "getattr" "globals" "hasattr" "hash" "help" "hex" "id"
"input" "int" "isinstance" "issubclass" "iter" "len" "list" "locals" "map" "max" "memoryview"
"min" "next" "object" "oct" "open" "ord" "pow" "print" "property" "range" "repr" "reversed"
"round" "set" "setattr" "slice" "sorted" "staticmethod" "str" "sum" "super" "tuple" "type"
"vars" "zip" "__import__"))
; Regex from the `re` module
(call
function: (attribute
object: (identifier) @_re)
arguments: (argument_list
(string
(string_content) @string.regexp))
(#eq? @_re "re"))
(call
function: (attribute
object: (identifier) @_re)
arguments: (argument_list
(concatenated_string
(string
(string_content) @string.regexp)))
(#eq? @_re "re"))
; Decorators
((decorator
"@" @attribute)
(#set! priority 101))
(decorator
(identifier) @attribute)
(decorator
(attribute
attribute: (identifier) @attribute))
(decorator
(call
(identifier) @attribute))
(decorator
(call
(attribute
attribute: (identifier) @attribute)))
((decorator
(identifier) @attribute.builtin)
(#any-of? @attribute.builtin "classmethod" "property" "staticmethod"))

View file

@ -0,0 +1,319 @@
; Variables
[
(identifier)
(global_variable)
] @variable
; Keywords
[
"alias"
"begin"
"do"
"end"
"ensure"
"module"
"rescue"
"then"
] @keyword
"class" @keyword.type
[
"return"
"yield"
] @keyword.return
[
"and"
"or"
"in"
"not"
] @keyword.operator
[
"def"
"undef"
] @keyword.function
(method
"end" @keyword.function)
[
"case"
"else"
"elsif"
"if"
"unless"
"when"
"then"
] @keyword.conditional
(in_clause
"in" @keyword.conditional)
(if
"end" @keyword.conditional)
[
"for"
"until"
"while"
"break"
"redo"
"retry"
"next"
] @keyword.repeat
(in
"in" @keyword.repeat)
(constant) @constant
((identifier) @keyword.modifier
(#any-of? @keyword.modifier "private" "protected" "public"))
[
"rescue"
"ensure"
] @keyword.exception
; Function calls
"defined?" @function
(call
receiver: (constant)? @type
method: [
(identifier)
(constant)
] @function.call)
(program
(call
(identifier) @keyword.import)
(#any-of? @keyword.import "require" "require_relative" "load"))
; Function definitions
(alias
(identifier) @function)
(setter
(identifier) @function)
(method
name: [
(identifier) @function
(constant) @type
])
(singleton_method
name: [
(identifier) @function
(constant) @type
])
(class
name: (constant) @type)
(module
name: (constant) @type)
(superclass
(constant) @type)
; Identifiers
[
(class_variable)
(instance_variable)
] @variable.member
((identifier) @constant.builtin
(#any-of? @constant.builtin
"__callee__" "__dir__" "__id__" "__method__" "__send__" "__ENCODING__" "__FILE__" "__LINE__"))
((identifier) @function.builtin
(#any-of? @function.builtin "attr_reader" "attr_writer" "attr_accessor" "module_function"))
((call
!receiver
method: (identifier) @function.builtin)
(#any-of? @function.builtin "include" "extend" "prepend" "refine" "using"))
((identifier) @keyword.exception
(#any-of? @keyword.exception "raise" "fail" "catch" "throw"))
((constant) @type
(#not-lua-match? @type "^[A-Z0-9_]+$"))
[
(self)
(super)
] @variable.builtin
(method_parameters
(identifier) @variable.parameter)
(lambda_parameters
(identifier) @variable.parameter)
(block_parameters
(identifier) @variable.parameter)
(splat_parameter
(identifier) @variable.parameter)
(hash_splat_parameter
(identifier) @variable.parameter)
(optional_parameter
(identifier) @variable.parameter)
(destructured_parameter
(identifier) @variable.parameter)
(block_parameter
(identifier) @variable.parameter)
(keyword_parameter
(identifier) @variable.parameter)
; Literals
[
(string_content)
(heredoc_content)
"\""
"`"
] @string
[
(heredoc_beginning)
(heredoc_end)
] @label
[
(bare_symbol)
(simple_symbol)
(hash_key_symbol)
] @string.special.symbol
(delimited_symbol
":\"" @string.special.symbol
(string_content) @string.special.symbol
"\"" @string.special.symbol)
(regex
(string_content) @string.regexp)
(escape_sequence) @string.escape
(integer) @number
(float) @number.float
[
(true)
(false)
] @boolean
(nil) @constant.builtin
(comment) @comment @spell
((program
.
(comment) @keyword.directive @nospell)
(#lua-match? @keyword.directive "^#!/"))
(program
(comment)+ @comment.documentation
(class))
(module
(comment)+ @comment.documentation
(body_statement
(class)))
(class
(comment)+ @comment.documentation
(body_statement
(method)))
(body_statement
(comment)+ @comment.documentation
(method))
; Operators
[
"!"
"="
"=="
"==="
"<=>"
"=>"
"->"
">>"
"<<"
">"
"<"
">="
"<="
"**"
"*"
"/"
"%"
"+"
"-"
"&"
"|"
"^"
"&&"
"||"
"||="
"&&="
"!="
"%="
"+="
"-="
"*="
"/="
"=~"
"!~"
"?"
":"
".."
"..."
] @operator
[
","
";"
"."
"&."
"::"
] @punctuation.delimiter
(regex
"/" @punctuation.bracket)
(pair
":" @punctuation.delimiter)
(keyword_pattern
":" @punctuation.delimiter)
[
"("
")"
"["
"]"
"{"
"}"
"%w("
"%i("
] @punctuation.bracket
(block_parameters
"|" @punctuation.bracket)
(interpolation
"#{" @punctuation.special
"}" @punctuation.special)

View file

@ -0,0 +1,534 @@
; Forked from https://github.com/tree-sitter/tree-sitter-rust
; Copyright (c) 2017 Maxim Sokolov
; Licensed under the MIT license.
; Identifier conventions
(shebang) @keyword.directive
(identifier) @variable
((identifier) @type
(#lua-match? @type "^[A-Z]"))
(const_item
name: (identifier) @constant)
; Assume all-caps names are constants
((identifier) @constant
(#lua-match? @constant "^[A-Z][A-Z%d_]*$"))
; Other identifiers
(type_identifier) @type
(primitive_type) @type.builtin
(field_identifier) @variable.member
(shorthand_field_identifier) @variable.member
(shorthand_field_initializer
(identifier) @variable.member)
(mod_item
name: (identifier) @module)
(self) @variable.builtin
"_" @character.special
(label
[
"'"
(identifier)
] @label)
; Function definitions
(function_item
(identifier) @function)
(function_signature_item
(identifier) @function)
(parameter
[
(identifier)
"_"
] @variable.parameter)
(parameter
(ref_pattern
[
(mut_pattern
(identifier) @variable.parameter)
(identifier) @variable.parameter
]))
(closure_parameters
(_) @variable.parameter)
; Function calls
(call_expression
function: (identifier) @function.call)
(call_expression
function: (scoped_identifier
(identifier) @function.call .))
(call_expression
function: (field_expression
field: (field_identifier) @function.call))
(generic_function
function: (identifier) @function.call)
(generic_function
function: (scoped_identifier
name: (identifier) @function.call))
(generic_function
function: (field_expression
field: (field_identifier) @function.call))
; Assume other uppercase names are enum constructors
((field_identifier) @constant
(#lua-match? @constant "^[A-Z]"))
(enum_variant
name: (identifier) @constant)
; Assume that uppercase names in paths are types
(scoped_identifier
path: (identifier) @module)
(scoped_identifier
(scoped_identifier
name: (identifier) @module))
(scoped_type_identifier
path: (identifier) @module)
(scoped_type_identifier
path: (identifier) @type
(#lua-match? @type "^[A-Z]"))
(scoped_type_identifier
(scoped_identifier
name: (identifier) @module))
((scoped_identifier
path: (identifier) @type)
(#lua-match? @type "^[A-Z]"))
((scoped_identifier
name: (identifier) @type)
(#lua-match? @type "^[A-Z]"))
((scoped_identifier
name: (identifier) @constant)
(#lua-match? @constant "^[A-Z][A-Z%d_]*$"))
((scoped_identifier
path: (identifier) @type
name: (identifier) @constant)
(#lua-match? @type "^[A-Z]")
(#lua-match? @constant "^[A-Z]"))
((scoped_type_identifier
path: (identifier) @type
name: (type_identifier) @constant)
(#lua-match? @type "^[A-Z]")
(#lua-match? @constant "^[A-Z]"))
[
(crate)
(super)
] @module
(scoped_use_list
path: (identifier) @module)
(scoped_use_list
path: (scoped_identifier
(identifier) @module))
(use_list
(scoped_identifier
(identifier) @module
.
(_)))
(use_list
(identifier) @type
(#lua-match? @type "^[A-Z]"))
(use_as_clause
alias: (identifier) @type
(#lua-match? @type "^[A-Z]"))
; Correct enum constructors
(call_expression
function: (scoped_identifier
"::"
name: (identifier) @constant)
(#lua-match? @constant "^[A-Z]"))
; Assume uppercase names in a match arm are constants.
((match_arm
pattern: (match_pattern
(identifier) @constant))
(#lua-match? @constant "^[A-Z]"))
((match_arm
pattern: (match_pattern
(scoped_identifier
name: (identifier) @constant)))
(#lua-match? @constant "^[A-Z]"))
((identifier) @constant.builtin
(#any-of? @constant.builtin "Some" "None" "Ok" "Err"))
; Macro definitions
"$" @function.macro
(metavariable) @function.macro
(macro_definition
"macro_rules!" @function.macro)
; Attribute macros
(attribute_item
(attribute
(identifier) @function.macro))
(inner_attribute_item
(attribute
(identifier) @function.macro))
(attribute
(scoped_identifier
(identifier) @function.macro .))
; Derive macros (assume all arguments are types)
; (attribute
; (identifier) @_name
; arguments: (attribute (attribute (identifier) @type))
; (#eq? @_name "derive"))
; Function-like macros
(macro_invocation
macro: (identifier) @function.macro)
(macro_invocation
macro: (scoped_identifier
(identifier) @function.macro .))
; Literals
(boolean_literal) @boolean
(integer_literal) @number
(float_literal) @number.float
[
(raw_string_literal)
(string_literal)
] @string
(escape_sequence) @string.escape
(char_literal) @character
; Keywords
[
"use"
"mod"
] @keyword.import
(use_as_clause
"as" @keyword.import)
[
"default"
"impl"
"let"
"move"
"unsafe"
"where"
] @keyword
[
"enum"
"struct"
"union"
"trait"
"type"
] @keyword.type
[
"async"
"await"
"gen"
] @keyword.coroutine
"try" @keyword.exception
[
"ref"
"pub"
"raw"
(mutable_specifier)
"const"
"static"
"dyn"
"extern"
] @keyword.modifier
(lifetime
"'" @keyword.modifier)
(lifetime
(identifier) @attribute)
(lifetime
(identifier) @attribute.builtin
(#any-of? @attribute.builtin "static" "_"))
"fn" @keyword.function
[
"return"
"yield"
] @keyword.return
(type_cast_expression
"as" @keyword.operator)
(qualified_type
"as" @keyword.operator)
(use_list
(self) @module)
(scoped_use_list
(self) @module)
(scoped_identifier
[
(crate)
(super)
(self)
] @module)
(visibility_modifier
[
(crate)
(super)
(self)
] @module)
[
"if"
"else"
"match"
] @keyword.conditional
[
"break"
"continue"
"in"
"loop"
"while"
] @keyword.repeat
"for" @keyword
(for_expression
"for" @keyword.repeat)
; Operators
[
"!"
"!="
"%"
"%="
"&"
"&&"
"&="
"*"
"*="
"+"
"+="
"-"
"-="
".."
"..="
"..."
"/"
"/="
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"?"
"@"
"^"
"^="
"|"
"|="
"||"
] @operator
(use_wildcard
"*" @character.special)
(remaining_field_pattern
".." @character.special)
(range_pattern
[
".."
"..="
"..."
] @character.special)
; Punctuation
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
(closure_parameters
"|" @punctuation.bracket)
(type_arguments
[
"<"
">"
] @punctuation.bracket)
(type_parameters
[
"<"
">"
] @punctuation.bracket)
(bracketed_type
[
"<"
">"
] @punctuation.bracket)
(for_lifetimes
[
"<"
">"
] @punctuation.bracket)
[
","
"."
":"
"::"
";"
"->"
"=>"
] @punctuation.delimiter
(attribute_item
"#" @punctuation.special)
(inner_attribute_item
[
"!"
"#"
] @punctuation.special)
(macro_invocation
"!" @function.macro)
(never_type
"!" @type.builtin)
(macro_invocation
macro: (identifier) @_identifier @keyword.exception
"!" @keyword.exception
(#eq? @_identifier "panic"))
(macro_invocation
macro: (identifier) @_identifier @keyword.exception
"!" @keyword.exception
(#contains? @_identifier "assert"))
(macro_invocation
macro: (identifier) @_identifier @keyword.debug
"!" @keyword.debug
(#eq? @_identifier "dbg"))
; Comments
[
(line_comment)
(block_comment)
] @comment @spell
[
(outer_doc_comment_marker)
(inner_doc_comment_marker)
] @comment.documentation
(line_comment
(doc_comment)) @comment.documentation
(block_comment
(doc_comment)) @comment.documentation
(call_expression
function: (scoped_identifier
path: (identifier) @_regex
(#any-of? @_regex "Regex" "ByteRegexBuilder")
name: (identifier) @_new
(#eq? @_new "new"))
arguments: (arguments
(raw_string_literal
(string_content) @string.regexp)))
(call_expression
function: (scoped_identifier
path: (scoped_identifier
(identifier) @_regex
(#any-of? @_regex "Regex" "ByteRegexBuilder") .)
name: (identifier) @_new
(#eq? @_new "new"))
arguments: (arguments
(raw_string_literal
(string_content) @string.regexp)))
(call_expression
function: (scoped_identifier
path: (identifier) @_regex
(#any-of? @_regex "RegexSet" "RegexSetBuilder")
name: (identifier) @_new
(#eq? @_new "new"))
arguments: (arguments
(array_expression
(raw_string_literal
(string_content) @string.regexp))))
(call_expression
function: (scoped_identifier
path: (scoped_identifier
(identifier) @_regex
(#any-of? @_regex "RegexSet" "RegexSetBuilder") .)
name: (identifier) @_new
(#eq? @_new "new"))
arguments: (arguments
(array_expression
(raw_string_literal
(string_content) @string.regexp))))

View file

@ -0,0 +1,208 @@
; inherits: ecma
"require" @keyword.import
(import_require_clause
source: (string) @string.special.url)
[
"declare"
"implements"
"type"
"override"
"module"
"asserts"
"infer"
"is"
"using"
] @keyword
[
"namespace"
"interface"
"enum"
] @keyword.type
[
"keyof"
"satisfies"
] @keyword.operator
(as_expression
"as" @keyword.operator)
(mapped_type_clause
"as" @keyword.operator)
[
"abstract"
"private"
"protected"
"public"
"readonly"
] @keyword.modifier
; types
(type_identifier) @type
(predefined_type) @type.builtin
(import_statement
"type"
(import_clause
(named_imports
(import_specifier
name: (identifier) @type))))
(template_literal_type) @string
(non_null_expression
"!" @operator)
; punctuation
(type_arguments
[
"<"
">"
] @punctuation.bracket)
(type_parameters
[
"<"
">"
] @punctuation.bracket)
(object_type
[
"{|"
"|}"
] @punctuation.bracket)
(union_type
"|" @punctuation.delimiter)
(intersection_type
"&" @punctuation.delimiter)
(type_annotation
":" @punctuation.delimiter)
(type_predicate_annotation
":" @punctuation.delimiter)
(index_signature
":" @punctuation.delimiter)
(omitting_type_annotation
"-?:" @punctuation.delimiter)
(adding_type_annotation
"+?:" @punctuation.delimiter)
(opting_type_annotation
"?:" @punctuation.delimiter)
"?." @punctuation.delimiter
(abstract_method_signature
"?" @punctuation.special)
(method_signature
"?" @punctuation.special)
(method_definition
"?" @punctuation.special)
(property_signature
"?" @punctuation.special)
(optional_parameter
"?" @punctuation.special)
(optional_type
"?" @punctuation.special)
(public_field_definition
[
"?"
"!"
] @punctuation.special)
(flow_maybe_type
"?" @punctuation.special)
(template_type
[
"${"
"}"
] @punctuation.special)
(conditional_type
[
"?"
":"
] @keyword.conditional.ternary)
; Parameters
(required_parameter
pattern: (identifier) @variable.parameter)
(optional_parameter
pattern: (identifier) @variable.parameter)
(required_parameter
(rest_pattern
(identifier) @variable.parameter))
; ({ a }) => null
(required_parameter
(object_pattern
(shorthand_property_identifier_pattern) @variable.parameter))
; ({ a = b }) => null
(required_parameter
(object_pattern
(object_assignment_pattern
(shorthand_property_identifier_pattern) @variable.parameter)))
; ({ a: b }) => null
(required_parameter
(object_pattern
(pair_pattern
value: (identifier) @variable.parameter)))
; ([ a ]) => null
(required_parameter
(array_pattern
(identifier) @variable.parameter))
; a => null
(arrow_function
parameter: (identifier) @variable.parameter)
; global declaration
(ambient_declaration
"global" @module)
; function signatures
(ambient_declaration
(function_signature
name: (identifier) @function))
; method signatures
(method_signature
name: (_) @function.method)
(abstract_method_signature
name: (property_identifier) @function.method)
; property signatures
(property_signature
name: (property_identifier) @function.method
type: (type_annotation
[
(union_type
(parenthesized_type
(function_type)))
(function_type)
]))

View file

@ -0,0 +1,119 @@
# Community tags.scm — Source Audit
Audit date: July 3, 2026
Source: Individual tree-sitter grammar repos (NOT nvim-treesitter)
## Correction
Existing `references/tags-queries/` files match grammar-repo content, NOT
nvim-treesitter. The ANALYSIS.md report checked only nvim-treesitter (404).
All grammar repos have live tags.scm.
## Availability
| Language | Grammar Repo | Has tags.scm? |
|----------|-------------|---------------|
| Python | tree-sitter/tree-sitter-python | YES |
| JavaScript | tree-sitter/tree-sitter-javascript | YES |
| Ruby | tree-sitter/tree-sitter-ruby | YES |
| Go | tree-sitter/tree-sitter-go | YES |
| Rust | tree-sitter/tree-sitter-rust | YES |
| Java | tree-sitter/tree-sitter-java | YES |
| C | tree-sitter/tree-sitter-c | YES |
| C++ | tree-sitter/tree-sitter-cpp | YES |
| TypeScript | tree-sitter/tree-sitter-typescript | YES |
| Kotlin | fwcd/tree-sitter-kotlin | YES |
## Captures Per Language
### Python
- `@definition.class` — class_definition name
- `@definition.function` — function_definition name
- `@definition.constant` — module-level assignment LHS
- `@reference.call` — call function (identifier or attribute)
### JavaScript
- `@definition.class` — class / class_declaration
- `@definition.function` — function_declaration, function_expression, arrow_function
- `@definition.method` — method_definition
- `@definition.constant` — export_statement with value
- `@reference.call` — call_expression function name
- `@reference.class` — new_expression constructor
### Ruby
- `@definition.class` — class / singleton_class
- `@definition.method` — method / singleton_method / alias
- `@definition.module` — module
- `@reference.call` — call method / identifier
### Go
- `@definition.function` — function_declaration
- `@definition.method` — method_declaration
- `@definition.type` — type_spec
- `@reference.call` — call_expression (direct + selector)
- `@reference.type` — type_identifier references
- Plus: package, import, var, const, struct, interface declarations
### Rust
- `@definition.class` — struct / enum / union / type_item
- `@definition.function` — function_item
- `@definition.method` — function_item in declaration_list
- `@definition.interface` — trait_item
- `@definition.module` — mod_item
- `@definition.macro` — macro_definition
- `@reference.call` — call_expression (direct + field + macro)
- `@reference.implementation` — impl_item
### Java
- `@definition.class` — class_declaration
- `@definition.method` — method_declaration
- `@definition.interface` — interface_declaration
- `@reference.call` — method_invocation with argument_list
- `@reference.implementation` — type_list in implements
- `@reference.class` — object_creation_expression, superclass
### C
- `@definition.class` — struct_specifier
- `@definition.function` — function_declarator
- `@definition.type` — type_definition, enum_specifier
### C++
- `@definition.class` — struct_specifier, union_specifier, class_specifier
- `@definition.function` — function_declarator (identifier)
- `@definition.method` — function_declarator (qualified_identifier)
- `@definition.type` — type_definition, enum_specifier
### TypeScript
- `@definition.function` — function_signature
- `@definition.method` — method_signature, abstract_method_signature
- `@definition.class` — abstract_class_declaration
- `@definition.module` — module
- `@definition.interface` — interface_declaration
- `@reference.type` — type_annotation
- `@reference.class` — new_expression
### Kotlin
- `@definition.class` — class_declaration, object_declaration, companion_object
- `@definition.function` — function_declaration (simple_identifier)
- `@definition.constant` — property_declaration, enum_entry
- `@definition.type` — type_alias
- `@reference.call` — call_expression, navigation_expression
- `@reference.class` — constructor_invocation
## Core Vocabulary (present in all)
- `@definition.*` — declaration/definition sites
- `@reference.*` — usage/reference sites
## Gaps vs Dervish Sequence Needs
| Need | Present in any community tags.scm? |
|------|-----------------------------------|
| Call tracking | Java, Python, Go, Rust, Kotlin, JS, Ruby |
| Constructor tracking | Java, TypeScript, Kotlin, JS |
| Class/method/function defs | All |
| Control flow (if/else/when) | **0 languages** |
| Error handling (try/catch/throw) | **0 languages** |
| Return statements | **0 languages** |
| Annotations/decorators | **0 languages** |
| Ordered sequences | **0 languages** |

File diff suppressed because it is too large Load diff

2881
references/gemini-chat1.md Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1199
references/gemini-chat2.md Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

2232
references/gemini-chat3.md Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1991
references/gemini-chat4.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,207 @@
# Dervish / BEX — Complete Conversation Summary
## Overview
4 Gemini conversations from 2026-07-03 (all from same session, branching at different points).
All revolve around BEX grammar inference algorithms and the Dervish MCP tool.
---
## Chat 1: "LLMs, Agenten und Schema-Inferenz" (32 turns)
**Model:** 3.5 Flash | **Link:** share/8fce4fbdf14a
### Flow
1. Starts with arXiv:1004.2372 (Bex et al. — XML schema inference via k-OREs)
2. Gemini proposes 4 application areas for LLM agents:
- **① Workflow Discovery** — infer state machines from agent traces
- **② Dynamic Schema Generation** — distill JSON/XML schemas from unstructured data for grammar-guided decoding
- **③ API Reverse Engineering** — infer API structure from probe calls
- **④ Prompt Injection Defense** — detect structural anomalies in incoming data
3. User picks **#3** (API reverse engineering), explores MCP tools
4. Shifts focus to **#1 extended: Code Generation patterns** (IaC, CI/CD pipelines)
5. **Key insight:** BEX can learn the *unwritten conventions* of existing codebases
6. User requests Python implementation of all BEX algorithms from paper pseudocode
7. Multiple BEX papers explored:
- Bex et al. 2010 (k-OREs, the main paper)
- Bex, Neven, Vansummeren 2008 (DTD inference — simpler, less powerful)
- Bex, Neven, Schwentick, Vansummeren 2010 (concise regex + DTDs)
8. **Paradigm shift:** XML → **YAML-native**. YAML is trees too, no XML intermediate needed
9. User requests actual pseudocode extraction from PDFs (not AI-generated hallucinations)
10. **Escalation:** User frustrated when Gemini can't find real papers about formal grammars helping agents (hallucinates fake sources). Ends with user abandoning Gemini as search engine
### Key Decisions
- Focus on **code generation patterns** as primary application
- **YAML-native** approach (no XML intermediate)
- Multiple BEX papers needed for full algorithm coverage
---
## Chat 2: "Regex Power Beyond Formal Definitions" (14 turns)
**Model:** 3.5 Flash | **Link:** share/d100a2d42200
### Flow
1. Regex primitives (concatenation, disjunction, iteration) vs modern regex
2. **Grammar Induction** from positive examples only (Gold's Theorem — impossible in general case)
3. BEX algorithms as the practical solution to this problem
4. Improvements on BEX: interleaving (.), higher k-values
5. User: "I have implemented BEX but I'm intrigued by interleaving"
6. Dervish README walkthrough
7. **embabel agent** discussion: JVM-based agent framework with typed actions
8. GOAP (Goal-Oriented Action Planning) + Dervish — infer action preconditions from examples
9. **Convention monitoring idea:** Dervish observes agent, detects when patterns become conventions
### Key Decisions
- BEX improvements needed: interleaving, higher k
- Dervish could act as **passive convention observer** for agents
---
## Chat 3: "Dervish: Grammar Inference for LLM Agents" (32 turns)
**Model:** 3.1 Pro | **Link:** share/0f836d3c25ba
### Flow (Turns 1-27 — shared with Chat 4)
#### Phase: README Polish (Turns 1-5)
- README paste → improve "MDL" wording
- Add **generative schema** section (infer grammar → generate sample data)
- Add "Why not just use a schema?" section
#### Phase: Architecture Discovery (Turns 6-10)
- Question: **Can Dervish analyze Java/Kotlin codebases?**
- Answer: Language structure ≠ code conventions. Dervish needs *behavioral* sequences
- **Turn 7: DomainRouter pre-detection** idea — detect context (source code vs YAML) before choosing algorithm
- **Turn 8: MDL Ensemble insight** — Dervish already runs all algorithms and picks best by MDL. No need for pre-detection!
- **Turn 9: Single-pass heuristic** — maybe we don't need all algorithms, can derive coverage levels from one pass
#### Phase: TreeSitter Revolution (Turns 10-17)
- **Turn 10: Language-agnostic breakthrough** — Dervish is absolutely language-agnostic, can analyze any codebase
- **Turn 11: Prior art needed** — is there existing research on grammar inference from ASTs?
- **Turn 12: TreeSitter AST pipeline** — extract AST nodes → flatten to sequences → Dervish infers grammar
- **Turn 13-14: Concrete Java examples** — spring boot controllers, which AST nodes matter
- **Turn 15: Repository vs directory scoping** — how does Dervish know where conventions boundaries are?
- **Turn 16: Avoiding per-language heuristics** — must be zero-config
- **Turn 17: Novelty confirmed** — no prior work on grammar inference from TreeSitter ASTs. This is a genuine research contribution
#### Phase: Roadmap Definition (Turns 18-20)
- **Formal roadmap defined:**
- **1.0: Code Repository Analysis** — TreeSitter → AST nodes → Dervish grammar
- **1.1: Structured Data** (YAML, XML, JSON) — existing feature, enhance
- **1.2: Markdown/Document AST** — DISCUSSED THEN **DROPPED** (too fuzzy)
- **2.0: Cross-file conventions** — class hierarchies, test patterns, file-level relationships
- **1.2 dropped** — documents too fuzzy
#### Phase: Implementation Design (Turns 21-27)
- **Features first, combined later** — code analysis separate from structured data
- **Interesting nodes** — NOT per-language heuristic! Use **TreeSitter's built-in tag queries** (tags.scm)
- Universal query approach: a single query works across languages (annotation→@meta, call_expression→@call, try_statement→@block)
- **Community tags.scm** for 100% coverage (Zero maintenance)
- **Single-pass frequency analysis** — count symbol frequency across files, filter outliers < threshold
- **Concrete example with Spring Boot:**
- Raw AST: `['@RestController', '@RequestMapping', '@PostMapping', 'log.info', 'dto.getItems', 'dto.getItems.isEmpty', 'orderService.process', 'ResponseEntity.ok']`
- After frequency filter: remove `dto.getItems` (occurs in 1/10 files)
- Result: convention grammar for Spring Boot controllers
- **Critical concern (Turn 27):** Will Dervish find genuinely novel insights or just obvious patterns?
#### Phase: Broader Vision (Turns 28-32 — UNIQUE TO CHAT 3)
- **BEX in LLM training/design** — structural tokenization (replace BPE with grammar-guided), Skeleton-of-Thought patterns
- **Paper title proposals:**
1. "DERVISH: Neuro-Symbolic Code Generation via MDL-Optimized Structural Grammars"
2. "AST2Regex: Mining Implicit Conventions from Abstract Syntax Trees"
3. "Grammar is All You Need: Zero-Shot Convention Learning for LLMs"
- **Terminology debate:** "skeleton" bad, prefer "grammar" or "schema"
- **Grammar-Constrained Decoding (GCD)** research — position Dervish as bridging structured output generation
- Final task: deep research into GCD + neuro-symbolic generation literature
### Key Decisions
- **TreeSitter AST → Dervish pipeline** is the core architecture
- **No per-language heuristics** — use TreeSitter's universal node types and community tag queries
- **Single-pass frequency analysis** filters noise
- **1.2 (documents) dropped** — focus on code repos + structured data
- **Features isolated** before integration
- **This is novel research** — no prior work on grammar inference from TreeSitter ASTs
---
## Chat 4: "Dervish: Grammar Inference for LLM Agents" (27 turns)
**Model:** 3.1 Pro | **Link:** share/a5ff288e0fdf
### Relationship to Chat 3
- **IDENTICAL to Chat 3 for Turns 1-27** (same conversation, same user messages, same AI responses)
- **Ends at Turn 27** — Chat 3 continues with 5 additional turns (28-32)
- Chat 4 = the "short branch" of the conversation
---
## Divergence Map
```
Chat 1 (32 turns) — LLMs/Agenten/Schema
─────────────────────────────────
Separate conversation, different focus (MCP, YAML-native, PDF algorithms)
Chat 2 (14 turns) — Regex theory
─────────────────────────────────
Separate conversation, different focus (regex theory, embabel, GOAP)
Chat 3 (32 turns) — Dervish: Grammar Inference
Chat 4 (27 turns) — Dervish: Grammar Inference
├── Turns 1-5: README polish (MDL wording, generative schema section)
├── Turns 6-10: Architecture (DomainRouter, MDL ensemble, TreeSitter idea)
├── Turns 11-17: TreeSitter deep dive (language-agnostic, prior art, roadmapping)
├── Turns 18-20: Formal roadmap, 1.2 dropped
├── Turns 21-27: Implementation design (tags queries, frequency analysis, Spring Boot example)
└── Turn 27: "Will it find genuine insights?" (SAME question in both)
├── Chat 3 continues (Turns 28-32)
│ ├── 28: BEX in LLM training (structural tokenization, SoT)
│ ├── 29: Paper search on GCD approaches
│ ├── 30: arXiv paper title proposals
│ ├── 31: Terminology debate (grammar vs skeleton)
│ └── 32: GCD research assignment
└── Chat 4 ENDS at Turn 27
```
---
## Planned Feature Roadmap (from Chats 3-4)
### Phase 1.0: Code Repository Analysis (TreeSitter AST → Dervish)
1. **Language detection** (file extension, MIME type)
2. **TreeSitter parsing** with language-specific grammar
3. **UNIVERSAL_STRUCTURE_QUERY** (single query for all languages):
- `(call_expression) @call`
- `(annotation) @meta` / `(decorator) @meta`
- `(try_statement) @block` / `(catch_clause) @block`
- Alternatively: load community `tags.scm` for each language
4. **Single-pass frequency analysis** — count symbol frequency across files, filter outliers below threshold
5. **Dervish inference** on cleaned sequences → compact grammar
6. **Output:** ~60-200 token rule representing codebase conventions
### Phase 1.1: Structured Data (existing feature, enhance)
- YAML/XML/JSON sequences → grammar inference
- Already partially implemented in Dervish
### Phase 1.2: Markdown/Document AST (DROPPED)
- Too fuzzy, documents vary too much
- Not a priority
### Phase 2.0: Cross-File Conventions (future)
- Class hierarchies, test patterns, file-level relationships
- Beyond single-file AST analysis
### Broader Research (Chat 3 extra turns)
- **Structural tokenization** — replace BPE with grammar-guided tokenization
- **Grammar-Constrained Decoding (GCD)** — position Dervish in the GCD ecosystem
- **arXiv paper** — "DERVISH: Neuro-Symbolic Code Generation via MDL-Optimized Structural Grammars"
- **Literature review** — deep search on GCD + neuro-symbolic generation
---
## Repository State
- **Main repo:** grammar-inference-engine (git submodule at `projects/grammar-inference-engine/`)
- **Branch:** `feature/dervish-2`
- **Remote:** `origin → https://forgejo.corentic.eu/tobi/grammar-inference-engine`
- **Current code:** BEX algorithms (CRX, iDRegEx), MCP server, basic ORES/SORE/CHARE types
- **Need 5th Gemini share link** — user mentioned 5 chats, we only have 4

View file

@ -0,0 +1,212 @@
# Community Tree-Sitter Query Analysis
Analyzed: July 3, 2026
Source: nvim-treesitter (master branch) tag queries + highlight queries
## Key Finding
**Community TAGS queries are for code navigation (Go to Definition), NOT for Dervish.**
Dervish needs **behavioral sequences**: what operations happen in what order.
Tags queries only capture declaration sites and reference locations.
## Language-by-Language Gap Analysis
### JAVA
**Tags captures:**
- `@definition.class` — class declaration sites
- `@definition.method` — method declaration sites
- `@definition.interface` — interface declaration sites
- `@reference.call` — method invocations (ONLY with `argument_list`)
- `@reference.implementation` — implements clauses
- `@reference.class``new Type()` expressions + superclass refs
**What is MISSING for Dervish:**
- `@annotation` / `@decorator` — annotations only exist in highlights as `@attribute`, not in tags
- `@reference.call` excludes parameterless calls like `foo()` — requires `argument_list`
- No `throw_statement`, `try_statement`, `catch_clause` in tags
- No `if_statement`, `return_statement` captures
- No mechanism to extract ORDERED sequences
- Highlights collapse all control-flow keywords into `@keyword`
### KOTLIN (from highlights.scm since no tags.scm exists at that path)
**Available captures (highlights only):**
- `@function.call``call_expression` with `simple_identifier`
- `@constructor``constructor_invocation`, `primary_constructor`, secondary
- `@attribute``annotation` with `user_type`
- `@keyword.conditional``if`/`else`/`when`
- `@keyword.repeat``for`/`do`/`while`
- `@keyword.exception``try`/`catch`/`throw`/`finally`
- `@keyword.return``return`
- `@function``function_declaration`
**What is MISSING for Dervish:**
- No tags.scm available on nvim-treesitter master for Kotlin
- Call expressions captured as `@function.call` in highlights, not structured for sequence extraction
- Navigation expressions (`obj.method()`) captured but as `@function.call` on the suffix
- No `when_structure` / `when_condition` structural capture
- No `navigation_expression` itself as a token — only the method name inside
- No sequencing mechanism
### PYTHON
**Tags captures:**
- `@definition.constant` — module-level assignments
- `@definition.class` — class definitions
- `@definition.function` — function definitions
- `@reference.call` — direct function calls + method calls via attribute
**What is MISSING for Dervish:**
- No `decorator` capture in tags (only in highlights as `@function`)
- `call` only captured as reference, not as behavioral sequence token
- No `raise_statement`, `try_statement`, `except_clause` in tags
- No `if_statement`, `return_statement`, `with_statement` in tags
- Highlights `@function` conflates decorators, definitions, and calls
### GO
**Tags captures:**
- `@definition.function` — function declarations (with doc comments)
- `@definition.method` — method declarations
- `@definition.type` — type specs
- `@reference.call` — direct calls + selector calls (`obj.Method()`)
- `@reference.type` — type identifier references
- Plus: var/const/import/struct/interface tracking
**What is MISSING for Dervish:**
- No `defer_statement` capture (only `defer` keyword in highlights)
- No `go` (goroutine launch) as structural capture
- No `if_statement`, `return_statement`, `for_statement`, `switch_statement` in tags
- `call_expression` well captured but only function name as `@name`, not whole expression
- Highlights distinguish builtins (`append`, `len`, `make`, `panic`, etc.) but not structured
### RUST
**Tags captures:**
- `@definition.class` — struct/enum/union/type alias
- `@definition.method` — methods in impl blocks
- `@definition.function` — free functions
- `@definition.interface` — trait definitions
- `@definition.module` — module definitions
- `@definition.macro` — macro definitions
- `@reference.call` — direct calls + method calls + macro invocations
- `@reference.implementation` — trait/inherent impl tracking
**What is MISSING for Dervish:**
- Best coverage of any language — captures calls, macros, implementations
- Still: no `if_expression` / `match_expression` / `return` in tags
- No `unsafe` block capture
- `@attribute` (`#[derive]`) only in highlights, not tags
- No sequencing mechanism
### TYPESCRIPT / JAVASCRIPT
**Tags captures:**
- `@definition.function` — function signatures only (definitions)
- `@definition.method` — method signatures
- `@definition.class` — class + abstract class declarations
- `@definition.module` — module declarations
- `@definition.interface` — interface declarations
- `@reference.type` — type annotations
- `@reference.class``new Foo()` constructor calls
**What is MISSING for Dervish:**
- **NO `call_expression` capture at all** — neither in tags nor highlights
- **NO `@reference.call`** — critical gap
- No function/method call tracking
- Highlight query is extremely minimal (35 lines)
- Missing: `arrow_function`, `call_expression`, `method_invocation`
- Query file seems designed for `.d.ts` type definitions, not implementation code
### C++
**Tags captures:**
- `@definition.class` — struct/union/class specifiers
- `@definition.function` — function declarators
- `@definition.method` — qualified methods (with namespace scope)
- `@definition.type` — typedef/enum
**What is MISSING for Dervish:**
- **NO `call_expression` capture in tags** — call tracking only in highlights as `@function`
- **NO `@reference.call`** in tags at all
- No `template_function`, `template_method` in tags
- No `new_expression`, `delete_expression` in tags
- No `throw_statement`, `try_statement`, `catch_clause` in tags
- No sequencing mechanism
### YAML
**What is MISSING for Dervish:**
- No tags query exists at all
- YAML is data-oriented, not code-oriented
- Highlights only capture data types (strings, numbers, booleans) and key names
- YAML sequence extraction (for Ansible/Helm) needs a different approach entirely
## Cross-Cutting Findings
### What community tags DO capture (for Dervish, partially useful):
| Capture | Languages | Dervish Value |
|---------|-----------|--------------|
| `@reference.call` | Java, Python, Go, Rust | **Partial** — identifies call sites but per-language inconsistencies |
| `@reference.class` / `new` | Java, TypeScript | **Partial** — constructor calls |
| `@reference.implementation` | Java, Rust | Low — inheritance tracking |
| macro invocations (as `@reference.call`) | Rust | **Useful** — Rust macros ARE behavioral tokens |
### What community tags do NOT capture (GAPS):
| Dervish Need | In Tags? | In Highlights? |
|-------------|----------|---------------|
| `@annotation` / `@decorator` / `@attribute` | **0 languages** | Java `@attribute`, Python `@function` (decorator), Rust `@attribute`, Kotlin `@attribute` |
| Control flow (`if`/`else`/`when`) | **0 languages** | All: collapsed in `@keyword` |
| Error handling (`try`/`catch`/`throw`) | **0 languages** | All: collapsed in `@keyword` |
| `@return` | **0 languages** | All: collapsed in `@keyword` |
| Call expressions | Java, Python, Go, Rust | All except TS |
| Ordered sequences | **0 languages** | **0 languages** |
| Variable declarations | Go only | Not structural |
| Resource management (`defer`/`with`) | **0 languages** | Go: `defer` in keyword; Python: `with` in keyword |
| Goroutines / async / coroutines | **0 languages** | Go `go` in keyword; Python async/await in keyword; Kotlin `suspend` as `@keyword.coroutine` |
### The Naming Inconsistency Problem
Same tree-sitter node types have DIFFERENT capture names across languages:
| Node | Java | Python | Go | Rust | C++ | TS |
|------|------|--------|----|------|-----|----|
| call expr | `@reference.call` | `@reference.call` | `@reference.call` | `@reference.call` | NONE | NONE |
| class def | `@definition.class` | `@definition.class` | -- | `@definition.class` | `@definition.class` | `@definition.class` |
| function def | -- | `@definition.function` | `@definition.function` | `@definition.function` | `@definition.function` | `@definition.function` |
Dervish cannot rely on capture names alone. Must either:
1. Use universal query with Dervish-specific capture names, OR
2. Map language-specific capture names to canonical Dervish vocabulary
### Community tags.scm availability on nvim-treesitter master
Checked July 3, 2026 via `raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/master/queries/<lang>/tags.scm`:
| Language | tags.scm exists? | highlights.scm? |
|----------|-----------------|-----------------|
| Java | 404 | yes (in refs) |
| Kotlin | 404 | yes (newly downloaded) |
| Python | 404 | yes (in refs) |
| Go | 404 | yes (in refs) |
| Rust | 404 | yes (in refs) |
| TypeScript | 404 | yes (in refs) |
| C++ | 404 | yes (in refs) |
| YAML | never | yes (in refs) |
All tags.scm returned 404 — nvim-treesitter may have restructured or moved to a different branch/tag.
## Verdict
**Community queries alone are insufficient for Dervish sequence extraction.** They:
1. Purpose-built for navigation, not behavioral sequence extraction
2. Lack critical behavioral captures (annotations, control flow, error handling)
3. Inconsistent across languages
4. No sequencing/traversal mechanism
5. tags.scm no longer available on nvim-treesitter master
A **universal query file** (like the deleted `universal.scm`) using actual tree-sitter node type names is the correct approach, supplemented by a custom AST traversal to produce ordered sequences.

View file

@ -0,0 +1,70 @@
; Functions
(call_expression
function: (qualified_identifier
name: (identifier) @function))
(template_function
name: (identifier) @function)
(template_method
name: (field_identifier) @function)
(template_function
name: (identifier) @function)
(function_declarator
declarator: (qualified_identifier
name: (identifier) @function))
(function_declarator
declarator: (field_identifier) @function)
; Types
((namespace_identifier) @type
(#match? @type "^[A-Z]"))
(auto) @type
; Constants
(this) @variable.builtin
(null "nullptr" @constant)
; Keywords
[
"catch"
"class"
"co_await"
"co_return"
"co_yield"
"constexpr"
"constinit"
"consteval"
"delete"
"explicit"
"final"
"friend"
"mutable"
"namespace"
"noexcept"
"new"
"override"
"private"
"protected"
"public"
"template"
"throw"
"try"
"typename"
"using"
"concept"
"requires"
"virtual"
] @keyword
; Strings
(raw_string_literal) @string

View file

@ -0,0 +1,3 @@
(raw_string_literal
delimiter: (raw_string_delimiter) @injection.language
(raw_string_content) @injection.content)

View file

@ -0,0 +1,15 @@
(struct_specifier name: (type_identifier) @name body:(_)) @definition.class
(declaration type: (union_specifier name: (type_identifier) @name)) @definition.class
(function_declarator declarator: (identifier) @name) @definition.function
(function_declarator declarator: (field_identifier) @name) @definition.function
(function_declarator declarator: (qualified_identifier scope: (namespace_identifier) @local.scope name: (identifier) @name)) @definition.method
(type_definition declarator: (type_identifier) @name) @definition.type
(enum_specifier name: (type_identifier) @name) @definition.type
(class_specifier name: (type_identifier) @name) @definition.class

View file

@ -0,0 +1,123 @@
; Function calls
(call_expression
function: (identifier) @function)
(call_expression
function: (identifier) @function.builtin
(#match? @function.builtin "^(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)$"))
(call_expression
function: (selector_expression
field: (field_identifier) @function.method))
; Function definitions
(function_declaration
name: (identifier) @function)
(method_declaration
name: (field_identifier) @function.method)
; Identifiers
(type_identifier) @type
(field_identifier) @property
(identifier) @variable
; Operators
[
"--"
"-"
"-="
":="
"!"
"!="
"..."
"*"
"*"
"*="
"/"
"/="
"&"
"&&"
"&="
"%"
"%="
"^"
"^="
"+"
"++"
"+="
"<-"
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"|"
"|="
"||"
"~"
] @operator
; Keywords
[
"break"
"case"
"chan"
"const"
"continue"
"default"
"defer"
"else"
"fallthrough"
"for"
"func"
"go"
"goto"
"if"
"import"
"interface"
"map"
"package"
"range"
"return"
"select"
"struct"
"switch"
"type"
"var"
] @keyword
; Literals
[
(interpreted_string_literal)
(raw_string_literal)
(rune_literal)
] @string
(escape_sequence) @escape
[
(int_literal)
(float_literal)
(imaginary_literal)
] @number
[
(true)
(false)
(nil)
(iota)
] @constant.builtin
(comment) @comment

View file

@ -0,0 +1,42 @@
(
(comment)* @doc
.
(function_declaration
name: (identifier) @name) @definition.function
(#strip! @doc "^//\\s*")
(#set-adjacent! @doc @definition.function)
)
(
(comment)* @doc
.
(method_declaration
name: (field_identifier) @name) @definition.method
(#strip! @doc "^//\\s*")
(#set-adjacent! @doc @definition.method)
)
(call_expression
function: [
(identifier) @name
(parenthesized_expression (identifier) @name)
(selector_expression field: (field_identifier) @name)
(parenthesized_expression (selector_expression field: (field_identifier) @name))
]) @reference.call
(type_spec
name: (type_identifier) @name) @definition.type
(type_identifier) @name @reference.type
(package_clause "package" (package_identifier) @name)
(type_declaration (type_spec name: (type_identifier) @name type: (interface_type)))
(type_declaration (type_spec name: (type_identifier) @name type: (struct_type)))
(import_declaration (import_spec) @name)
(var_declaration (var_spec name: (identifier) @name))
(const_declaration (const_spec name: (identifier) @name))

View file

@ -0,0 +1,149 @@
; Variables
(identifier) @variable
; Methods
(method_declaration
name: (identifier) @function.method)
(method_invocation
name: (identifier) @function.method)
(super) @function.builtin
; Annotations
(annotation
name: (identifier) @attribute)
(marker_annotation
name: (identifier) @attribute)
"@" @operator
; Types
(type_identifier) @type
(interface_declaration
name: (identifier) @type)
(class_declaration
name: (identifier) @type)
(enum_declaration
name: (identifier) @type)
((field_access
object: (identifier) @type)
(#match? @type "^[A-Z]"))
((scoped_identifier
scope: (identifier) @type)
(#match? @type "^[A-Z]"))
((method_invocation
object: (identifier) @type)
(#match? @type "^[A-Z]"))
((method_reference
. (identifier) @type)
(#match? @type "^[A-Z]"))
(constructor_declaration
name: (identifier) @type)
[
(boolean_type)
(integral_type)
(floating_point_type)
(floating_point_type)
(void_type)
] @type.builtin
; Constants
((identifier) @constant
(#match? @constant "^_*[A-Z][A-Z\\d_]+$"))
; Builtins
(this) @variable.builtin
; Literals
[
(hex_integer_literal)
(decimal_integer_literal)
(octal_integer_literal)
(decimal_floating_point_literal)
(hex_floating_point_literal)
] @number
[
(character_literal)
(string_literal)
] @string
(escape_sequence) @string.escape
[
(true)
(false)
(null_literal)
] @constant.builtin
[
(line_comment)
(block_comment)
] @comment
; Keywords
[
"abstract"
"assert"
"break"
"case"
"catch"
"class"
"continue"
"default"
"do"
"else"
"enum"
"exports"
"extends"
"final"
"finally"
"for"
"if"
"implements"
"import"
"instanceof"
"interface"
"module"
"native"
"new"
"non-sealed"
"open"
"opens"
"package"
"permits"
"private"
"protected"
"provides"
"public"
"requires"
"record"
"return"
"sealed"
"static"
"strictfp"
"switch"
"synchronized"
"throw"
"throws"
"to"
"transient"
"transitive"
"try"
"uses"
"volatile"
"when"
"while"
"with"
"yield"
] @keyword

View file

@ -0,0 +1,20 @@
(class_declaration
name: (identifier) @name) @definition.class
(method_declaration
name: (identifier) @name) @definition.method
(method_invocation
name: (identifier) @name
arguments: (argument_list) @reference.call)
(interface_declaration
name: (identifier) @name) @definition.interface
(type_list
(type_identifier) @name) @reference.implementation
(object_creation_expression
type: (type_identifier) @name) @reference.class
(superclass (type_identifier) @name) @reference.class

View file

@ -0,0 +1,43 @@
; Classes
(class_declaration
(type_identifier) @name) @definition.class
; Objects
(object_declaration
(type_identifier) @name) @definition.class
; Functions (top-level and member)
(function_declaration
(simple_identifier) @name) @definition.function
; Properties
(property_declaration
(variable_declaration
(simple_identifier) @name)) @definition.constant
; Enum entries
(enum_entry
(simple_identifier) @name) @definition.constant
; Type aliases
(type_alias
(type_identifier) @name) @definition.type
; Companion objects (only named ones)
(companion_object
(type_identifier) @name) @definition.class
; Function calls
(call_expression
(simple_identifier) @name) @reference.call
; Method calls via navigation
(call_expression
(navigation_expression
(navigation_suffix
(simple_identifier) @name))) @reference.call
; Constructor invocations (class references)
(constructor_invocation
(user_type
(type_identifier) @name)) @reference.class

View file

@ -0,0 +1,137 @@
; Identifier naming conventions
(identifier) @variable
((identifier) @constructor
(#match? @constructor "^[A-Z]"))
((identifier) @constant
(#match? @constant "^[A-Z][A-Z_]*$"))
; Function calls
(decorator) @function
(decorator
(identifier) @function)
(call
function: (attribute attribute: (identifier) @function.method))
(call
function: (identifier) @function)
; Builtin functions
((call
function: (identifier) @function.builtin)
(#match?
@function.builtin
"^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$"))
; Function definitions
(function_definition
name: (identifier) @function)
(attribute attribute: (identifier) @property)
(type (identifier) @type)
; Literals
[
(none)
(true)
(false)
] @constant.builtin
[
(integer)
(float)
] @number
(comment) @comment
(string) @string
(escape_sequence) @escape
(interpolation
"{" @punctuation.special
"}" @punctuation.special) @embedded
[
"-"
"-="
"!="
"*"
"**"
"**="
"*="
"/"
"//"
"//="
"/="
"&"
"&="
"%"
"%="
"^"
"^="
"+"
"->"
"+="
"<"
"<<"
"<<="
"<="
"<>"
"="
":="
"=="
">"
">="
">>"
">>="
"|"
"|="
"~"
"@="
"and"
"in"
"is"
"not"
"or"
"is not"
"not in"
] @operator
[
"as"
"assert"
"async"
"await"
"break"
"class"
"continue"
"def"
"del"
"elif"
"else"
"except"
"exec"
"finally"
"for"
"from"
"global"
"if"
"import"
"lambda"
"nonlocal"
"pass"
"print"
"raise"
"return"
"try"
"while"
"with"
"yield"
"match"
"case"
] @keyword

View file

@ -0,0 +1,14 @@
(module (expression_statement (assignment left: (identifier) @name) @definition.constant))
(class_definition
name: (identifier) @name) @definition.class
(function_definition
name: (identifier) @name) @definition.function
(call
function: [
(identifier) @name
(attribute
attribute: (identifier) @name)
]) @reference.call

View file

@ -0,0 +1,161 @@
; Identifiers
(type_identifier) @type
(primitive_type) @type.builtin
(field_identifier) @property
; Identifier conventions
; Assume all-caps names are constants
((identifier) @constant
(#match? @constant "^[A-Z][A-Z\\d_]+$'"))
; Assume uppercase names are enum constructors
((identifier) @constructor
(#match? @constructor "^[A-Z]"))
; Assume that uppercase names in paths are types
((scoped_identifier
path: (identifier) @type)
(#match? @type "^[A-Z]"))
((scoped_identifier
path: (scoped_identifier
name: (identifier) @type))
(#match? @type "^[A-Z]"))
((scoped_type_identifier
path: (identifier) @type)
(#match? @type "^[A-Z]"))
((scoped_type_identifier
path: (scoped_identifier
name: (identifier) @type))
(#match? @type "^[A-Z]"))
; Assume all qualified names in struct patterns are enum constructors. (They're
; either that, or struct names; highlighting both as constructors seems to be
; the less glaring choice of error, visually.)
(struct_pattern
type: (scoped_type_identifier
name: (type_identifier) @constructor))
; Function calls
(call_expression
function: (identifier) @function)
(call_expression
function: (field_expression
field: (field_identifier) @function.method))
(call_expression
function: (scoped_identifier
"::"
name: (identifier) @function))
(generic_function
function: (identifier) @function)
(generic_function
function: (scoped_identifier
name: (identifier) @function))
(generic_function
function: (field_expression
field: (field_identifier) @function.method))
(macro_invocation
macro: (identifier) @function.macro
"!" @function.macro)
; Function definitions
(function_item (identifier) @function)
(function_signature_item (identifier) @function)
(line_comment) @comment
(block_comment) @comment
(line_comment (doc_comment)) @comment.documentation
(block_comment (doc_comment)) @comment.documentation
"(" @punctuation.bracket
")" @punctuation.bracket
"[" @punctuation.bracket
"]" @punctuation.bracket
"{" @punctuation.bracket
"}" @punctuation.bracket
(type_arguments
"<" @punctuation.bracket
">" @punctuation.bracket)
(type_parameters
"<" @punctuation.bracket
">" @punctuation.bracket)
"::" @punctuation.delimiter
":" @punctuation.delimiter
"." @punctuation.delimiter
"," @punctuation.delimiter
";" @punctuation.delimiter
(parameter (identifier) @variable.parameter)
(lifetime (identifier) @label)
"as" @keyword
"async" @keyword
"await" @keyword
"break" @keyword
"const" @keyword
"continue" @keyword
"default" @keyword
"dyn" @keyword
"else" @keyword
"enum" @keyword
"extern" @keyword
"fn" @keyword
"for" @keyword
"gen" @keyword
"if" @keyword
"impl" @keyword
"in" @keyword
"let" @keyword
"loop" @keyword
"macro_rules!" @keyword
"match" @keyword
"mod" @keyword
"move" @keyword
"pub" @keyword
"raw" @keyword
"ref" @keyword
"return" @keyword
"static" @keyword
"struct" @keyword
"trait" @keyword
"type" @keyword
"union" @keyword
"unsafe" @keyword
"use" @keyword
"where" @keyword
"while" @keyword
"yield" @keyword
(crate) @keyword
(mutable_specifier) @keyword
(use_list (self) @keyword)
(scoped_use_list (self) @keyword)
(scoped_identifier (self) @keyword)
(super) @keyword
(self) @variable.builtin
(char_literal) @string
(string_literal) @string
(raw_string_literal) @string
(boolean_literal) @constant.builtin
(integer_literal) @constant.builtin
(float_literal) @constant.builtin
(escape_sequence) @escape
(attribute_item) @attribute
(inner_attribute_item) @attribute
"*" @operator
"&" @operator
"'" @operator

View file

@ -0,0 +1,9 @@
((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))

View file

@ -0,0 +1,60 @@
; ADT definitions
(struct_item
name: (type_identifier) @name) @definition.class
(enum_item
name: (type_identifier) @name) @definition.class
(union_item
name: (type_identifier) @name) @definition.class
; type aliases
(type_item
name: (type_identifier) @name) @definition.class
; method definitions
(declaration_list
(function_item
name: (identifier) @name) @definition.method)
; function definitions
(function_item
name: (identifier) @name) @definition.function
; trait definitions
(trait_item
name: (type_identifier) @name) @definition.interface
; module definitions
(mod_item
name: (identifier) @name) @definition.module
; macro definitions
(macro_definition
name: (identifier) @name) @definition.macro
; references
(call_expression
function: (identifier) @name) @reference.call
(call_expression
function: (field_expression
field: (field_identifier) @name)) @reference.call
(macro_invocation
macro: (identifier) @name) @reference.call
; implementations
(impl_item
trait: (type_identifier) @name) @reference.implementation
(impl_item
type: (type_identifier) @name
!trait) @reference.implementation

View file

@ -0,0 +1,35 @@
; Types
(type_identifier) @type
(predefined_type) @type.builtin
((identifier) @type
(#match? @type "^[A-Z]"))
(type_arguments
"<" @punctuation.bracket
">" @punctuation.bracket)
; Variables
(required_parameter (identifier) @variable.parameter)
(optional_parameter (identifier) @variable.parameter)
; Keywords
[ "abstract"
"declare"
"enum"
"export"
"implements"
"interface"
"keyof"
"namespace"
"private"
"protected"
"public"
"type"
"readonly"
"override"
"satisfies"
] @keyword

View file

@ -0,0 +1,23 @@
(function_signature
name: (identifier) @name) @definition.function
(method_signature
name: (property_identifier) @name) @definition.method
(abstract_method_signature
name: (property_identifier) @name) @definition.method
(abstract_class_declaration
name: (type_identifier) @name) @definition.class
(module
name: (identifier) @name) @definition.module
(interface_declaration
name: (type_identifier) @name) @definition.interface
(type_annotation
(type_identifier) @name) @reference.type
(new_expression
constructor: (identifier) @name) @reference.class

View file

@ -0,0 +1,79 @@
(boolean_scalar) @boolean
(null_scalar) @constant.builtin
[
(double_quote_scalar)
(single_quote_scalar)
(block_scalar)
(string_scalar)
] @string
[
(integer_scalar)
(float_scalar)
] @number
(comment) @comment
[
(anchor_name)
(alias_name)
] @label
(tag) @type
[
(yaml_directive)
(tag_directive)
(reserved_directive)
] @attribute
(block_mapping_pair
key: (flow_node
[
(double_quote_scalar)
(single_quote_scalar)
] @property))
(block_mapping_pair
key: (flow_node
(plain_scalar
(string_scalar) @property)))
(flow_mapping
(_
key: (flow_node
[
(double_quote_scalar)
(single_quote_scalar)
] @property)))
(flow_mapping
(_
key: (flow_node
(plain_scalar
(string_scalar) @property))))
[
","
"-"
":"
">"
"?"
"|"
] @punctuation.delimiter
[
"["
"]"
"{"
"}"
] @punctuation.bracket
[
"*"
"&"
"---"
"..."
] @punctuation.special