Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>CAVE LanguageNew to Visual Studio Code? Get it now.
CAVE Language

CAVE Language

Mirek Rusin

|
7 installs
| (0) | Free
CAVE language support — syntax highlighting driven by the @cavelang/tree-sitter-cave grammar via semantic tokens.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

CAVE for VSCode

Language support for CAVE (.cave files).

Highlighting is a semantic-tokens provider running the @cavelang/tree-sitter-cave grammar (WASM, via web-tree-sitter) with the grammar's own queries/highlights.scm — the exact query Neovim/Helix/Zed and the cave highlight terminal command use. One grammar, every surface; there is deliberately no TextMate grammar to drift out of sync. Explicit @claim markers use keyword tokens; reserved and numeric-looking subjects retain entity tokens, and trailing @claim contexts retain context highlighting.

The extension owns one parser and compiled query for its activation lifetime. Disposal unregisters the token provider and frees both native resources; failed activation frees any resources already allocated. Each document tree is freed after token generation, including when querying or building tokens fails. Cleanup still attempts to free the query if parser disposal throws; subsequent provider calls return no tokens without reading the document. If activation or token generation and cleanup both fail, an AggregateError retains the original error as its cause and first entry, followed by the cleanup error. Multiple disposal failures are retained in provider, parser, then query cleanup order. A single failure is propagated unchanged. Disposal is attempted once per resource; a failed cleanup is not retried automatically. Requests already cancelled by the editor return no tokens before reading or parsing the document; later active requests use the same provider normally. Parsing remains synchronous, so this entry check does not interrupt a parse already in progress.

Also contributes ; line comments, "/` auto-closing pairs, and the cave language id.

CAVE files default to two-space indentation with automatic indentation detection disabled. Tab inserts spaces rather than introducing tab indentation that the CAVE parser rejects. These are language-specific defaults; explicit [cave] user or workspace settings can override them. Existing file contents are not rewritten. See VS Code's indentation settings for the editor controls.

Build and install

The extension supports VS Code 1.100 and newer. Its @types/vscode dependency is pinned exactly to 1.100.0 so typechecking uses the minimum supported editor's API. A caret range can resolve newer declarations while leaving the declared minimum unchanged; VSIX packaging alone does not detect that drift. Raise the type pin and engines.vscode together when deliberately adopting a newer API, and exercise the extension in the corresponding editor host.

pnpm install
pnpm package          # → cave-language-<version>.vsix
code --install-extension cave-language-*.vsix

For development, open editors/vscode itself as the VS Code workspace folder after installing the workspace dependencies. Select Run CAVE extension in Run and Debug and press F5. The checked-in launch configuration runs pnpm build from that folder before starting an Extension Development Host, with source maps from dist/ available to the debugger. Open a .cave file in the new window to activate the provider. Stop and restart debugging after source changes to rebuild; this launch task is not a watch process. VS Code's extension debugging guide describes the development-host workflow.

pnpm test typechecks and builds the extension, then checks its resource lifecycle and packaged grammar. A provider integration test uses the real WASM runtime with a small VS Code host double to verify single-line, non-overlapping UTF-16 token ranges for Unicode, CRLF input and incomplete edits. It does not replace an interactive extension-host check of theme rendering.

An installed VS Code can also run the real host smoke test from this directory:

pnpm build
test_profile="$(mktemp -d /tmp/cave-vscode.XXXXXX)"
trap 'rm -rf "$test_profile"' EXIT
CAVE_VSCODE_HOST_RESULT="$test_profile/result.json" code --user-data-dir "$test_profile/profile" \
  --extensions-dir "$test_profile/extensions" \
  --extensionDevelopmentPath "$PWD" \
  --extensionTestsPath "$PWD/test-host/index.cjs" \
  --disable-workspace-trust --skip-welcome --skip-release-notes
node -e 'const fs = require("node:fs"); const assert = require("node:assert/strict"); assert.equal(JSON.parse(fs.readFileSync(process.argv[1], "utf8")).active, true)' "$test_profile/result.json"

The test opens a temporary .cave file containing Unicode and CRLF lines, checks automatic language detection, two-space indentation and spaces, waits up to ten seconds for automatic activation, and requests the legend and tokens through VS Code's semantic-token commands. It checks non-overlapping UTF-16 token ranges, keywords, Unicode strings, and the trajectory operator. It then replaces the document with an unfinished string and corrects it, checking version changes, fresh tokens, and an astral-character identifier before the test host exits. Set CAVE_VSCODE_HOST_RESULT to a file path to retain the initial and edited tokens and host version as JSON. The temporary profile keeps normal editor settings and installed extensions separate. This requires a graphical VS Code installation; it supplements the ordinary Node tests and does not verify theme colors. The test passed locally with VS Code 1.126.0-insider on macOS arm64. The success JSON is written only after all assertions pass. Check it from a fresh profile as shown above: the local code launcher can return zero even when the test host reports an assertion failure. Keep the profile path short: on macOS, a long temporary directory can exceed the IPC socket path limit and fail with listen EINVAL before the extension loads. The command above uses a short /tmp path for that reason. If the macOS shell launcher exits without a result file or usable diagnostics, invoke the application executable directly with the same arguments and CAVE_VSCODE_HOST_RESULT, for example "/Applications/Visual Studio Code - Insiders.app/Contents/MacOS/Code - Insiders". Unset ELECTRON_RUN_AS_NODE for this direct application launch. Check the success JSON again; a zero exit code alone still does not prove the test passed.

For an artifact check, run pnpm package, extract the generated VSIX, and point --extensionDevelopmentPath at its extracted extension directory. Keep --extensionTestsPath pointing at this repository's test module. The host test also passed against the extracted artifact, verifying its file association, automatic activation, defaults and semantic-token behavior.

A separate visual review in that host checked Default Dark Modern and Default Light Modern with comments, Unicode strings, contexts, trajectory numbers/operators/units, confidence, and tags. Both rendered legibly with distinct token colors and no clipped text. This is evidence for those built-in themes; custom themes retain control over their semantic-token colors.

pnpm package builds the extension and validates the resulting VSIX archive: extension identity and version, the expected executable entry point, and required manifest/readme/license/configuration, bundle, WASM, and highlight-query files. Every required file must be nonempty, including the executable JavaScript bundle. The package manifest and language configuration must decode as strict UTF-8 and parse as JSON objects; malformed bytes, invalid JSON, and non-object roots fail with the archive path in the error. This checks their encoding and structure, not the complete VS Code configuration schema. Both bundled WASM payloads must pass WebAssembly validation, so malformed or truncated binaries cannot pass merely by occupying a nonempty archive entry. This checks binary validity; the provider and extension-host tests exercise grammar loading and editor behavior separately. The highlight query must decode as strict UTF-8; malformed bytes cannot silently become replacement characters when the extension loads it. Authored Unicode, including a literal replacement character, remains valid. This encoding check does not compile the query or establish grammar compatibility. Duplicate archive paths are rejected, so entry order cannot select a different manifest or executable. Archive read failures close the reader before rejection. It rejects packaged node_modules, src, test, test-host, and .vscode directories, independently of the packaging allowlist. This archive check complements the provider tests; it does not launch VS Code or publish to Marketplace.

Version and release policy

The extension is a released Marketplace product under publisher MirekRusin. Its version follows the repository's lockstep CAVE version: the automated version-packages PR updates this private manifest after Changesets has updated the public packages. Never edit the version by hand. Every repository release publishes the extension to Marketplace (listed as CAVE Language, id MirekRusin.cave-language) from the vscode job of .github/workflows/publish.yml, which runs after the npm publish.

Extension-facing changes use the same PR changeset as the rest of the repository. Those changesets and the linked v<version> Git history are the release log; there is deliberately no second extension changelog to maintain or reconcile.

Both publication paths use the vscode-marketplace GitHub environment, which holds a VSCE_PAT secret authorized only for the MirekRusin publisher plus any desired reviewer protection. To republish an older release manually, dispatch Publish VS Code extension (.github/workflows/vscode.yml) from the default branch and enter the version without the v. Either path checks out the exact tagged release, validates its release identity and lockstep manifest, builds and inspects the VSIX, then publishes it. Duplicate versions are treated as a successful no-op so a failed workflow can be rerun.

The VSCE_PAT is an Azure DevOps personal access token created at https://dev.azure.com/<org>/_usersSettings/tokens with organization scope All accessible organizations and the single scope Marketplace → Manage. Azure DevOps retires all-organization tokens on 1 December 2026; set the expiry no later than that date and migrate the workflow to the Entra-based authentication vsce supports (--azure-credential) before then.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft