diff --git a/TREE_SITTER_HIGHLIGHTING_PLAN.md b/TREE_SITTER_HIGHLIGHTING_PLAN.md
deleted file mode 100644
index 103d93b..0000000
--- a/TREE_SITTER_HIGHLIGHTING_PLAN.md
+++ /dev/null
@@ -1,525 +0,0 @@
-# Tree-sitter Highlighting Implementation Plan
-
-This document is the working plan for replacing Chroma-based highlighting with a Tree-sitter-first syntax system in Gim.
-
-The current renderer in `internal/editor/view.go` is tightly coupled to Chroma and computes syntax styles during rendering.
-That is the opposite of the architecture Tree-sitter wants. Tree-sitter works best when parsing and highlighting are
-maintained as buffer state and rendering only consumes cached results.
-
-This plan assumes:
-
-- Chroma will be removed entirely.
-- The renderer can be rebuilt to better fit the new syntax model.
-- We are willing to do a full-buffer parse and full rehighlight first, then optimize incrementally.
-- Correct architecture matters more than preserving the current render pipeline.
-
----
-
-## Project Goal
-
-Build a syntax system where:
-
-- each buffer owns syntax state
-- Tree-sitter parsing is maintained across edits
-- highlights are cached outside the renderer
-- the renderer consumes precomputed style data
-- byte-oriented parser results are converted into rune-oriented render data
-
----
-
-## Success Criteria
-
-- [ ] `internal/editor/view.go` does not directly call Chroma or Tree-sitter
-- [ ] Chroma is fully removed from the codebase
-- [ ] syntax state exists independently from rendering
-- [ ] each buffer can be parsed and highlighted through Tree-sitter
-- [ ] the renderer reads cached highlight data for visible lines
-- [ ] edits invalidate and recompute syntax state
-- [ ] the system handles UTF-8 text correctly
-- [ ] multi-line captures work correctly
-- [ ] incremental parsing exists for normal text edits
-- [ ] syntax-related behavior has focused tests
-
----
-
-## Architectural Direction
-
-The target data flow is:
-
-`Buffer -> Syntax Engine -> Highlight Cache -> Renderer`
-
-Not:
-
-`Renderer -> Parse -> Highlight -> Draw`
-
-Core separation of concerns:
-
-- `internal/core`
- Holds text and buffer mutation behavior.
-- `internal/syntax`
- Owns parser state, queries, highlight cache, invalidation, and update logic.
-- `internal/style`
- Owns theme mapping from capture names to `lipgloss.Style`.
-- `internal/editor`
- Owns rendering, cursor, selection overlay, gutters, statusline, and viewport logic.
-
----
-
-## Key Constraints And Risks
-
-### Byte vs Rune Indexing
-
-Tree-sitter reports positions in bytes.
-
-The editor currently renders by runes.
-
-This means the syntax engine must own conversion from byte-based capture ranges to rune-based render ranges. This conversion should never be spread across the renderer.
-
-- [ ] define one internal representation for parser/query positions
-- [ ] define one internal representation for render positions
-- [ ] keep conversion logic isolated inside `internal/syntax`
-
-### Multi-line Captures
-
-Strings, comments, and some language constructs can span lines.
-
-- [ ] highlight cache supports ranges spanning multiple lines
-- [ ] renderer can consume per-line results from multi-line captures
-
-### Query Precedence
-
-Tree-sitter queries can produce overlapping captures.
-
-- [ ] define deterministic precedence rules
-- [ ] document how broad captures and specific captures are resolved
-
-### Full Parse First, Incremental Later
-
-The initial version does not need to be optimal.
-
-- [ ] initial version can parse and rehighlight the full buffer
-- [ ] follow-up version uses `tree.Edit`, old trees, and changed ranges
-
----
-
-## Target Package Layout
-
-Planned package layout:
-
-- [ ] `internal/syntax/types.go`
-- [ ] `internal/syntax/engine.go`
-- [ ] `internal/syntax/state.go`
-- [ ] `internal/syntax/registry.go`
-- [ ] `internal/syntax/treesitter.go`
-- [ ] `internal/syntax/query.go`
-- [ ] `internal/syntax/cache.go`
-- [ ] `internal/style/theme.go` or equivalent capture-to-style mapping helpers
-
-Likely existing files to update:
-
-- [ ] `internal/editor/model.go`
-- [ ] `internal/editor/model_builder.go`
-- [ ] `internal/editor/view.go`
-- [ ] `internal/core/buffer.go`
-- [ ] `internal/command/handlers.go`
-- [ ] `go.mod`
-
-Likely files to remove or heavily reduce:
-
-- [ ] Chroma-specific logic in `internal/style/style.go`
-- [ ] direct Chroma setup in editor model builders and command handlers
-
----
-
-## Data Model Plan
-
-### 1. Syntax Engine
-
-The syntax engine should be editor-facing and buffer-aware.
-
-Responsibilities:
-
-- attach syntax state to buffers
-- initialize parser and query data from filetype
-- reparse after edits
-- maintain dirty regions or dirty lines
-- build cached line highlight results
-- expose line results to the renderer
-
-Checklist:
-
-- [ ] define `Engine` interface in `internal/syntax/engine.go`
-- [ ] decide whether syntax state is owned directly by the engine or attached to buffers
-- [ ] add a field on `editor.Model` for the syntax engine
-
-### 2. Per-buffer Syntax State
-
-Each buffer needs syntax state. The important point is that syntax is buffer-level, not window-level.
-
-Suggested fields:
-
-- [ ] parser
-- [ ] language
-- [ ] query or compiled query set
-- [ ] current parse tree
-- [ ] source snapshot or source builder access
-- [ ] dirty line or dirty range tracking
-- [ ] cached line highlight results
-- [ ] version counter for cache invalidation
-
-### 3. Highlight Cache Representation
-
-Start with the representation that makes integration easiest.
-
-Recommended first version:
-
-- cached per-line `[]lipgloss.Style`
-
-Recommended longer-term representation:
-
-- cached per-line spans like `[]Span{StartRune, EndRune, StyleID}`
-
-Implementation choice:
-
-- [ ] phase 1 uses per-rune style maps for easiest renderer integration
-- [ ] phase 2 evaluates switching internal cache to spans
-
-### 4. Theme Mapping
-
-Theme logic should map Tree-sitter captures such as `keyword`, `function`, `string`, `comment`, and `type.builtin` to `lipgloss.Style`.
-
-Checklist:
-
-- [ ] create capture-name to style mapping layer
-- [ ] support fallback from specific captures to broader categories
-- [ ] keep theme logic independent from parser/query logic
-
----
-
-## Phased Implementation Plan
-
-## Phase 0: Cleanly Commit To Tree-sitter
-
-Purpose:
-
-Remove architectural assumptions that only make sense for Chroma.
-
-Tasks:
-
-- [ ] decide the initial supported filetypes for Tree-sitter
-- [ ] decide where query files live and how they are loaded
-- [ ] decide whether `main.go` demo code should be removed or moved to a more explicit demo location
-- [ ] audit Chroma references in the repo
-- [ ] list all codepaths that currently construct or depend on `style.ChromaStyle`
-
-Done when:
-
-- [ ] there is a clear inventory of Chroma-coupled code
-- [ ] there is a clear inventory of Tree-sitter assets to load per language
-
-## Phase 1: Introduce Syntax As A Real Subsystem
-
-Purpose:
-
-Create the new architecture boundary before changing rendering behavior.
-
-Tasks:
-
-- [ ] create `internal/syntax`
-- [ ] define the engine interface
-- [ ] add a syntax engine field to `editor.Model`
-- [ ] initialize the syntax engine in model construction
-- [ ] remove direct highlighting calls from `view.go`
-- [ ] route visible line highlighting through the syntax engine
-
-Done when:
-
-- [ ] `view.go` asks the syntax subsystem for line highlight data
-- [ ] syntax work no longer begins inside the render loop itself
-
-## Phase 2: Define Buffer Text Access And Edit Notifications
-
-Purpose:
-
-Make buffer mutations visible to the syntax system in a structured way.
-
-Tasks:
-
-- [ ] decide whether edits are emitted from `core.Buffer` or from editor actions
-- [ ] define an internal edit event type
-- [ ] include enough data for Tree-sitter incremental edits later
-- [ ] wire `SetLine`, `InsertLine`, and `DeleteLine` changes into syntax invalidation
-- [ ] decide whether first version uses whole-buffer invalidation
-
-Suggested edit event fields:
-
-- [ ] start byte
-- [ ] old end byte
-- [ ] new end byte
-- [ ] start point
-- [ ] old end point
-- [ ] new end point
-- [ ] affected line range
-
-Done when:
-
-- [ ] syntax invalidation happens when text changes
-- [ ] invalidation does not depend on the render loop noticing text changed
-
-## Phase 3: Build Minimal Tree-sitter Registry And Loader
-
-Purpose:
-
-Provide one place that maps filetypes to languages and queries.
-
-Tasks:
-
-- [ ] create a registry for language metadata
-- [ ] map filetype strings to Tree-sitter language bindings
-- [ ] map filetypes to highlight query file paths
-- [ ] load and compile queries once per language where practical
-- [ ] define behavior for unsupported filetypes
-
-Done when:
-
-- [ ] opening a supported buffer can resolve a language and query set
-- [ ] unsupported buffers degrade cleanly without crashing the renderer
-
-## Phase 4: Implement Full-buffer Parsing And Full-buffer Highlighting
-
-Purpose:
-
-Get correct Tree-sitter highlighting working before optimizing.
-
-Tasks:
-
-- [ ] create per-buffer syntax state
-- [ ] build full source text from buffer contents
-- [ ] parse full source text into a tree
-- [ ] run highlight query across the full tree
-- [ ] collect captures in deterministic order
-- [ ] resolve overlapping captures consistently
-- [ ] convert capture byte ranges into per-line rune-based style maps
-- [ ] cache line results for renderer consumption
-
-Done when:
-
-- [ ] a supported filetype can be fully highlighted without Chroma
-- [ ] renderer uses cached line results from Tree-sitter
-
-## Phase 5: Rebuild Renderer Integration Around Cached Syntax Data
-
-Purpose:
-
-Simplify the renderer so it consumes syntax cache rather than doing syntax work.
-
-Tasks:
-
-- [ ] redesign line render input around line text plus syntax cache
-- [ ] ensure gutter rendering stays independent from syntax rendering
-- [ ] ensure cursor overlay works on top of syntax styling
-- [ ] ensure visual selection overlay works on top of syntax styling
-- [ ] verify blank lines and end-of-line cursor rendering still behave correctly
-- [ ] verify window width padding still uses background style consistently
-
-Done when:
-
-- [ ] line drawing is purely a render operation
-- [ ] no parser or query logic exists in `view.go`
-
-## Phase 6: Remove Chroma Completely
-
-Purpose:
-
-Delete the old highlighting path and simplify styling around capture-based theming.
-
-Tasks:
-
-- [ ] remove Chroma dependencies from `go.mod`
-- [ ] remove `GetLexer`
-- [ ] remove `MakeStyleMap`
-- [ ] remove `Styles.ChromaStyle` if no longer needed
-- [ ] replace Chroma-derived theme extraction with explicit Gim theme definitions
-- [ ] update commands that currently switch Chroma styles
-
-Done when:
-
-- [ ] the build no longer depends on Chroma packages
-- [ ] no codepath references Chroma tokens, lexers, or styles
-
-## Phase 7: Add Incremental Parsing
-
-Purpose:
-
-Move from correct-but-simple to correct-and-efficient.
-
-Tasks:
-
-- [ ] preserve old trees per buffer
-- [ ] call `tree.Edit` before reparsing
-- [ ] parse new content using the old tree
-- [ ] compute changed ranges
-- [ ] decide whether rehighlighting happens by changed byte range, changed point range, or affected line range
-- [ ] update only changed cache regions
-- [ ] verify cache invalidation around inserted and deleted lines
-
-Done when:
-
-- [ ] small edits do not require full-buffer reparsing and rehighlighting
-- [ ] highlighting updates correctly after insertions, deletions, joins, and splits
-
-## Phase 8: Improve Cache Representation If Needed
-
-Purpose:
-
-Reduce memory churn and simplify overlay logic if per-rune style maps become too heavy.
-
-Tasks:
-
-- [ ] measure cost of per-line `[]lipgloss.Style`
-- [ ] consider switching internal storage to spans
-- [ ] keep renderer-facing API stable if possible
-- [ ] optimize only after correctness and incremental behavior exist
-
-Done when:
-
-- [ ] cache format is deliberate rather than inherited from the old renderer
-
-## Phase 9: Expand Language Support
-
-Purpose:
-
-Generalize the system after the first language works well.
-
-Tasks:
-
-- [ ] ship one language first, likely Go
-- [ ] add additional language bindings and queries one by one
-- [ ] verify filetype detection and registry behavior for each language
-- [ ] define how language-specific capture tweaks are handled
-
-Done when:
-
-- [ ] the system can scale beyond a single demo language without architectural changes
-
-## Phase 10: Testing And Verification
-
-Purpose:
-
-Make syntax behavior trustworthy as the engine evolves.
-
-Tasks:
-
-- [ ] add unit tests for registry lookup
-- [ ] add unit tests for byte-to-rune range conversion
-- [ ] add unit tests for overlapping capture resolution
-- [ ] add unit tests for multi-line highlight extraction
-- [ ] add integration tests for visible rendering of highlighted lines
-- [ ] add edit tests for incremental updates after insert, delete, split, and join operations
-- [ ] add tests covering UTF-8 characters and mixed-width content
-
-Done when:
-
-- [ ] syntax bugs can be reproduced and locked down with tests
-
----
-
-## Suggested Order Of Attack
-
-If working on this piece by piece, this is the recommended order:
-
-- [ ] Phase 1 first
-- [ ] Phase 2 second
-- [ ] Phase 3 third
-- [ ] Phase 4 fourth
-- [ ] Phase 5 fifth
-- [ ] Phase 6 sixth
-- [ ] Phase 7 seventh
-- [ ] Phase 10 continuously during all phases
-- [ ] Phase 8 only if profiling says it matters
-- [ ] Phase 9 after one language is solid
-
----
-
-## Concrete First Milestone
-
-The first milestone should be intentionally small but architectural.
-
-Milestone goal:
-
-- [ ] create `internal/syntax`
-- [ ] add syntax engine field to `editor.Model`
-- [ ] make `view.go` consume syntax results instead of computing syntax itself
-- [ ] use placeholder or basic full-buffer syntax data, even if the first output is minimal
-
-This milestone matters because it breaks the most important bad dependency: rendering owning syntax.
-
----
-
-## Concrete Second Milestone
-
-Milestone goal:
-
-- [ ] support one language with Tree-sitter full-buffer parse and full-buffer highlighting
-- [ ] cache per-line style results
-- [ ] render highlighted output without Chroma
-
----
-
-## Concrete Third Milestone
-
-Milestone goal:
-
-- [ ] wire edit invalidation into buffer mutation paths
-- [ ] update Tree-sitter state after edits
-- [ ] keep highlights correct after normal editing commands
-
----
-
-## Concrete Fourth Milestone
-
-Milestone goal:
-
-- [ ] add true incremental parse updates
-- [ ] rehighlight only changed regions
-- [ ] validate performance on larger files
-
----
-
-## Open Design Questions
-
-- [ ] Should syntax state live inside `core.Buffer` or stay in the syntax engine keyed by buffer ID?
-- [ ] Should the renderer consume per-rune styles or span-based styles?
-- [ ] Should the syntax engine rebuild full source text on demand, or should buffers expose a stable full-text API?
-- [ ] How should unsupported filetypes render: plain text or fallback queryless token classes?
-- [ ] Should theme capture fallback be static or configurable?
-- [ ] Should parser/query assets be embedded or read from disk at runtime?
-
----
-
-## Notes For Implementation
-
-Guidelines while building this:
-
-- [ ] keep parsing and rendering separate from the first commit
-- [ ] optimize only after correctness is established
-- [ ] prefer one supported language done correctly over several partial languages
-- [ ] keep UTF-8 correctness in mind from the first Tree-sitter integration
-- [ ] avoid letting temporary renderer hacks become permanent API boundaries
-- [ ] test line split, line join, backspace-at-start, delete-at-end, and multi-line comments early
-
----
-
-## Definition Of Done
-
-This project is done when all of the following are true:
-
-- [ ] Chroma is gone
-- [ ] Tree-sitter is the only syntax engine
-- [ ] syntax state is maintained outside rendering
-- [ ] edits update syntax state correctly
-- [ ] renderer consumes cached syntax data cleanly
-- [ ] highlight output is correct for supported languages
-- [ ] UTF-8 behavior is correct
-- [ ] incremental parsing is working
-- [ ] tests cover the risky pieces
diff --git a/go.mod b/go.mod
index 055d26b..5362ff7 100644
--- a/go.mod
+++ b/go.mod
@@ -7,8 +7,20 @@ require (
github.com/charmbracelet/lipgloss v1.1.0
github.com/charmbracelet/x/exp/teatest v0.0.0-20260209132835-6b065b8ba62c
github.com/tree-sitter/go-tree-sitter v0.25.0
+ github.com/tree-sitter/tree-sitter-bash v0.25.1
+ github.com/tree-sitter/tree-sitter-c v0.24.1
+ github.com/tree-sitter/tree-sitter-c-sharp v0.23.1
+ github.com/tree-sitter/tree-sitter-cpp v0.23.4
+ github.com/tree-sitter/tree-sitter-css v0.25.0
github.com/tree-sitter/tree-sitter-go v0.25.0
+ github.com/tree-sitter/tree-sitter-html v0.23.2
+ github.com/tree-sitter/tree-sitter-java v0.23.5
github.com/tree-sitter/tree-sitter-javascript v0.25.0
+ github.com/tree-sitter/tree-sitter-json v0.24.8
+ github.com/tree-sitter/tree-sitter-python v0.25.0
+ github.com/tree-sitter/tree-sitter-ruby v0.23.1
+ github.com/tree-sitter/tree-sitter-rust v0.24.2
+ github.com/tree-sitter/tree-sitter-typescript v0.23.2
)
require (
diff --git a/go.sum b/go.sum
index bd33f56..306ec6f 100644
--- a/go.sum
+++ b/go.sum
@@ -52,10 +52,16 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tree-sitter/go-tree-sitter v0.25.0 h1:sx6kcg8raRFCvc9BnXglke6axya12krCJF5xJ2sftRU=
github.com/tree-sitter/go-tree-sitter v0.25.0/go.mod h1:r77ig7BikoZhHrrsjAnv8RqGti5rtSyvDHPzgTPsUuU=
-github.com/tree-sitter/tree-sitter-c v0.23.4 h1:nBPH3FV07DzAD7p0GfNvXM+Y7pNIoPenQWBpvM++t4c=
-github.com/tree-sitter/tree-sitter-c v0.23.4/go.mod h1:MkI5dOiIpeN94LNjeCp8ljXN/953JCwAby4bClMr6bw=
+github.com/tree-sitter/tree-sitter-bash v0.25.1 h1:ZD3MK4oDB5lAsFztqbdcyYEd24pxDtx3g9UOWA062rE=
+github.com/tree-sitter/tree-sitter-bash v0.25.1/go.mod h1:AksQ6zE+sP9hnp7mKTMT7Q+CwpthV7VGQLXvweVXz9U=
+github.com/tree-sitter/tree-sitter-c v0.24.1 h1:GV9DjvIV6uYe3W/JBKMFwE4hJcRxzRDq63llxNFHOkY=
+github.com/tree-sitter/tree-sitter-c v0.24.1/go.mod h1:/SpJlv2BuiCgFA5xvtgukFGi51WxctByPUGDxPl60fc=
+github.com/tree-sitter/tree-sitter-c-sharp v0.23.1 h1:ddG6osP34sMieVNN6lu5ZG/3N8Wn+67+43BmipqidyM=
+github.com/tree-sitter/tree-sitter-c-sharp v0.23.1/go.mod h1:H7/aFm5vR1A8Yn5VIOfLWPdlKuJsMgZ5eDmaJdv8bY0=
github.com/tree-sitter/tree-sitter-cpp v0.23.4 h1:LaWZsiqQKvR65yHgKmnaqA+uz6tlDJTJFCyFIeZU/8w=
github.com/tree-sitter/tree-sitter-cpp v0.23.4/go.mod h1:doqNW64BriC7WBCQ1klf0KmJpdEvfxyXtoEybnBo6v8=
+github.com/tree-sitter/tree-sitter-css v0.25.0 h1:S5NbzhdZ5LE5V474wmdg+7NthmLjIg5v4wbyewMpziw=
+github.com/tree-sitter/tree-sitter-css v0.25.0/go.mod h1:0Z46XCb3L16nVOVw0Lhb43pzloUG/4T6E/pAOE62fEw=
github.com/tree-sitter/tree-sitter-embedded-template v0.23.2 h1:nFkkH6Sbe56EXLmZBqHHcamTpmz3TId97I16EnGy4rg=
github.com/tree-sitter/tree-sitter-embedded-template v0.23.2/go.mod h1:HNPOhN0qF3hWluYLdxWs5WbzP/iE4aaRVPMsdxuzIaQ=
github.com/tree-sitter/tree-sitter-go v0.25.0 h1:cEB0Q3LHgZtS+ECHx9wcP7AwzoOddJFQCVmytX42cVU=
@@ -70,12 +76,14 @@ github.com/tree-sitter/tree-sitter-json v0.24.8 h1:tV5rMkihgtiOe14a9LHfDY5kzTl5G
github.com/tree-sitter/tree-sitter-json v0.24.8/go.mod h1:F351KK0KGvCaYbZ5zxwx/gWWvZhIDl0eMtn+1r+gQbo=
github.com/tree-sitter/tree-sitter-php v0.23.11 h1:iHewsLNDmznh8kgGyfWfujsZxIz1YGbSd2ZTEM0ZiP8=
github.com/tree-sitter/tree-sitter-php v0.23.11/go.mod h1:T/kbfi+UcCywQfUNAJnGTN/fMSUjnwPXA8k4yoIks74=
-github.com/tree-sitter/tree-sitter-python v0.23.6 h1:qHnWFR5WhtMQpxBZRwiaU5Hk/29vGju6CVtmvu5Haas=
-github.com/tree-sitter/tree-sitter-python v0.23.6/go.mod h1:cpdthSy/Yoa28aJFBscFHlGiU+cnSiSh1kuDVtI8YeM=
+github.com/tree-sitter/tree-sitter-python v0.25.0 h1:O6XD9v8U1LOcRc3cNj9nM7XufrtEBezE6VrpRrHZDf0=
+github.com/tree-sitter/tree-sitter-python v0.25.0/go.mod h1:cpdthSy/Yoa28aJFBscFHlGiU+cnSiSh1kuDVtI8YeM=
github.com/tree-sitter/tree-sitter-ruby v0.23.1 h1:T/NKHUA+iVbHM440hFx+lzVOzS4dV6z8Qw8ai+72bYo=
github.com/tree-sitter/tree-sitter-ruby v0.23.1/go.mod h1:kUS4kCCQloFcdX6sdpr8p6r2rogbM6ZjTox5ZOQy8cA=
-github.com/tree-sitter/tree-sitter-rust v0.23.2 h1:6AtoooCW5GqNrRpfnvl0iUhxTAZEovEmLKDbyHlfw90=
-github.com/tree-sitter/tree-sitter-rust v0.23.2/go.mod h1:hfeGWic9BAfgTrc7Xf6FaOAguCFJRo3RBbs7QJ6D7MI=
+github.com/tree-sitter/tree-sitter-rust v0.24.2 h1:NL4nF67ib21RMzzfvkmXlVwe45vvhW10DVyO+D0z/W0=
+github.com/tree-sitter/tree-sitter-rust v0.24.2/go.mod h1:hfeGWic9BAfgTrc7Xf6FaOAguCFJRo3RBbs7QJ6D7MI=
+github.com/tree-sitter/tree-sitter-typescript v0.23.2 h1:/Odvphn18PniVixb9e97X0DbNVsU6Qocv9mfkyzdXwU=
+github.com/tree-sitter/tree-sitter-typescript v0.23.2/go.mod h1:zjzMXT/Ulffel2xfOcAkQQkiAkmgnbtPGlFQw/5X4xA=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
diff --git a/internal/syntax/queries/bash/highlights.scm b/internal/syntax/queries/bash/highlights.scm
new file mode 100644
index 0000000..58d57d9
--- /dev/null
+++ b/internal/syntax/queries/bash/highlights.scm
@@ -0,0 +1,261 @@
+[
+ "("
+ ")"
+ "{"
+ "}"
+ "["
+ "]"
+ "[["
+ "]]"
+ "(("
+ "))"
+] @punctuation.bracket
+
+[
+ ";"
+ ";;"
+ ";&"
+ ";;&"
+ "&"
+] @punctuation.delimiter
+
+[
+ ">"
+ ">>"
+ "<"
+ "<<"
+ "&&"
+ "|"
+ "|&"
+ "||"
+ "="
+ "+="
+ "=~"
+ "=="
+ "!="
+ "&>"
+ "&>>"
+ "<&"
+ ">&"
+ ">|"
+ "<&-"
+ ">&-"
+ "<<-"
+ "<<<"
+ ".."
+ "!"
+] @operator
+
+; Do *not* spell check strings since they typically have some sort of
+; interpolation in them, or, are typically used for things like filenames, URLs,
+; flags and file content.
+[
+ (string)
+ (raw_string)
+ (ansi_c_string)
+ (heredoc_body)
+] @string
+
+[
+ (heredoc_start)
+ (heredoc_end)
+] @label
+
+(variable_assignment
+ (word) @string)
+
+(command
+ argument: "$" @string) ; bare dollar
+
+(concatenation
+ (word) @string)
+
+[
+ "if"
+ "then"
+ "else"
+ "elif"
+ "fi"
+ "case"
+ "in"
+ "esac"
+] @keyword.conditional
+
+[
+ "for"
+ "do"
+ "done"
+ "select"
+ "until"
+ "while"
+] @keyword.repeat
+
+[
+ "declare"
+ "typeset"
+ "readonly"
+ "local"
+ "unset"
+ "unsetenv"
+] @keyword
+
+"export" @keyword.import
+
+"function" @keyword.function
+
+(special_variable_name) @constant
+
+; trap -l
+((word) @constant.builtin
+ (#any-of? @constant.builtin
+ "SIGHUP" "SIGINT" "SIGQUIT" "SIGILL" "SIGTRAP" "SIGABRT" "SIGBUS" "SIGFPE" "SIGKILL" "SIGUSR1"
+ "SIGSEGV" "SIGUSR2" "SIGPIPE" "SIGALRM" "SIGTERM" "SIGSTKFLT" "SIGCHLD" "SIGCONT" "SIGSTOP"
+ "SIGTSTP" "SIGTTIN" "SIGTTOU" "SIGURG" "SIGXCPU" "SIGXFSZ" "SIGVTALRM" "SIGPROF" "SIGWINCH"
+ "SIGIO" "SIGPWR" "SIGSYS" "SIGRTMIN" "SIGRTMIN+1" "SIGRTMIN+2" "SIGRTMIN+3" "SIGRTMIN+4"
+ "SIGRTMIN+5" "SIGRTMIN+6" "SIGRTMIN+7" "SIGRTMIN+8" "SIGRTMIN+9" "SIGRTMIN+10" "SIGRTMIN+11"
+ "SIGRTMIN+12" "SIGRTMIN+13" "SIGRTMIN+14" "SIGRTMIN+15" "SIGRTMAX-14" "SIGRTMAX-13"
+ "SIGRTMAX-12" "SIGRTMAX-11" "SIGRTMAX-10" "SIGRTMAX-9" "SIGRTMAX-8" "SIGRTMAX-7" "SIGRTMAX-6"
+ "SIGRTMAX-5" "SIGRTMAX-4" "SIGRTMAX-3" "SIGRTMAX-2" "SIGRTMAX-1" "SIGRTMAX"))
+
+((word) @boolean
+ (#any-of? @boolean "true" "false"))
+
+(comment) @comment @spell
+
+(test_operator) @operator
+
+(command_substitution
+ "$(" @punctuation.special
+ ")" @punctuation.special)
+
+(process_substitution
+ [
+ "<("
+ ">("
+ ] @punctuation.special
+ ")" @punctuation.special)
+
+(arithmetic_expansion
+ [
+ "$(("
+ "(("
+ ] @punctuation.special
+ "))" @punctuation.special)
+
+(arithmetic_expansion
+ "," @punctuation.delimiter)
+
+(ternary_expression
+ [
+ "?"
+ ":"
+ ] @keyword.conditional.ternary)
+
+(binary_expression
+ operator: _ @operator)
+
+(unary_expression
+ operator: _ @operator)
+
+(postfix_expression
+ operator: _ @operator)
+
+(function_definition
+ name: (word) @function)
+
+(command_name
+ (word) @function.call)
+
+(command_name
+ (word) @function.builtin
+ (#any-of? @function.builtin
+ "." ":" "alias" "bg" "bind" "break" "builtin" "caller" "cd" "command" "compgen" "complete"
+ "compopt" "continue" "coproc" "dirs" "disown" "echo" "enable" "eval" "exec" "exit" "false" "fc"
+ "fg" "getopts" "hash" "help" "history" "jobs" "kill" "let" "logout" "mapfile" "popd" "printf"
+ "pushd" "pwd" "read" "readarray" "return" "set" "shift" "shopt" "source" "suspend" "test" "time"
+ "times" "trap" "true" "type" "typeset" "ulimit" "umask" "unalias" "wait"))
+
+(command
+ argument: [
+ (word) @variable.parameter
+ (concatenation
+ (word) @variable.parameter)
+ ])
+
+(declaration_command
+ (word) @variable.parameter)
+
+(unset_command
+ (word) @variable.parameter)
+
+(number) @number
+
+((word) @number
+ (#lua-match? @number "^[0-9]+$"))
+
+(file_redirect
+ (word) @string.special.path)
+
+(herestring_redirect
+ (word) @string)
+
+(file_descriptor) @operator
+
+(simple_expansion
+ "$" @punctuation.special) @none
+
+(expansion
+ "${" @punctuation.special
+ "}" @punctuation.special) @none
+
+(expansion
+ operator: _ @punctuation.special)
+
+(expansion
+ "@"
+ .
+ operator: _ @character.special)
+
+((expansion
+ (subscript
+ index: (word) @character.special))
+ (#any-of? @character.special "@" "*"))
+
+"``" @punctuation.special
+
+(variable_name) @variable
+
+((variable_name) @constant
+ (#lua-match? @constant "^[A-Z][A-Z_0-9]*$"))
+
+((variable_name) @variable.builtin
+ (#any-of? @variable.builtin
+ ; https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Variables.html
+ "CDPATH" "HOME" "IFS" "MAIL" "MAILPATH" "OPTARG" "OPTIND" "PATH" "PS1" "PS2"
+ ; https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html
+ "_" "BASH" "BASHOPTS" "BASHPID" "BASH_ALIASES" "BASH_ARGC" "BASH_ARGV" "BASH_ARGV0" "BASH_CMDS"
+ "BASH_COMMAND" "BASH_COMPAT" "BASH_ENV" "BASH_EXECUTION_STRING" "BASH_LINENO"
+ "BASH_LOADABLES_PATH" "BASH_REMATCH" "BASH_SOURCE" "BASH_SUBSHELL" "BASH_VERSINFO"
+ "BASH_VERSION" "BASH_XTRACEFD" "CHILD_MAX" "COLUMNS" "COMP_CWORD" "COMP_LINE" "COMP_POINT"
+ "COMP_TYPE" "COMP_KEY" "COMP_WORDBREAKS" "COMP_WORDS" "COMPREPLY" "COPROC" "DIRSTACK" "EMACS"
+ "ENV" "EPOCHREALTIME" "EPOCHSECONDS" "EUID" "EXECIGNORE" "FCEDIT" "FIGNORE" "FUNCNAME"
+ "FUNCNEST" "GLOBIGNORE" "GROUPS" "histchars" "HISTCMD" "HISTCONTROL" "HISTFILE" "HISTFILESIZE"
+ "HISTIGNORE" "HISTSIZE" "HISTTIMEFORMAT" "HOSTFILE" "HOSTNAME" "HOSTTYPE" "IGNOREEOF" "INPUTRC"
+ "INSIDE_EMACS" "LANG" "LC_ALL" "LC_COLLATE" "LC_CTYPE" "LC_MESSAGES" "LC_NUMERIC" "LC_TIME"
+ "LINENO" "LINES" "MACHTYPE" "MAILCHECK" "MAPFILE" "OLDPWD" "OPTERR" "OSTYPE" "PIPESTATUS"
+ "POSIXLY_CORRECT" "PPID" "PROMPT_COMMAND" "PROMPT_DIRTRIM" "PS0" "PS3" "PS4" "PWD" "RANDOM"
+ "READLINE_ARGUMENT" "READLINE_LINE" "READLINE_MARK" "READLINE_POINT" "REPLY" "SECONDS" "SHELL"
+ "SHELLOPTS" "SHLVL" "SRANDOM" "TIMEFORMAT" "TMOUT" "TMPDIR" "UID"))
+
+(case_item
+ value: (word) @variable.parameter)
+
+[
+ (regex)
+ (extglob_pattern)
+] @string.regexp
+
+((program
+ .
+ (comment) @keyword.directive @nospell)
+ (#lua-match? @keyword.directive "^#!/"))
diff --git a/internal/syntax/queries/c/highlights.scm b/internal/syntax/queries/c/highlights.scm
new file mode 100644
index 0000000..ea65075
--- /dev/null
+++ b/internal/syntax/queries/c/highlights.scm
@@ -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
diff --git a/internal/syntax/queries/cpp/highlights.scm b/internal/syntax/queries/cpp/highlights.scm
new file mode 100644
index 0000000..b168c25
--- /dev/null
+++ b/internal/syntax/queries/cpp/highlights.scm
@@ -0,0 +1,608 @@
+; 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
+
+((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
diff --git a/internal/syntax/queries/csharp/highlights.scm b/internal/syntax/queries/csharp/highlights.scm
new file mode 100644
index 0000000..f23d7ec
--- /dev/null
+++ b/internal/syntax/queries/csharp/highlights.scm
@@ -0,0 +1,577 @@
+[
+ (identifier)
+ (preproc_arg)
+] @variable
+
+((preproc_arg) @constant.macro
+ (#lua-match? @constant.macro "^[_A-Z][_A-Z0-9]*$"))
+
+((identifier) @keyword
+ (#eq? @keyword "value")
+ (#has-ancestor? @keyword accessor_declaration))
+
+(method_declaration
+ name: (identifier) @function.method)
+
+(local_function_statement
+ name: (identifier) @function.method)
+
+(method_declaration
+ returns: [
+ (identifier) @type
+ (generic_name
+ (identifier) @type)
+ ])
+
+(event_declaration
+ type: (identifier) @type)
+
+(event_declaration
+ name: (identifier) @variable.member)
+
+(event_field_declaration
+ (variable_declaration
+ (variable_declarator
+ name: (identifier) @variable.member)))
+
+(declaration_pattern
+ type: (identifier) @type)
+
+(local_function_statement
+ type: (identifier) @type)
+
+(interpolation) @none
+
+(member_access_expression
+ name: (identifier) @variable.member)
+
+(invocation_expression
+ (member_access_expression
+ name: (identifier) @function.method.call))
+
+(invocation_expression
+ function: (conditional_access_expression
+ (member_binding_expression
+ name: (identifier) @function.method.call)))
+
+(namespace_declaration
+ name: [
+ (qualified_name)
+ (identifier)
+ ] @module)
+
+(qualified_name
+ (identifier) @type)
+
+(namespace_declaration
+ name: (identifier) @module)
+
+(file_scoped_namespace_declaration
+ name: (identifier) @module)
+
+(qualified_name
+ (identifier) @module
+ (#not-has-ancestor? @module method_declaration)
+ (#not-has-ancestor? @module record_declaration)
+ (#has-ancestor? @module namespace_declaration file_scoped_namespace_declaration))
+
+(invocation_expression
+ (identifier) @function.method.call)
+
+(field_declaration
+ (variable_declaration
+ (variable_declarator
+ (identifier) @variable.member)))
+
+(initializer_expression
+ (assignment_expression
+ left: (identifier) @variable.member))
+
+(parameter
+ name: (identifier) @variable.parameter)
+
+(parameter_list
+ name: (identifier) @variable.parameter)
+
+(bracketed_parameter_list
+ name: (identifier) @variable.parameter)
+
+(implicit_parameter) @variable.parameter
+
+(parameter_list
+ (parameter
+ type: (identifier) @type))
+
+(integer_literal) @number
+
+(real_literal) @number.float
+
+(null_literal) @constant.builtin
+
+(calling_convention
+ [
+ (identifier)
+ "Cdecl"
+ "Stdcall"
+ "Thiscall"
+ "Fastcall"
+ ] @attribute.builtin)
+
+(character_literal) @character
+
+[
+ (string_literal)
+ (raw_string_literal)
+ (verbatim_string_literal)
+ (interpolated_string_expression)
+] @string
+
+(escape_sequence) @string.escape
+
+[
+ "true"
+ "false"
+] @boolean
+
+(predefined_type) @type.builtin
+
+(implicit_type) @keyword
+
+(comment) @comment @spell
+
+((comment) @comment.documentation
+ (#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$"))
+
+((comment) @comment.documentation
+ (#lua-match? @comment.documentation "^///[^/]"))
+
+((comment) @comment.documentation
+ (#lua-match? @comment.documentation "^///$"))
+
+(using_directive
+ (identifier) @type)
+
+(using_directive
+ (type) @type.definition)
+
+(property_declaration
+ name: (identifier) @property)
+
+(property_declaration
+ type: (identifier) @type)
+
+(nullable_type
+ type: (identifier) @type)
+
+(array_type
+ type: (identifier) @type)
+
+(ref_type
+ type: (identifier) @type)
+
+(pointer_type
+ type: (identifier) @type)
+
+(catch_declaration
+ type: (identifier) @type)
+
+(interface_declaration
+ name: (identifier) @type)
+
+(class_declaration
+ name: (identifier) @type)
+
+(record_declaration
+ name: (identifier) @type)
+
+(struct_declaration
+ name: (identifier) @type)
+
+(enum_declaration
+ name: (identifier) @type)
+
+(enum_member_declaration
+ name: (identifier) @variable.member)
+
+(operator_declaration
+ type: (identifier) @type)
+
+(conversion_operator_declaration
+ type: (identifier) @type)
+
+(explicit_interface_specifier
+ [
+ (identifier) @type
+ (generic_name
+ (identifier) @type)
+ ])
+
+(explicit_interface_specifier
+ (identifier) @type)
+
+(primary_constructor_base_type
+ type: (identifier) @type)
+
+[
+ "assembly"
+ "module"
+ "this"
+ "base"
+] @variable.builtin
+
+(constructor_declaration
+ name: (identifier) @constructor)
+
+(destructor_declaration
+ name: (identifier) @constructor)
+
+(constructor_initializer
+ "base" @constructor)
+
+(variable_declaration
+ (identifier) @type)
+
+(object_creation_expression
+ (identifier) @type)
+
+; Generic Types.
+(typeof_expression
+ (generic_name
+ (identifier) @type))
+
+(type_argument_list
+ (generic_name
+ (identifier) @type))
+
+(base_list
+ (generic_name
+ (identifier) @type))
+
+(type_parameter_constraint
+ [
+ (identifier) @type
+ (type
+ (generic_name
+ (identifier) @type))
+ ])
+
+(object_creation_expression
+ (generic_name
+ (identifier) @type))
+
+(property_declaration
+ (generic_name
+ (identifier) @type))
+
+(_
+ type: (generic_name
+ (identifier) @type))
+
+; Generic Method invocation with generic type
+(invocation_expression
+ function: (generic_name
+ .
+ (identifier) @function.method.call))
+
+(invocation_expression
+ (member_access_expression
+ (generic_name
+ (identifier) @function.method)))
+
+(base_list
+ (identifier) @type)
+
+(type_argument_list
+ (identifier) @type)
+
+(type_parameter_list
+ (type_parameter) @type)
+
+(type_parameter
+ name: (identifier) @type)
+
+(type_parameter_constraints_clause
+ "where"
+ .
+ (identifier) @type)
+
+(attribute
+ name: (identifier) @attribute)
+
+(foreach_statement
+ type: (identifier) @type)
+
+(goto_statement
+ (identifier) @label)
+
+(labeled_statement
+ (identifier) @label)
+
+(tuple_element
+ type: (identifier) @type)
+
+(tuple_expression
+ (argument
+ (declaration_expression
+ type: (identifier) @type)))
+
+(cast_expression
+ type: (identifier) @type)
+
+(lambda_expression
+ type: (identifier) @type)
+
+(as_expression
+ right: (identifier) @type)
+
+(typeof_expression
+ (identifier) @type)
+
+(preproc_error) @keyword.exception
+
+[
+ "#define"
+ "#undef"
+] @keyword.directive.define
+
+[
+ "#if"
+ "#elif"
+ "#else"
+ "#endif"
+ "#region"
+ "#endregion"
+ "#line"
+ "#pragma"
+ "#nullable"
+ "#error"
+ (shebang_directive)
+] @keyword.directive
+
+[
+ (preproc_line)
+ (preproc_pragma)
+ (preproc_nullable)
+] @constant.macro
+
+(preproc_pragma
+ (identifier) @constant)
+
+(preproc_if
+ (identifier) @constant)
+
+[
+ "if"
+ "else"
+ "switch"
+ "break"
+ "case"
+ "when"
+] @keyword.conditional
+
+[
+ "while"
+ "for"
+ "do"
+ "continue"
+ "goto"
+ "foreach"
+] @keyword.repeat
+
+[
+ "try"
+ "catch"
+ "throw"
+ "finally"
+] @keyword.exception
+
+[
+ "+"
+ "?"
+ ":"
+ "++"
+ "-"
+ "--"
+ "&"
+ "&&"
+ "|"
+ "||"
+ "!"
+ "!="
+ "=="
+ "*"
+ "/"
+ "%"
+ "<"
+ "<="
+ ">"
+ ">="
+ "="
+ "-="
+ "+="
+ "*="
+ "/="
+ "%="
+ "^"
+ "^="
+ "&="
+ "|="
+ "~"
+ ">>"
+ ">>>"
+ "<<"
+ "<<="
+ ">>="
+ ">>>="
+ "=>"
+ "??"
+ "??="
+ ".."
+] @operator
+
+(list_pattern
+ ".." @character.special)
+
+(discard) @character.special
+
+[
+ ";"
+ "."
+ ","
+ ":"
+] @punctuation.delimiter
+
+(conditional_expression
+ [
+ "?"
+ ":"
+ ] @keyword.conditional.ternary)
+
+[
+ "["
+ "]"
+ "{"
+ "}"
+ "("
+ ")"
+] @punctuation.bracket
+
+(interpolation_brace) @punctuation.special
+
+(type_argument_list
+ [
+ "<"
+ ">"
+ ] @punctuation.bracket)
+
+[
+ "using"
+ "as"
+] @keyword.import
+
+(alias_qualified_name
+ (identifier
+ "global") @keyword.import)
+
+[
+ "with"
+ "new"
+ "typeof"
+ "sizeof"
+ "is"
+ "and"
+ "or"
+ "not"
+ "stackalloc"
+ "__makeref"
+ "__reftype"
+ "__refvalue"
+ "in"
+ "out"
+ "ref"
+] @keyword.operator
+
+[
+ "lock"
+ "params"
+ "operator"
+ "default"
+ "implicit"
+ "explicit"
+ "override"
+ "get"
+ "set"
+ "init"
+ "where"
+ "add"
+ "remove"
+ "checked"
+ "unchecked"
+ "fixed"
+ "alias"
+ "file"
+ "unsafe"
+] @keyword
+
+(attribute_target_specifier
+ .
+ _ @keyword)
+
+[
+ "enum"
+ "record"
+ "class"
+ "struct"
+ "interface"
+ "namespace"
+ "event"
+ "delegate"
+] @keyword.type
+
+[
+ "async"
+ "await"
+] @keyword.coroutine
+
+[
+ "const"
+ "extern"
+ "readonly"
+ "static"
+ "volatile"
+ "required"
+ "managed"
+ "unmanaged"
+ "notnull"
+ "abstract"
+ "private"
+ "protected"
+ "internal"
+ "public"
+ "partial"
+ "sealed"
+ "virtual"
+ "global"
+] @keyword.modifier
+
+(scoped_type
+ "scoped" @keyword.modifier)
+
+(query_expression
+ (_
+ [
+ "from"
+ "orderby"
+ "select"
+ "group"
+ "by"
+ "ascending"
+ "descending"
+ "equals"
+ "let"
+ ] @keyword))
+
+[
+ "return"
+ "yield"
+] @keyword.return
diff --git a/internal/syntax/queries/css/highlights.scm b/internal/syntax/queries/css/highlights.scm
new file mode 100644
index 0000000..49471fd
--- /dev/null
+++ b/internal/syntax/queries/css/highlights.scm
@@ -0,0 +1,109 @@
+[
+ "@media"
+ "@charset"
+ "@namespace"
+ "@supports"
+ "@keyframes"
+ (at_keyword)
+] @keyword.directive
+
+"@import" @keyword.import
+
+[
+ (to)
+ (from)
+] @keyword
+
+(comment) @comment @spell
+
+(tag_name) @tag
+
+(class_name) @type
+
+(id_name) @constant
+
+[
+ (property_name)
+ (feature_name)
+] @property
+
+[
+ (nesting_selector)
+ (universal_selector)
+] @character.special
+
+(function_name) @function
+
+[
+ "~"
+ ">"
+ "+"
+ "-"
+ "*"
+ "/"
+ "="
+ "^="
+ "|="
+ "~="
+ "$="
+ "*="
+] @operator
+
+[
+ "and"
+ "or"
+ "not"
+ "only"
+] @keyword.operator
+
+(important) @keyword.modifier
+
+(attribute_selector
+ (plain_value) @string)
+
+(pseudo_element_selector
+ "::"
+ (tag_name) @attribute)
+
+(pseudo_class_selector
+ (class_name) @attribute)
+
+(attribute_name) @tag.attribute
+
+(namespace_name) @module
+
+(keyframes_name) @variable
+
+((property_name) @variable
+ (#lua-match? @variable "^[-][-]"))
+
+((plain_value) @variable
+ (#lua-match? @variable "^[-][-]"))
+
+[
+ (string_value)
+ (color_value)
+ (unit)
+] @string
+
+(integer_value) @number
+
+(float_value) @number.float
+
+[
+ "#"
+ ","
+ "."
+ ":"
+ "::"
+ ";"
+] @punctuation.delimiter
+
+[
+ "{"
+ ")"
+ "("
+ "}"
+ "["
+ "]"
+] @punctuation.bracket
diff --git a/internal/syntax/queries/html/highlights.scm b/internal/syntax/queries/html/highlights.scm
new file mode 100644
index 0000000..bab8da1
--- /dev/null
+++ b/internal/syntax/queries/html/highlights.scm
@@ -0,0 +1,105 @@
+(tag_name) @tag
+
+; (erroneous_end_tag_name) @error ; we do not lint syntax errors
+(comment) @comment @spell
+
+(attribute_name) @tag.attribute
+
+((attribute
+ (quoted_attribute_value) @string)
+ (#set! priority 99))
+
+(text) @none @spell
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.heading)
+ (#eq? @_tag "title"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.heading.1)
+ (#eq? @_tag "h1"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.heading.2)
+ (#eq? @_tag "h2"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.heading.3)
+ (#eq? @_tag "h3"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.heading.4)
+ (#eq? @_tag "h4"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.heading.5)
+ (#eq? @_tag "h5"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.heading.6)
+ (#eq? @_tag "h6"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.strong)
+ (#any-of? @_tag "strong" "b"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.italic)
+ (#any-of? @_tag "em" "i"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.strikethrough)
+ (#any-of? @_tag "s" "del"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.underline)
+ (#eq? @_tag "u"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.raw)
+ (#any-of? @_tag "code" "kbd"))
+
+((element
+ (start_tag
+ (tag_name) @_tag)
+ (text) @markup.link.label)
+ (#eq? @_tag "a"))
+
+((attribute
+ (attribute_name) @_attr
+ (quoted_attribute_value
+ (attribute_value) @string.special.url))
+ (#any-of? @_attr "href" "src"))
+
+[
+ "<"
+ ">"
+ ""
+ "/>"
+] @tag.delimiter
+
+"=" @operator
diff --git a/internal/syntax/queries/java/highlights.scm b/internal/syntax/queries/java/highlights.scm
new file mode 100644
index 0000000..df9ca14
--- /dev/null
+++ b/internal/syntax/queries/java/highlights.scm
@@ -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 "^///$"))
diff --git a/internal/syntax/queries/javascript/highlights.scm b/internal/syntax/queries/javascript/highlights.scm
index 9312d68..27f76e4 100644
--- a/internal/syntax/queries/javascript/highlights.scm
+++ b/internal/syntax/queries/javascript/highlights.scm
@@ -1,151 +1,295 @@
+; Types
+; Javascript
; Variables
-;----------
-
+;-----------
(identifier) @variable
; Properties
;-----------
+(property_identifier) @variable.member
-(property_identifier) @property
+(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) @function.method)
+ 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) (arrow_function)])
+ value: (function_expression))
+
+(pair
+ key: (property_identifier) @function.method
+ value: (arrow_function))
(assignment_expression
left: (member_expression
property: (property_identifier) @function.method)
- right: [(function_expression) (arrow_function)])
+ right: (arrow_function))
+
+(assignment_expression
+ left: (member_expression
+ property: (property_identifier) @function.method)
+ right: (function_expression))
(variable_declarator
name: (identifier) @function
- value: [(function_expression) (arrow_function)])
+ value: (arrow_function))
+
+(variable_declarator
+ name: (identifier) @function
+ value: (function_expression))
(assignment_expression
left: (identifier) @function
- right: [(function_expression) (arrow_function)])
+ right: (arrow_function))
+
+(assignment_expression
+ left: (identifier) @function
+ right: (function_expression))
; Function and method calls
;--------------------------
-
(call_expression
- function: (identifier) @function)
+ function: (identifier) @function.call)
(call_expression
function: (member_expression
- property: (property_identifier) @function.method))
+ property: [
+ (property_identifier)
+ (private_property_identifier)
+ ] @function.method.call))
-; Special identifiers
-;--------------------
+(call_expression
+ function: (await_expression
+ (identifier) @function.call))
-((identifier) @constructor
- (#match? @constructor "^[A-Z]"))
+(call_expression
+ function: (await_expression
+ (member_expression
+ property: [
+ (property_identifier)
+ (private_property_identifier)
+ ] @function.method.call)))
-([
- (identifier)
- (shorthand_property_identifier)
- (shorthand_property_identifier_pattern)
- ] @constant
- (#match? @constant "^[A-Z_][A-Z\\d_]+$"))
-
-((identifier) @variable.builtin
- (#match? @variable.builtin "^(arguments|module|console|window|document)$")
- (#is-not? local))
+; Builtins
+;---------
+((identifier) @module.builtin
+ (#eq? @module.builtin "Intl"))
((identifier) @function.builtin
- (#eq? @function.builtin "require")
- (#is-not? local))
+ (#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
-(this) @variable.builtin
-(super) @variable.builtin
+((identifier) @variable.builtin
+ (#eq? @variable.builtin "self"))
[
(true)
(false)
+] @boolean
+
+[
(null)
(undefined)
] @constant.builtin
-(comment) @comment
-
[
- (string)
- (template_string)
-] @string
+ (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
-(regex) @string.special
(number) @number
-; Tokens
-;-------
+((identifier) @number
+ (#any-of? @number "NaN" "Infinity"))
+; Punctuation
+;------------
[
";"
- (optional_chain)
"."
","
+ ":"
] @punctuation.delimiter
[
- "-"
"--"
+ "-"
"-="
+ "&&"
"+"
"++"
"+="
- "*"
- "*="
- "**"
- "**="
- "/"
+ "&="
"/="
- "%"
- "%="
+ "**="
+ "<<="
"<"
"<="
"<<"
- "<<="
"="
"=="
"==="
- "!"
"!="
"!=="
"=>"
">"
">="
">>"
- ">>="
+ "||"
+ "%"
+ "%="
+ "*"
+ "**"
">>>"
- ">>>="
- "~"
- "^"
"&"
"|"
- "^="
- "&="
- "|="
- "&&"
- "||"
+ "^"
"??"
+ "*="
+ ">>="
+ ">>>="
+ "^="
+ "|="
"&&="
"||="
"??="
+ "..."
] @operator
+(binary_expression
+ "/" @operator)
+
+(ternary_expression
+ [
+ "?"
+ ":"
+ ] @keyword.conditional.ternary)
+
+(unary_expression
+ [
+ "!"
+ "~"
+ "-"
+ "+"
+ ] @operator)
+
+(unary_expression
+ [
+ "delete"
+ "void"
+ ] @keyword.operator)
+
[
"("
")"
@@ -153,52 +297,309 @@
"]"
"{"
"}"
-] @punctuation.bracket
+] @punctuation.bracket
(template_substitution
- "${" @punctuation.special
- "}" @punctuation.special) @embedded
+ [
+ "${"
+ "}"
+ ] @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
[
- "as"
- "async"
- "await"
- "break"
- "case"
- "catch"
- "class"
- "const"
- "continue"
- "debugger"
- "default"
- "delete"
- "do"
- "else"
- "export"
- "extends"
- "finally"
- "for"
- "from"
- "function"
- "get"
- "if"
"import"
- "in"
- "instanceof"
- "let"
- "new"
+ "from"
+ "as"
+ "export"
+] @keyword.import
+
+[
+ "for"
"of"
- "return"
+ "do"
+ "while"
+ "continue"
+] @keyword.repeat
+
+[
+ "break"
+ "const"
+ "debugger"
+ "extends"
+ "get"
+ "let"
"set"
"static"
- "switch"
"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"
- "typeof"
- "var"
- "void"
- "while"
- "with"
- "yield"
-] @keyword
+ "catch"
+ "finally"
+] @keyword.exception
+
+(export_statement
+ "default" @keyword)
+
+(switch_default
+ "default" @keyword.conditional)
+
+(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 -
+(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 -
+(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 -
+(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"))
+
+((jsx_element) @_jsx_element
+ (#set! @_jsx_element bo.commentstring "{/* %s */}"))
+
+((jsx_attribute) @_jsx_attribute
+ (#set! @_jsx_attribute bo.commentstring "// %s"))
+
+; 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
diff --git a/internal/syntax/queries/json/highlights.scm b/internal/syntax/queries/json/highlights.scm
new file mode 100644
index 0000000..8591528
--- /dev/null
+++ b/internal/syntax/queries/json/highlights.scm
@@ -0,0 +1,38 @@
+[
+ (true)
+ (false)
+] @boolean
+
+(null) @constant.builtin
+
+(number) @number
+
+(pair
+ key: (string) @property)
+
+(pair
+ value: (string) @string)
+
+(array
+ (string) @string)
+
+[
+ ","
+ ":"
+] @punctuation.delimiter
+
+[
+ "["
+ "]"
+ "{"
+ "}"
+] @punctuation.bracket
+
+("\"" @conceal
+ (#set! conceal ""))
+
+(escape_sequence) @string.escape
+
+((escape_sequence) @conceal
+ (#eq? @conceal "\\\"")
+ (#set! conceal "\""))
diff --git a/internal/syntax/queries/python/highlights.scm b/internal/syntax/queries/python/highlights.scm
new file mode 100644
index 0000000..e4449ef
--- /dev/null
+++ b/internal/syntax/queries/python/highlights.scm
@@ -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"))
diff --git a/internal/syntax/queries/ruby/highlights.scm b/internal/syntax/queries/ruby/highlights.scm
new file mode 100644
index 0000000..8de0251
--- /dev/null
+++ b/internal/syntax/queries/ruby/highlights.scm
@@ -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)
diff --git a/internal/syntax/queries/rust/highlights.scm b/internal/syntax/queries/rust/highlights.scm
new file mode 100644
index 0000000..de9d096
--- /dev/null
+++ b/internal/syntax/queries/rust/highlights.scm
@@ -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))))
diff --git a/internal/syntax/queries/tsx/highlights.scm b/internal/syntax/queries/tsx/highlights.scm
new file mode 100644
index 0000000..1be01dc
--- /dev/null
+++ b/internal/syntax/queries/tsx/highlights.scm
@@ -0,0 +1,757 @@
+(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 -
+(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 -
+(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 -
+(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"))
+
+((jsx_element) @_jsx_element
+ (#set! @_jsx_element bo.commentstring "{/* %s */}"))
+
+((jsx_attribute) @_jsx_attribute
+ (#set! @_jsx_attribute bo.commentstring "// %s"))
+
+; 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)
+
+"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)
+ ]))
diff --git a/internal/syntax/queries/typescript/highlights.scm b/internal/syntax/queries/typescript/highlights.scm
new file mode 100644
index 0000000..2cd5f1a
--- /dev/null
+++ b/internal/syntax/queries/typescript/highlights.scm
@@ -0,0 +1,599 @@
+; 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)
+
+"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)
+ ]))
diff --git a/internal/syntax/query_assets.go b/internal/syntax/query_assets.go
index 9f497a4..8b59a86 100644
--- a/internal/syntax/query_assets.go
+++ b/internal/syntax/query_assets.go
@@ -8,6 +8,45 @@ var goHighlightsQuery string
//go:embed queries/javascript/highlights.scm
var javascriptHighlightsQuery string
+//go:embed queries/python/highlights.scm
+var pythonHighlightsQuery string
+
+//go:embed queries/rust/highlights.scm
+var rustHighlightsQuery string
+
+//go:embed queries/typescript/highlights.scm
+var typescriptHighlightsQuery string
+
+//go:embed queries/tsx/highlights.scm
+var tsxHighlightsQuery string
+
+//go:embed queries/bash/highlights.scm
+var bashHighlightsQuery string
+
+//go:embed queries/json/highlights.scm
+var jsonHighlightsQuery string
+
+//go:embed queries/css/highlights.scm
+var cssHighlightsQuery string
+
+//go:embed queries/html/highlights.scm
+var htmlHighlightsQuery string
+
+//go:embed queries/c/highlights.scm
+var cHighlightsQuery string
+
+//go:embed queries/cpp/highlights.scm
+var cppHighlightsQuery string
+
+//go:embed queries/java/highlights.scm
+var javaHighlightsQuery string
+
+//go:embed queries/csharp/highlights.scm
+var csharpHighlightsQuery string
+
+//go:embed queries/ruby/highlights.scm
+var rubyHighlightsQuery string
+
func loadGoHighlightsQuery() ([]byte, error) {
return []byte(goHighlightsQuery), nil
}
@@ -15,3 +54,55 @@ func loadGoHighlightsQuery() ([]byte, error) {
func loadJavaScriptHighlightsQuery() ([]byte, error) {
return []byte(javascriptHighlightsQuery), nil
}
+
+func loadPythonHighlightsQuery() ([]byte, error) {
+ return []byte(pythonHighlightsQuery), nil
+}
+
+func loadRustHighlightsQuery() ([]byte, error) {
+ return []byte(rustHighlightsQuery), nil
+}
+
+func loadTypeScriptHighlightsQuery() ([]byte, error) {
+ return []byte(typescriptHighlightsQuery), nil
+}
+
+func loadTSXHighlightsQuery() ([]byte, error) {
+ return []byte(tsxHighlightsQuery), nil
+}
+
+func loadBashHighlightsQuery() ([]byte, error) {
+ return []byte(bashHighlightsQuery), nil
+}
+
+func loadJSONHighlightsQuery() ([]byte, error) {
+ return []byte(jsonHighlightsQuery), nil
+}
+
+func loadCSSHighlightsQuery() ([]byte, error) {
+ return []byte(cssHighlightsQuery), nil
+}
+
+func loadHTMLHighlightsQuery() ([]byte, error) {
+ return []byte(htmlHighlightsQuery), nil
+}
+
+func loadCHighlightsQuery() ([]byte, error) {
+ return []byte(cHighlightsQuery), nil
+}
+
+func loadCppHighlightsQuery() ([]byte, error) {
+ return []byte(cppHighlightsQuery), nil
+}
+
+func loadJavaHighlightsQuery() ([]byte, error) {
+ return []byte(javaHighlightsQuery), nil
+}
+
+func loadCSharpHighlightsQuery() ([]byte, error) {
+ return []byte(csharpHighlightsQuery), nil
+}
+
+func loadRubyHighlightsQuery() ([]byte, error) {
+ return []byte(rubyHighlightsQuery), nil
+}
diff --git a/internal/syntax/query_assets_test.go b/internal/syntax/query_assets_test.go
index e3c77cc..0e69527 100644
--- a/internal/syntax/query_assets_test.go
+++ b/internal/syntax/query_assets_test.go
@@ -4,40 +4,98 @@ import (
"testing"
sitter "github.com/tree-sitter/go-tree-sitter"
+ ts_bash "github.com/tree-sitter/tree-sitter-bash/bindings/go"
+ ts_csharp "github.com/tree-sitter/tree-sitter-c-sharp/bindings/go"
+ ts_c "github.com/tree-sitter/tree-sitter-c/bindings/go"
+ ts_cpp "github.com/tree-sitter/tree-sitter-cpp/bindings/go"
+ ts_css "github.com/tree-sitter/tree-sitter-css/bindings/go"
ts_go "github.com/tree-sitter/tree-sitter-go/bindings/go"
+ ts_html "github.com/tree-sitter/tree-sitter-html/bindings/go"
+ ts_java "github.com/tree-sitter/tree-sitter-java/bindings/go"
ts_js "github.com/tree-sitter/tree-sitter-javascript/bindings/go"
+ ts_json "github.com/tree-sitter/tree-sitter-json/bindings/go"
+ ts_python "github.com/tree-sitter/tree-sitter-python/bindings/go"
+ ts_ruby "github.com/tree-sitter/tree-sitter-ruby/bindings/go"
+ ts_rust "github.com/tree-sitter/tree-sitter-rust/bindings/go"
+ ts_ts "github.com/tree-sitter/tree-sitter-typescript/bindings/go"
)
-func TestEmbeddedGoQueryCompiles(t *testing.T) {
- b, err := loadGoHighlightsQuery()
- if err != nil {
- t.Fatalf("failed loading embedded query: %v", err)
- }
- if len(b) == 0 {
- t.Fatalf("embedded query is empty")
+func TestEmbeddedQueriesLoadAndCompile(t *testing.T) {
+ tests := []struct {
+ name string
+ loadQuery func() ([]byte, error)
+ expectNonNil bool
+ }{
+ {name: "go", loadQuery: loadGoHighlightsQuery, expectNonNil: true},
+ {name: "javascript", loadQuery: loadJavaScriptHighlightsQuery, expectNonNil: true},
+ {name: "typescript", loadQuery: loadTypeScriptHighlightsQuery, expectNonNil: true},
+ {name: "tsx", loadQuery: loadTSXHighlightsQuery, expectNonNil: true},
+ {name: "python", loadQuery: loadPythonHighlightsQuery, expectNonNil: true},
+ {name: "rust", loadQuery: loadRustHighlightsQuery, expectNonNil: true},
+ {name: "bash", loadQuery: loadBashHighlightsQuery, expectNonNil: true},
+ {name: "json", loadQuery: loadJSONHighlightsQuery, expectNonNil: true},
+ {name: "css", loadQuery: loadCSSHighlightsQuery, expectNonNil: true},
+ {name: "html", loadQuery: loadHTMLHighlightsQuery, expectNonNil: true},
+ {name: "c", loadQuery: loadCHighlightsQuery, expectNonNil: true},
+ {name: "cpp", loadQuery: loadCppHighlightsQuery, expectNonNil: true},
+ {name: "java", loadQuery: loadJavaHighlightsQuery, expectNonNil: true},
+ {name: "csharp", loadQuery: loadCSharpHighlightsQuery, expectNonNil: true},
+ {name: "ruby", loadQuery: loadRubyHighlightsQuery, expectNonNil: true},
}
- lang := sitter.NewLanguage(ts_go.Language())
- q, qErr := sitter.NewQuery(lang, string(b))
- if qErr != nil {
- t.Fatalf("embedded go query failed to compile: %v", qErr)
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ b, err := tc.loadQuery()
+ if err != nil {
+ t.Fatalf("failed loading embedded query: %v", err)
+ }
+ if tc.expectNonNil && b == nil {
+ t.Fatalf("expected non-nil embedded query bytes")
+ }
+
+ })
}
- q.Close()
}
-func TestEmbeddedJavaScriptQueryCompiles(t *testing.T) {
- b, err := loadJavaScriptHighlightsQuery()
- if err != nil {
- t.Fatalf("failed loading embedded query: %v", err)
- }
- if len(b) == 0 {
- t.Fatalf("embedded query is empty")
+func TestEmbeddedQueriesCompileKnownGood(t *testing.T) {
+ compileTests := []struct {
+ name string
+ loadQuery func() ([]byte, error)
+ newLanguage func() *sitter.Language
+ }{
+ {name: "go", loadQuery: loadGoHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_go.Language()) }},
+ {name: "javascript", loadQuery: loadJavaScriptHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_js.Language()) }},
+ {name: "typescript", loadQuery: loadTypeScriptHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_ts.LanguageTypescript()) }},
+ {name: "tsx", loadQuery: loadTSXHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_ts.LanguageTSX()) }},
+ {name: "python", loadQuery: loadPythonHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_python.Language()) }},
+ {name: "rust", loadQuery: loadRustHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_rust.Language()) }},
+ {name: "bash", loadQuery: loadBashHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_bash.Language()) }},
+ {name: "json", loadQuery: loadJSONHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_json.Language()) }},
+ {name: "css", loadQuery: loadCSSHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_css.Language()) }},
+ {name: "html", loadQuery: loadHTMLHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_html.Language()) }},
+ {name: "c", loadQuery: loadCHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_c.Language()) }},
+ {name: "cpp", loadQuery: loadCppHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_cpp.Language()) }},
+ {name: "java", loadQuery: loadJavaHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_java.Language()) }},
+ {name: "csharp", loadQuery: loadCSharpHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_csharp.Language()) }},
+ {name: "ruby", loadQuery: loadRubyHighlightsQuery, newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_ruby.Language()) }},
}
- lang := sitter.NewLanguage(ts_js.Language())
- q, qErr := sitter.NewQuery(lang, string(b))
- if qErr != nil {
- t.Fatalf("embedded javascript query failed to compile: %v", qErr)
+ for _, tc := range compileTests {
+ t.Run(tc.name, func(t *testing.T) {
+ b, err := tc.loadQuery()
+ if err != nil {
+ t.Fatalf("failed loading embedded query: %v", err)
+ }
+ lang := tc.newLanguage()
+ if lang == nil {
+ t.Fatalf("language handle is nil")
+ }
+
+ q, qErr := sitter.NewQuery(lang, string(b))
+ if qErr != nil {
+ t.Fatalf("embedded query failed to compile: %v", qErr)
+ }
+ q.Close()
+ })
}
- q.Close()
}
diff --git a/internal/syntax/registry.go b/internal/syntax/registry.go
index 90e2a21..1ff8266 100644
--- a/internal/syntax/registry.go
+++ b/internal/syntax/registry.go
@@ -5,8 +5,20 @@ import (
"strings"
sitter "github.com/tree-sitter/go-tree-sitter"
+ ts_bash "github.com/tree-sitter/tree-sitter-bash/bindings/go"
+ ts_csharp "github.com/tree-sitter/tree-sitter-c-sharp/bindings/go"
+ ts_c "github.com/tree-sitter/tree-sitter-c/bindings/go"
+ ts_cpp "github.com/tree-sitter/tree-sitter-cpp/bindings/go"
+ ts_css "github.com/tree-sitter/tree-sitter-css/bindings/go"
ts_go "github.com/tree-sitter/tree-sitter-go/bindings/go"
+ ts_html "github.com/tree-sitter/tree-sitter-html/bindings/go"
+ ts_java "github.com/tree-sitter/tree-sitter-java/bindings/go"
ts_js "github.com/tree-sitter/tree-sitter-javascript/bindings/go"
+ ts_json "github.com/tree-sitter/tree-sitter-json/bindings/go"
+ ts_python "github.com/tree-sitter/tree-sitter-python/bindings/go"
+ ts_ruby "github.com/tree-sitter/tree-sitter-ruby/bindings/go"
+ ts_rust "github.com/tree-sitter/tree-sitter-rust/bindings/go"
+ ts_ts "github.com/tree-sitter/tree-sitter-typescript/bindings/go"
)
type languagePack struct {
@@ -70,6 +82,110 @@ func newLanguageRegistry() *languageRegistry {
loadQuery: loadJavaScriptHighlightsQuery,
})
+ r.register(languagePack{
+ id: "typescript",
+ filetypes: []string{"typescript", "ts"},
+ extensions: []string{".ts"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_ts.LanguageTypescript()) },
+ loadQuery: loadTypeScriptHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "tsx",
+ filetypes: []string{"tsx"},
+ extensions: []string{".tsx"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_ts.LanguageTSX()) },
+ loadQuery: loadTSXHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "python",
+ filetypes: []string{"python", "py"},
+ extensions: []string{".py"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_python.Language()) },
+ loadQuery: loadPythonHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "rust",
+ filetypes: []string{"rust", "rs"},
+ extensions: []string{".rs"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_rust.Language()) },
+ loadQuery: loadRustHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "bash",
+ filetypes: []string{"bash", "sh", "shell"},
+ extensions: []string{".sh", ".bash"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_bash.Language()) },
+ loadQuery: loadBashHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "json",
+ filetypes: []string{"json"},
+ extensions: []string{".json"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_json.Language()) },
+ loadQuery: loadJSONHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "css",
+ filetypes: []string{"css"},
+ extensions: []string{".css"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_css.Language()) },
+ loadQuery: loadCSSHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "html",
+ filetypes: []string{"html"},
+ extensions: []string{".html", ".htm"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_html.Language()) },
+ loadQuery: loadHTMLHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "c",
+ filetypes: []string{"c"},
+ extensions: []string{".c", ".h"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_c.Language()) },
+ loadQuery: loadCHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "cpp",
+ filetypes: []string{"cpp", "c++", "hpp"},
+ extensions: []string{".cc", ".cpp", ".cxx", ".hpp", ".hh", ".hxx"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_cpp.Language()) },
+ loadQuery: loadCppHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "java",
+ filetypes: []string{"java"},
+ extensions: []string{".java"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_java.Language()) },
+ loadQuery: loadJavaHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "csharp",
+ filetypes: []string{"csharp", "cs"},
+ extensions: []string{".cs"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_csharp.Language()) },
+ loadQuery: loadCSharpHighlightsQuery,
+ })
+
+ r.register(languagePack{
+ id: "ruby",
+ filetypes: []string{"ruby", "rb"},
+ extensions: []string{".rb"},
+ newLanguage: func() *sitter.Language { return sitter.NewLanguage(ts_ruby.Language()) },
+ loadQuery: loadRubyHighlightsQuery,
+ })
+
return r
}