Skip to content

Repository files navigation

Inline Typst

VSCode extension that renders Typst math inside scoped editor regions (comments by default).

mode: edit (source):

Typst math written as $...$ segments inside a Rocq comment

mode: view (rendered):

The same comment with every formula rendered as an inline preview

Decoration patterns adapted from comment-formula (MIT). The bundled Typst TextMate grammars are vendored from tinymist (Apache-2.0); see THIRD-PARTY-NOTICES.

Features

  • Scope-gated capture via @scope-search/core TextMate tokenization
  • Typst CLI rendering for inline $...$ and display $ ... $ math in comments
  • Previews render on a transparent background, so they always sit on the exact editor background; the ink uses the token color of the enclosing scope, following theme switches including OS-driven dark/light auto-detection
  • Preview size derives from editor.fontSize / editor.lineHeight configuration (per resource and language) and follows the editor font zoom, scaling with the surrounding text as the zoom level changes
  • Typst math syntax highlighting inside comment formulas, from a bundled grammar injected into every language's comments
  • Typst code completion inside formulas when a tinymist binary is available (see Completion below)
  • Rendered formula in a hover tooltip (inlineTypst.hover)
  • Global source/preview modes (inlineTypst.mode: edit, view, both) with Inline Typst: Toggle Preview Mode and per-mode commands
  • Keep the source visible alongside the preview (inlineTypst.hidden: none)
  • Indent multi-row previews to the source (inlineTypst.autotab) and reposition over-wide previews (inlineTypst.optimize.overflow)

Development

./scripts/setup-vendor.sh   # monorepo: link ../vscode-scope-search
npm ci
npm run build
npm test
npm run package
code --install-extension inline-typst-*.vsix

CI checks out vscode-scope-search into vendor/vscode-scope-search automatically.

Press F5 with .vscode/launch.json for extension host debugging.

Visual regression test

test/visual.test.js runs the real pipeline (typst compile, preview presentation) and compares rasterized previews against test/goldens/*.png pixel by pixel. The goldens are rendered with the typst version pinned in the CI workflows; after an intentional rendering change, regenerate them:

UPDATE_GOLDENS=1 npm test

On failure the actual images are written to test-out/*.actual.png (uploaded as a CI artifact).

Completion

Completion inside a formula is served by tinymist and needs a tinymist binary, resolved in order from inlineTypst.tinymistPath, the installed tinymist extension, then PATH. When none is found completion is disabled and a line is logged to the Inline Typst output channel; everything else keeps working.

Formulas live inside comments, and VS Code decides whether to open the suggestion list automatically from the token type at the cursor. A comment token is governed by editor.quickSuggestions.comments, which is off by default, so as-you-type completion would only appear on manual invoke (Ctrl+Space). To match the behaviour of a .typ file, the extension sets a default that turns comment quick-suggestions on for every language:

"editor.quickSuggestions": { "other": "on", "comments": "on", "strings": "off" }

VS Code shows this in Settings as "Default value set by extension." To turn it off, set editor.quickSuggestions yourself in settings.json (globally or per language, for example "[python]": { "editor.quickSuggestions": { "comments": "off" } }); your own value always wins. Completion still works on Ctrl+Space regardless, and the trigger characters \, #, and . open it as you type even with comment quick-suggestions off.

Settings

Key Default
inlineTypst.scopes ["comment"]
inlineTypst.typstPath "typst"
inlineTypst.tinymistPath "tinymist" (completion; auto-discovers)
inlineTypst.typst.preamble "" (path to Typst preamble file)
inlineTypst.languages ["rocq", "coq", "coqc", "agda"]
inlineTypst.mode "both" (edit / view / both)
inlineTypst.hidden "scope" (scope / none)
inlineTypst.hover "all" (all / partial / none)
inlineTypst.autotab false
inlineTypst.optimize.overflow false

Preamble

inlineTypst.typst.preamble names a Typst markup file (workspace-relative or absolute) that is spliced into every formula document, ahead of the formula. Splicing the markup rather than importing it is what lets the file carry #show rules, which an imported module cannot export.

The formula document is compiled under a project root set to the preamble file's own directory, so relative #import/#include paths inside the preamble resolve just as they do when Typst compiles the preamble in place. Paths reaching above that directory are outside the root and will not resolve; keep the preamble at or above everything it pulls in.

Nothing is written to disk for a preview: the document reaches Typst on stdin and the SVG comes back on stdout, so no stray files appear beside your sources.

Delimiters

Pattern Rendered as
$...$ Typst inline math
$ ... $ with inner edge spaces Typst display math

Releases

Used by

Contributors

Languages