Editor support and syntax highlighting¶
.qvr files are highlighted by two complementary systems, depending on what reads the file:
| Consumer | Engine | Comes from |
|---|---|---|
Python tools: mkdocs, Sphinx, Jupyter, IPython, pygmentize |
Pygments | bundled with the quivers PyPI package |
| Editors: Neovim, Helix, Emacs, Zed | tree-sitter | the grammar and editor assets shipped by quivers |
| VS Code and Cursor | TextMate for initial colorization; QVR LSP for semantic tokens | the first-party vscode-qvr extension |
| GitHub.com source view, GitHub gists | Linguist | language registration (not yet upstream) |
This page documents how to wire each one up.
Pygments (Python doc and notebook tools)¶
Quivers ships a Pygments lexer registered as an entry point. After
every Pygments-based tool finds .qvr files automatically. No further configuration is needed for mkdocs, Sphinx, pygmentize, IPython / Jupyter cell magic (%%highlight qvr), or any other consumer that asks Pygments to choose a lexer by filename or by name="qvr".
To confirm the lexer is visible:
python -c "from pygments.lexers import get_lexer_by_name; print(get_lexer_by_name('qvr').name)"
# QVR
To highlight a file to a terminal:
The lexer source lives at src/quivers/dsl/pygments_lexer.py; the highlight rules and keyword list are kept in sync with the tree-sitter grammar by tests/test_dsl_extensions.py.
Tree-sitter (editors)¶
The authoritative tree-sitter grammar lives at
grammars/qvr/
in the quivers repository. The Python package includes its generated source;
platform wheels pair that source with a manifest-verified native parser. The
Pygments lexer, CLI, REPL, and language server load this pair directly and fail
closed if either component is absent or inconsistent. Editable checkouts may
compile a content-addressed development parser after grammar changes.
panproto-grammars-all remains a dependency for the eleven transpiler-target
grammars, but it does not define QVR syntax.
Editor integrations use the first-party extensions below or clone the quivers
repository and build against grammars/qvr/. The grammar follows standard
tree-sitter conventions; if an editor has a :TSInstall qvr or equivalent
command and the grammar is not on its upstream list yet, the manual paths below
also work.
Neovim¶
With nvim-treesitter:
-- init.lua (or any config file loaded after nvim-treesitter)
local parsers = require("nvim-treesitter.parsers").get_parser_configs()
parsers.qvr = {
install_info = {
url = "https://github.com/quivers-dev/quivers",
files = { "grammars/qvr/src/parser.c" },
location = "grammars/qvr",
branch = "main",
generate_requires_npm = false,
requires_generate_from_grammar = false,
},
filetype = "qvr",
}
vim.filetype.add({ extension = { qvr = "qvr" } })
Then :TSInstall qvr from inside Neovim. The repository ships queries/highlights.scm at grammars/qvr/queries/highlights.scm; nvim-treesitter picks it up automatically once the parser is registered.
Helix¶
Helix has native tree-sitter support. Add to ~/.config/helix/languages.toml:
[[language]]
name = "qvr"
scope = "source.qvr"
file-types = ["qvr"]
roots = []
comment-token = "#"
indent = { tab-width = 4, unit = " " }
[[grammar]]
name = "qvr"
source = { git = "https://github.com/quivers-dev/quivers", subpath = "grammars/qvr" }
Then:
Place the highlight queries at ~/.config/helix/runtime/queries/qvr/highlights.scm; copy the file from grammars/qvr/queries/highlights.scm in this repository, or symlink to a checkout.
Emacs (tree-sitter-langs)¶
With tree-sitter-langs and built-in treesit (Emacs 29+):
(add-to-list 'treesit-language-source-alist
'(qvr . ("https://github.com/quivers-dev/quivers"
"main" ; branch
"grammars/qvr/src")))
(define-derived-mode qvr-mode prog-mode "QVR"
"Major mode for editing .qvr files."
(when (treesit-ready-p 'qvr)
(treesit-parser-create 'qvr)
(setq-local treesit-font-lock-settings
(treesit-font-lock-rules
:language 'qvr
:feature 'comment
'((comment) @font-lock-comment-face)
:language 'qvr
:feature 'keyword
'(["morphism" "object" "program"
"composition" "category" "contraction" "bundle"
"deduction" "atoms" "start" "depth"
"lexicon" "let" "in" "sample" "observe"
"marginalize" "return" "factor" "score"
"index" "family" "constructor" "effect"
"instance" "handler" "perform" "handle"
"case" "motive" "resumes" "construct"
"for" "with" "lacks"
"coverage"
"forwards" "introduces" "unknown" "none"
"total" "partial"
"aff" "omega" "true" "false" "unit"
"export" "as" "over"
"algebra" "semigroupoid" "bilinear_form"
"rule"]
@font-lock-keyword-face)))
(treesit-major-mode-setup)))
(add-to-list 'auto-mode-alist '("\\.qvr\\'" . qvr-mode))
Run M-x treesit-install-language-grammar RET qvr RET once after Emacs starts to fetch the parser.
Zed¶
The quivers repository ships a Zed extension at
editors/zed-extension-qvr/.
Until the extension is published to Zed's public registry, install it
locally from a checkout:
git clone https://github.com/quivers-dev/quivers
mkdir -p ~/.config/zed/extensions
ln -s "$(pwd)/quivers/editors/zed-extension-qvr" ~/.config/zed/extensions/qvr
Reload extensions (zed: reload extensions from the command palette).
The extension's manifest pins the grammar against grammars/qvr/ in the
same repository, so a single checkout drives both the grammar source
and the editor packaging.
VS Code / Cursor¶
The repository ships a first-party VS Code extension at
editors/vscode-qvr/.
It provides:
- a TextMate grammar for the initial render,
- a
vscode-languageclientbridge toqvr-lspfor hover, go-to-definition, semantic tokens, document symbols, completion, formatting, and live diagnostics.
Install the packaged extension into VS Code (or Cursor):
cd editors/vscode-qvr
npm install
npx tsc -p .
npx @vscode/vsce package --allow-missing-repository --no-yarn
code --install-extension vscode-qvr-*.vsix
# or: cursor --install-extension vscode-qvr-*.vsix
The extension auto-discovers qvr-lsp in (1) the qvr.lsp.path
setting (with ${workspaceFolder} expansion), (2)
<workspace>/.venv/bin/qvr-lsp, (3) $VIRTUAL_ENV/bin/qvr-lsp, or
(4) plain qvr-lsp on $PATH. Install the LSP extra with
pip install 'quivers[lsp]'.
The full configuration options and launch resolution order are documented in the Interactive guide.
GitHub source view (Linguist)¶
GitHub's syntax highlighting on .qvr files in repository source view and gists is driven by github-linguist. QVR is not yet upstream; until the language is registered, repositories can override locally with a .gitattributes entry pointing at the closest existing language for at least some color:
This repository uses R as the temporary stand-in, which highlights common
declaration names, calls, numbers, strings, and comments. It is not a QVR
grammar: effect rows, categorial slashes, the ~ Family clause, and axis roles
remain approximate until Linguist has a native QVR entry.
Native GitHub highlighting requires a QVR language entry in github-linguist. Panproto's separate refresh of its vendored QVR grammar is tracked in panproto/panproto#321; that vendor update does not register QVR with GitHub Linguist.
Verifying your setup¶
A baseline probabilistic-program check is:
object Item : FinSet 32
program regression : Item -> Item [effects=[Sample, Score]]
sample sigma <- HalfNormal(scale=1.0)
sample beta <- Normal(loc=0.0, scale=2.0)
let mu = beta * x
observe y : Item <- Normal(loc=mu, scale=sigma)
return y
export regression
When the highlighting is wired up, keywords (object, program,
sample, let, observe, return, export), the effects option,
the <- bind punctuation, family identifiers (HalfNormal, Normal),
and comments carry distinct colors.
Use this second block to verify the indexed-effect tokens:
index Availability = Observed | Missing
family Measurement(s : Availability) : Type
constructor Present : Real -> Measurement(Observed)
constructor Absent : Measurement(Missing)
effect Robust
shrink : Real -> Real
instance robust : Robust
handler half_weight for Robust : Real -> Real [coverage=total, forwards=none, implementation=authored]
return x =>
return x
shrink(x : Real) resumes 1 =>
resume(0.5 * x)
define robustify(x : Real) : Real !{} =
handle robust with half_weight in
let adjusted <- perform robust.shrink(x)
return adjusted
The additional keywords (index, family, constructor, effect,
instance, handler, resumes, define, handle, perform) and handler
option keys should receive their semantic classes once the LSP attaches. The
QVR language reference contains tested blocks for
the remaining computation and program forms.
If a token is unhighlighted (rendered as default-foreground text), the corresponding rule in the editor's highlight query is the place to look; the canonical reference is grammars/qvr/queries/highlights.scm.