This repository contains a tree-sitter grammar for NATS server configuration files.
The grammar parses .conf files used by nats-server. Key source files:
grammar.js— the grammar definition (entry point for tree-sitter)src/scanner.c— external scanner for context-sensitive tokens (bare strings, comments, identifiers, booleans)queries/— highlight, fold, indent, and locals queries (.scmfiles)test/corpus/— tree-sitter test corpus (.txtfiles)examples/— sample NATS config files used bytree-sitter parse --stat
- Node.js 22.x (see
.tool-versions; Node 24+ is incompatible with tree-sitter-cli 0.25.x) - tree-sitter CLI — install via
cargo install tree-sitter-cli(not an npm dependency) - Task (optional but recommended) — task runner;
see
Taskfile.yaml
All commands assume you are in the repository root.
npm ci
command -v tree-sitter || cargo install tree-sitter-cliAfter editing grammar.js, regenerate the C parser:
tree-sitter generate # or: task generatetree-sitter test # or: task testThis runs the corpus in test/corpus/. Every test file contains input
fragments and expected S-expression parse trees. When adding or changing
grammar rules, update or add corpus tests to cover them.
tree-sitter parse examples/*.conf --stat # or: task test:parse-examplesAll example files must parse without errors.
task ci:testThis runs both test and test:parse-examples.
- Edit
grammar.js(andsrc/scanner.cif the change involves external tokens). - Run
tree-sitter generateto regeneratesrc/parser.c. - Add or update test cases in
test/corpus/. - Run
tree-sitter test— all tests must pass. - Run
tree-sitter parse examples/*.conf --stat— no errors allowed. - If the change adds or renames node types, update the queries in
queries/to match.
highlights.scm— syntax highlightingfolds.scm— code folding regionsindents.scm— auto-indentation ruleslocals.scm— scope/reference tracking
After editing queries, run tree-sitter test to ensure they are still valid
against the grammar. Highlight queries can be previewed with
tree-sitter highlight examples/full.conf.
Tests use tree-sitter's standard format:
===
Test name
===
input text
---
(expected_sexpression)
Group related tests in the appropriate file (e.g., blocks.txt for block
syntax, types.txt for value types). Each test should be focused and minimal.
These are per-editor setup guides. When changing grammar node names or query file structure, review and update affected editor docs.
The GitHub Actions workflow (.github/workflows/ci.yaml) runs on pushes to
main and on pull requests. It runs two jobs:
- Test —
task ci:test(generate, test, parse examples) - Check GitHub Actions — lints workflows with zizmor
All CI checks must pass before merging.
grammar.jsuses the tree-sitter DSL (grammar(),seq(),choice(),repeat(), etc.). Keep rules concise and well-commented.- The external scanner (
src/scanner.c) is plain C. Follow the existing style and keep functions short. - Query files (
.scm) use S-expression syntax. One capture pattern per line. - Do not edit
src/parser.cby hand — it is generated. - Do not commit
node_modules/, build artifacts, or.wasmfiles (see.gitignore).