feat: implemented more languages
All checks were successful
Run Test Suite / test (push) Successful in 35s

HTML isnt great, but I guess there isnt much to color, or maybe its just
the styles. The next step is making the colorschemes.
This commit is contained in:
Hayden Hargreaves 2026-04-07 11:40:34 -07:00
parent 760b7dd15a
commit 6034e44364
20 changed files with 5820 additions and 651 deletions

View File

@ -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

12
go.mod
View File

@ -7,8 +7,20 @@ require (
github.com/charmbracelet/lipgloss v1.1.0 github.com/charmbracelet/lipgloss v1.1.0
github.com/charmbracelet/x/exp/teatest v0.0.0-20260209132835-6b065b8ba62c 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/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-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-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 ( require (

20
go.sum
View File

@ -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/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 h1:sx6kcg8raRFCvc9BnXglke6axya12krCJF5xJ2sftRU=
github.com/tree-sitter/go-tree-sitter v0.25.0/go.mod h1:r77ig7BikoZhHrrsjAnv8RqGti5rtSyvDHPzgTPsUuU= 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-bash v0.25.1 h1:ZD3MK4oDB5lAsFztqbdcyYEd24pxDtx3g9UOWA062rE=
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/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 h1:LaWZsiqQKvR65yHgKmnaqA+uz6tlDJTJFCyFIeZU/8w=
github.com/tree-sitter/tree-sitter-cpp v0.23.4/go.mod h1:doqNW64BriC7WBCQ1klf0KmJpdEvfxyXtoEybnBo6v8= 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 h1:nFkkH6Sbe56EXLmZBqHHcamTpmz3TId97I16EnGy4rg=
github.com/tree-sitter/tree-sitter-embedded-template v0.23.2/go.mod h1:HNPOhN0qF3hWluYLdxWs5WbzP/iE4aaRVPMsdxuzIaQ= 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= 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-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 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-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.25.0 h1:O6XD9v8U1LOcRc3cNj9nM7XufrtEBezE6VrpRrHZDf0=
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/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 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-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.24.2 h1:NL4nF67ib21RMzzfvkmXlVwe45vvhW10DVyO+D0z/W0=
github.com/tree-sitter/tree-sitter-rust v0.23.2/go.mod h1:hfeGWic9BAfgTrc7Xf6FaOAguCFJRo3RBbs7QJ6D7MI= 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 h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= 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= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=

View File

@ -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 "^#!/"))

View File

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

View File

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

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

@ -1,151 +1,295 @@
; Types
; Javascript
; Variables ; Variables
;---------- ;-----------
(identifier) @variable (identifier) @variable
; Properties ; 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 and method definitions
;-------------------------------- ;--------------------------------
(function_expression (function_expression
name: (identifier) @function) name: (identifier) @function)
(function_declaration (function_declaration
name: (identifier) @function) name: (identifier) @function)
(generator_function
name: (identifier) @function)
(generator_function_declaration
name: (identifier) @function)
(method_definition (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 (pair
key: (property_identifier) @function.method key: (property_identifier) @function.method
value: [(function_expression) (arrow_function)]) value: (function_expression))
(pair
key: (property_identifier) @function.method
value: (arrow_function))
(assignment_expression (assignment_expression
left: (member_expression left: (member_expression
property: (property_identifier) @function.method) 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 (variable_declarator
name: (identifier) @function name: (identifier) @function
value: [(function_expression) (arrow_function)]) value: (arrow_function))
(variable_declarator
name: (identifier) @function
value: (function_expression))
(assignment_expression (assignment_expression
left: (identifier) @function left: (identifier) @function
right: [(function_expression) (arrow_function)]) right: (arrow_function))
(assignment_expression
left: (identifier) @function
right: (function_expression))
; Function and method calls ; Function and method calls
;-------------------------- ;--------------------------
(call_expression (call_expression
function: (identifier) @function) function: (identifier) @function.call)
(call_expression (call_expression
function: (member_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 (call_expression
(#match? @constructor "^[A-Z]")) function: (await_expression
(member_expression
property: [
(property_identifier)
(private_property_identifier)
] @function.method.call)))
([ ; Builtins
(identifier) ;---------
(shorthand_property_identifier) ((identifier) @module.builtin
(shorthand_property_identifier_pattern) (#eq? @module.builtin "Intl"))
] @constant
(#match? @constant "^[A-Z_][A-Z\\d_]+$"))
((identifier) @variable.builtin
(#match? @variable.builtin "^(arguments|module|console|window|document)$")
(#is-not? local))
((identifier) @function.builtin ((identifier) @function.builtin
(#eq? @function.builtin "require") (#any-of? @function.builtin
(#is-not? local)) "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 ; Literals
;--------- ;---------
[
(this)
(super)
] @variable.builtin
(this) @variable.builtin ((identifier) @variable.builtin
(super) @variable.builtin (#eq? @variable.builtin "self"))
[ [
(true) (true)
(false) (false)
] @boolean
[
(null) (null)
(undefined) (undefined)
] @constant.builtin ] @constant.builtin
(comment) @comment
[ [
(string) (comment)
(template_string) (html_comment)
] @string ] @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 (number) @number
; Tokens ((identifier) @number
;------- (#any-of? @number "NaN" "Infinity"))
; Punctuation
;------------
[ [
";" ";"
(optional_chain)
"." "."
"," ","
":"
] @punctuation.delimiter ] @punctuation.delimiter
[ [
"-"
"--" "--"
"-"
"-=" "-="
"&&"
"+" "+"
"++" "++"
"+=" "+="
"*" "&="
"*="
"**"
"**="
"/"
"/=" "/="
"%" "**="
"%=" "<<="
"<" "<"
"<=" "<="
"<<" "<<"
"<<="
"=" "="
"==" "=="
"===" "==="
"!"
"!=" "!="
"!==" "!=="
"=>" "=>"
">" ">"
">=" ">="
">>" ">>"
">>=" "||"
"%"
"%="
"*"
"**"
">>>" ">>>"
">>>="
"~"
"^"
"&" "&"
"|" "|"
"^=" "^"
"&="
"|="
"&&"
"||"
"??" "??"
"*="
">>="
">>>="
"^="
"|="
"&&=" "&&="
"||=" "||="
"??=" "??="
"..."
] @operator ] @operator
(binary_expression
"/" @operator)
(ternary_expression
[
"?"
":"
] @keyword.conditional.ternary)
(unary_expression
[
"!"
"~"
"-"
"+"
] @operator)
(unary_expression
[
"delete"
"void"
] @keyword.operator)
[ [
"(" "("
")" ")"
@ -156,49 +300,306 @@
] @punctuation.bracket ] @punctuation.bracket
(template_substitution (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" "import"
"in" "from"
"instanceof" "as"
"let" "export"
"new" ] @keyword.import
[
"for"
"of" "of"
"return" "do"
"while"
"continue"
] @keyword.repeat
[
"break"
"const"
"debugger"
"extends"
"get"
"let"
"set" "set"
"static" "static"
"switch"
"target" "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" "throw"
"try" "try"
"typeof" "catch"
"var" "finally"
"void" ] @keyword.exception
"while"
"with" (export_statement
"yield" "default" @keyword)
] @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 - <My.Component>
(jsx_opening_element
(member_expression
(identifier) @tag.builtin
(property_identifier) @tag))
(jsx_closing_element
((identifier) @tag
(#lua-match? @tag "^[A-Z]")))
; Handle the dot operator effectively - </My.Component>
(jsx_closing_element
(member_expression
(identifier) @tag.builtin
(property_identifier) @tag))
(jsx_self_closing_element
((identifier) @tag
(#lua-match? @tag "^[A-Z]")))
; Handle the dot operator effectively - <My.Component />
(jsx_self_closing_element
(member_expression
(identifier) @tag.builtin
(property_identifier) @tag))
(html_character_reference) @tag
(jsx_text) @none @spell
(html_character_reference) @character.special
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading)
(#eq? @_tag "title"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.1)
(#eq? @_tag "h1"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.2)
(#eq? @_tag "h2"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.3)
(#eq? @_tag "h3"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.4)
(#eq? @_tag "h4"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.5)
(#eq? @_tag "h5"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.heading.6)
(#eq? @_tag "h6"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.strong)
(#any-of? @_tag "strong" "b"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.italic)
(#any-of? @_tag "em" "i"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.strikethrough)
(#any-of? @_tag "s" "del"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.underline)
(#eq? @_tag "u"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.raw)
(#any-of? @_tag "code" "kbd"))
((jsx_element
(jsx_opening_element
name: (identifier) @_tag)
(jsx_text) @markup.link.label)
(#eq? @_tag "a"))
((jsx_attribute
(property_identifier) @_attr
(string
(string_fragment) @string.special.url))
(#any-of? @_attr "href" "src"))
((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

View File

@ -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 "\""))

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
]))

View File

@ -8,6 +8,45 @@ var goHighlightsQuery string
//go:embed queries/javascript/highlights.scm //go:embed queries/javascript/highlights.scm
var javascriptHighlightsQuery string 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) { func loadGoHighlightsQuery() ([]byte, error) {
return []byte(goHighlightsQuery), nil return []byte(goHighlightsQuery), nil
} }
@ -15,3 +54,55 @@ func loadGoHighlightsQuery() ([]byte, error) {
func loadJavaScriptHighlightsQuery() ([]byte, error) { func loadJavaScriptHighlightsQuery() ([]byte, error) {
return []byte(javascriptHighlightsQuery), nil 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
}

View File

@ -4,40 +4,98 @@ import (
"testing" "testing"
sitter "github.com/tree-sitter/go-tree-sitter" 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_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_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) { func TestEmbeddedQueriesLoadAndCompile(t *testing.T) {
b, err := loadGoHighlightsQuery() 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},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
b, err := tc.loadQuery()
if err != nil { if err != nil {
t.Fatalf("failed loading embedded query: %v", err) t.Fatalf("failed loading embedded query: %v", err)
} }
if len(b) == 0 { if tc.expectNonNil && b == nil {
t.Fatalf("embedded query is empty") t.Fatalf("expected non-nil embedded query bytes")
} }
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)
} }
q.Close()
} }
func TestEmbeddedJavaScriptQueryCompiles(t *testing.T) { func TestEmbeddedQueriesCompileKnownGood(t *testing.T) {
b, err := loadJavaScriptHighlightsQuery() 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()) }},
}
for _, tc := range compileTests {
t.Run(tc.name, func(t *testing.T) {
b, err := tc.loadQuery()
if err != nil { if err != nil {
t.Fatalf("failed loading embedded query: %v", err) t.Fatalf("failed loading embedded query: %v", err)
} }
if len(b) == 0 { lang := tc.newLanguage()
t.Fatalf("embedded query is empty") if lang == nil {
t.Fatalf("language handle is nil")
} }
lang := sitter.NewLanguage(ts_js.Language())
q, qErr := sitter.NewQuery(lang, string(b)) q, qErr := sitter.NewQuery(lang, string(b))
if qErr != nil { if qErr != nil {
t.Fatalf("embedded javascript query failed to compile: %v", qErr) t.Fatalf("embedded query failed to compile: %v", qErr)
} }
q.Close() q.Close()
})
}
} }

View File

@ -5,8 +5,20 @@ import (
"strings" "strings"
sitter "github.com/tree-sitter/go-tree-sitter" 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_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_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 { type languagePack struct {
@ -70,6 +82,110 @@ func newLanguageRegistry() *languageRegistry {
loadQuery: loadJavaScriptHighlightsQuery, 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 return r
} }