feat: align grammar, snippets, and diagnostics with upstream Sigil #1

Merged
rdenadai merged 11 commits from feat/v0.2.0-syntax-update into main 2026-09-12 21:59:49 +00:00
Owner

Summary

Catch the extension up to the current Sigil language. Adds grammar support for keywords/types/operators/decorators added upstream, expands snippets, hardens diagnostics parsing, and splits declaration keywords from their bindings so they render distinctly in color themes like Catppuccin.

Grammar (syntaxes/sigil.tmLanguage.json)

New syntax

  • Byte literal b'...'
  • Range operators .. and ..=
  • Cast pattern int32(x), float64(x), … (with lookbehind so .method() calls aren't misclassified)
  • Bare @ decorator operator
  • Type qualifiers linear, affine, count, at_least
  • TitleCase types Self, None, Object, Callable
  • Generic PascalCase type rule so user types (Person, Calculator, Result, Option, Union, …) render in the same color as None

New keywords

  • Declarations: class, record, protocol, enum, struct, union, effect, module, fn/function
  • Variable modifiers: var, live, global, local, async, reloadable
  • Control flow: await, yield, defer, errdefer, raise, throw, catch, finally, assert, goto, handle, using, perform, resume, abort, until
  • Regions/memory: region, alloc, to_heap, to_region, migrate, literal
  • Macros/meta: macro, quote, case, comptime

Math unicode aliases

, , , ¬, , (in addition to existing λ/Λ)

Visual fixes (theme parity)

  • let/constkeyword.declaration (was variable.other.assignment, uncolored in Catppuccin)
  • fn/functionkeyword.declaration (was inside entity.name.function, same color issue)
  • class/record/protocol/enum/struct/union/effect/ modulekeyword.declaration
  • Variable name / function name / type name after each keyword gets its own scope via lookbehind (entity.name.variable, entity.name.function, entity.name.type)
  • PascalCase identifiers → support.type

Internal

  • Integer lookahead adjusted so ranges (0..10) tokenize correctly
  • entity.name.type.class consolidated into entity.name.type + lookbehind
  • Trimmed storage.modifier to drop keywords now handled by keyword.declaration

Snippets (snippets/sigil.json)

18 new: match, matchexpr, try, tryexpr, import, importas, from, pubfn, decorator, lambda_kw, lambda_typed, record, protocol, enum, struct, union, effect, range, rangei, assert.

Language config (language-configuration.json)

  • catch added to decreaseIndentPattern
  • New onEnterRules for catch/finally (outdent)

Diagnostics (src/extension.ts, package.json)

  • Severity mapping extended to info and hint (compiler can now emit non-error severities)
  • Schema mismatches and malformed JSON envelope logged to the Sigil output channel instead of being silently dropped
  • Fixed broken test:grammar script (.mjs.cjs)
  • Bumped version 0.1.00.2.0

Housekeeping

  • .gitignore: dropped bun.lock (unused) and package-lock.json (npm-based project; lockfile should be tracked)
## Summary Catch the extension up to the current Sigil language. Adds grammar support for keywords/types/operators/decorators added upstream, expands snippets, hardens diagnostics parsing, and splits declaration keywords from their bindings so they render distinctly in color themes like Catppuccin. ## Grammar (`syntaxes/sigil.tmLanguage.json`) ### New syntax - **Byte literal** `b'...'` - **Range operators** `..` and `..=` - **Cast pattern** `int32(x)`, `float64(x)`, … (with lookbehind so `.method()` calls aren't misclassified) - **Bare `@` decorator operator** - **Type qualifiers** `linear`, `affine`, `count`, `at_least` - **TitleCase types** `Self`, `None`, `Object`, `Callable` - **Generic PascalCase type rule** so user types (`Person`, `Calculator`, `Result`, `Option`, `Union`, …) render in the same color as `None` ### New keywords - **Declarations**: `class`, `record`, `protocol`, `enum`, `struct`, `union`, `effect`, `module`, `fn`/`function` - **Variable modifiers**: `var`, `live`, `global`, `local`, `async`, `reloadable` - **Control flow**: `await`, `yield`, `defer`, `errdefer`, `raise`, `throw`, `catch`, `finally`, `assert`, `goto`, `handle`, `using`, `perform`, `resume`, `abort`, `until` - **Regions/memory**: `region`, `alloc`, `to_heap`, `to_region`, `migrate`, `literal` - **Macros/meta**: `macro`, `quote`, `case`, `comptime` ### Math unicode aliases `∈`, `∧`, `∨`, `¬`, `∃`, `∀` (in addition to existing `λ`/`Λ`) ### Visual fixes (theme parity) - `let`/`const` → `keyword.declaration` (was `variable.other.assignment`, uncolored in Catppuccin) - `fn`/`function` → `keyword.declaration` (was inside `entity.name.function`, same color issue) - `class`/`record`/`protocol`/`enum`/`struct`/`union`/`effect`/ `module` → `keyword.declaration` - Variable name / function name / type name after each keyword gets its own scope via lookbehind (`entity.name.variable`, `entity.name.function`, `entity.name.type`) - PascalCase identifiers → `support.type` ### Internal - Integer lookahead adjusted so ranges (`0..10`) tokenize correctly - `entity.name.type.class` consolidated into `entity.name.type` + lookbehind - Trimmed `storage.modifier` to drop keywords now handled by `keyword.declaration` ## Snippets (`snippets/sigil.json`) 18 new: `match`, `matchexpr`, `try`, `tryexpr`, `import`, `importas`, `from`, `pubfn`, `decorator`, `lambda_kw`, `lambda_typed`, `record`, `protocol`, `enum`, `struct`, `union`, `effect`, `range`, `rangei`, `assert`. ## Language config (`language-configuration.json`) - `catch` added to `decreaseIndentPattern` - New `onEnterRules` for `catch`/`finally` (outdent) ## Diagnostics (`src/extension.ts`, `package.json`) - Severity mapping extended to `info` and `hint` (compiler can now emit non-error severities) - Schema mismatches and malformed JSON envelope logged to the Sigil output channel instead of being silently dropped - Fixed broken `test:grammar` script (`.mjs` → `.cjs`) - Bumped version `0.1.0` → `0.2.0` ## Housekeeping - `.gitignore`: dropped `bun.lock` (unused) and `package-lock.json` (npm-based project; lockfile should be tracked)
Grammar:
- byte literal b'...'
- range operators .. and ..=
- cast pattern (int32(x), float64(x), ...) with proper lookbehind
- bare @ decorator operator
- new keywords: record, protocol, enum, struct, union, effect, macro,
  module, export, var, live, global, local, async, reloadable,
  migrate, literal, linear, affine, count, at_least, quote, case,
  comptime
- new control flow: await, yield, defer, errdefer, raise, throw,
  catch, finally, assert, goto, handle, using, perform, resume,
  abort, until, region, alloc, to_heap, to_region
- type qualifiers + Self/None/Object/Callable types
- math unicode aliases (∈, ∧, ∨, ¬, ∃, ∀)
- rename let/const scope to keyword.declaration for theme parity
- adjust integer lookahead so ranges (0..10) tokenize correctly

Snippets: 18 new (match, try, import, pub fn, decorator, record,
protocol, enum, struct, union, effect, lambda typed, range, assert).

Language-config: catch in decreaseIndentPattern + onEnterRules for
catch/finally.

Diagnostics: map info/hint severities; log schema mismatches and
invalid JSON in output channel.

Test:grammar wiring fixed (.mjs -> .cjs); new fixtures cover all
above syntax.
Use lookbehind to give the name after let/const its own
entity.name.variable scope. Previously the whole "let x" matched
keyword.declaration in one token, so 'x' rendered in the keyword
color. Now 'let'/'const' render as keyword.declaration and 'x'
renders as entity.name.variable (default variable color).
- bun.lock: not used (project is npm-based)
- package-lock.json: tracking the lockfile is the convention for
  npm projects and helps reproducible installs.
Add fn/function to keyword.declaration rule and use lookbehind on
entity.name.function so the name after fn/function gets its own
scope. Mirrors the let/const split: keyword color for the
declaration keyword, distinct color for the binding name.
Add class, record, protocol, enum, struct, union, effect, module to
keyword.declaration and introduce entity.name.type via lookbehind,
matching the let/const and fn/function split. Removes the dedicated
entity.name.type.class rule and trims storage.modifier accordingly.
feat(grammar): highlight PascalCase identifiers as support.type
Some checks failed
ci / test (pull_request) Has been cancelled
c83f585b85
Custom user types like Person, Result, Option, Union, Unknown,
Calculator and any other TitleCase identifier in type position
are now scoped as support.type so they render in the same color
as None/Object/Callable in Catppuccin and other themes.
ci: harden workflow with caching, json validation, artifact upload
Some checks failed
ci / build (pull_request) Has been cancelled
8a1dd5deef
- cache: npm via setup-node for faster installs
- drop dead vscode-oniguruma install (test harness uses native JS regex)
- drop redundant --no-save installs (deps are in devDependencies)
- validate JSON files (package, snippets, grammars, language-config)
- upload .vsix as artifact for easy install
- trigger on tags (v*) in addition to main and PRs
ci: drop GitHub workflow, keep Forgejo only
Some checks failed
ci / build (pull_request) Has been cancelled
e8fe5ebafc
ci: run on 'ubuntu' label to match registered Forgejo runner
Some checks failed
ci / build (pull_request) Failing after 2m4s
3cdf41c3de
The self-hosted runner is registered with label 'ubuntu', not the
GitHub-Actions-style 'ubuntu-latest'. Forgejo Actions matches
labels literally, so the previous label kept jobs queued forever.
chore: commit package-lock.json for reproducible builds
Some checks failed
ci / build (pull_request) Failing after 5m5s
2ff6f41538
setup-node@v4 with cache: npm requires a lockfile to manage the
cache. Generate it from the current devDependencies so CI can use
the cache and installs are reproducible.
ci: downgrade upload-artifact to v3 for GHES-compatible backends
All checks were successful
ci / build (pull_request) Successful in 10m21s
a237bcbea1
Forgejo Actions with GHES-like artifact backend doesn't support
upload-artifact@v4. v3 has the same API surface and works
everywhere.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rdenadai/sigil-vscode-language-support!1
No description provided.