Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Go template rainbowNew to Visual Studio Code? Get it now.
Go template rainbow

Go template rainbow

miller.garym

|
2 installs
| (0) | Free
Depth-based rainbow colouring of Go template control keywords, driven by the tree-sitter grammar and queries/rainbow.scm.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

gotmpl-rainbow

A VSCode extension for Go templates, driven by the tree-sitter grammar. It does three things every time a gotmpl document changes:

  1. Syntax highlighting — runs ../queries/highlights.scm and exposes the captures as VSCode semantic tokens (comments, strings, keywords, functions, fields, numbers, …). The active colour theme paints them; there is no hard-coded palette.
  2. Rainbow keywords — runs ../queries/rainbow.scm and paints each control keyword (define/range/if/with/block/else/ end) with a colour chosen by its block nesting depth, reproducing the Neovim rainbow-delimiters.nvim behaviour.
  3. Code folding — folds each control block at the same keyword markers, so {{if}}…{{else}}…{{end}} folds into per-branch regions.

Go template rainbow highlighting a gotmpl file in VSCode

VSCode has no built-in consumer for these .scm queries; this extension is the bridge. See ../docs/vscode.md for the full write-up.

Files

File Role
extension.js VSCode glue: activation, parsing, semantic tokens, decorations, config/reload.
rainbow-core.js Pure depth/bucketing logic for the rainbow layer — no vscode dependency.
highlight-core.js Pure highlights.scm capture → semantic-token mapping — no vscode dependency.
folding-core.js Pure control-block → fold-range logic — no vscode dependency.
resolve-assets.js Locates the parser/queries: config override → bundled dist/ → sibling grammar repo.
verify.js Headless check of both core layers (no VSCode needed).
build.js Copies the parser + rainbow.scm + highlights.scm into dist/ for packaging.
Makefile make package / make publish — see PUBLISHING.md.

Run in development mode

# 1. Build the WASM parser in the grammar directory (one level up):
cd .. && tree-sitter generate --abi 15 && tree-sitter build --wasm . && cd -

# 2. Install web-tree-sitter:
npm install

# 3. Sanity-check the logic without launching VSCode:
node verify.js            # prints each keyword's depth + colour bucket

# 4. Launch the Extension Development Host:
#    open this folder in VSCode and press F5 (uses .vscode/launch.json,
#    which also opens ../examples/sample.tmpl for you).

When run from source the parser and query resolve to ../tree-sitter-gotmpl.wasm and ../queries/rainbow.scm; a packaged build uses the copies bundled into dist/. Override either with the gotmplRainbow.parserPath / gotmplRainbow.rainbowQueryPath settings.

Build & publish

make package   # bundle assets into dist/ and produce gotmpl-rainbow-<version>.vsix
make publish   # bundle + publish to the VSCode Marketplace
make verify    # headless depth/colour check

Both package and publish re-bundle the parser and query first. Full marketplace setup (publisher, PAT, vsce login) is in PUBLISHING.md; installing a built .vsix without the Marketplace is covered in SIDELOADING.md.

Settings

Setting Default Meaning
gotmplRainbow.parserPath (bundled) Absolute path to override the WASM parser.
gotmplRainbow.rainbowQueryPath (bundled) Absolute path to override the rainbow query.
gotmplRainbow.highlightsQueryPath (bundled) Absolute path to override the highlights query.
gotmplRainbow.semanticHighlighting true Provide highlights.scm syntax highlighting (semantic tokens). Off = rainbow keywords only.
gotmplRainbow.colors 7-colour palette Rainbow palette for dark themes (and the light fallback); depth wraps around.
gotmplRainbow.colorsLight 7-colour palette Rainbow palette for light themes (darker, so e.g. yellow stays readable). Empty = reuse colors.
gotmplRainbow.bold true Render coloured keywords in bold.
gotmplRainbow.border true Draw a rounded per-depth outline around each keyword.
gotmplRainbow.background true Fill each keyword with a faint per-depth background tint.
gotmplRainbow.folding true Fold control blocks at the rainbow keyword markers.

Each rainbow decoration carries both a light and a dark colour (text, border and background tint), so VSCode picks the readable one for the active theme automatically — switching themes needs no reload.

Syntax-highlighting colours come from your active theme's semantic token rules, not from a setting here. The extension also turns on editor.semanticHighlighting.enabled for gotmpl files by default (via configurationDefaults), so the tokens render even under a theme that otherwise leaves semantic highlighting off; if a file still looks flat, the theme simply doesn't style these semantic token types.

Command Go template rainbow: Reload parser and query re-reads the WASM and .scm files without restarting the host — handy while editing rainbow.scm.

What's verified

node verify.js exercises everything except the VSCode rendering APIs: it loads the real WASM parser, runs rainbow.scm (printing the depth/colour each keyword receives) and highlights.scm (printing the semantic token each node resolves to). The vscode-specific glue in extension.js — decorations and the semantic-tokens provider — is exercised by launching the Extension Development Host (step 4).

Launch from the command line

The code CLI equivalent of the .vscode/launch.json config is --extensionDevelopmentPath:

code --extensionDevelopmentPath=`pwd` --disable-extensions `pwd`/../examples
  • --extensionDevelopmentPath=… loads the extension from source (same as the launch config).
  • --disable-extensions disables other installed extensions (this one still loads), so nothing else touches .tmpl files during testing.
  • The trailing path opens the sample file.

After editing extension.js / highlight-core.js, run Developer: Reload Window in the host to pick up the changes. Changes to package.json (e.g. the configurationDefaults) need the host relaunched, not just reloaded.

Highlighting

The syntax-highlighting layer maps each highlights.scm capture to a VSCode semantic token type, which the active colour theme paints:

Capture Semantic token
@comment comment
@keyword, @keyword.conditional, @keyword.repeat, @boolean, @constant.builtin keyword
@string, @string.special, @character string
@number number
@operator operator
@property property
@variable variable
@variable.builtin variable + defaultLibrary
@function.call, @function.builtin function (defaultLibrary on builtins)

Captures with no entry (e.g. @punctuation.*, @spell) are left to the editor default. When several patterns capture the same node, the first pattern in highlights.scm wins — the tree-sitter convention, which is why catch-alls such as (identifier) @variable sit at the bottom of the file.

Highlights aren't showing?

The resolution logic is verified independently (node verify.js prints the tokens), so missing colour is a rendering problem, not a parsing one. Two usual causes:

  1. Semantic highlighting is off. VSCode only requests semantic tokens when editor.semanticHighlighting.enabled is truthy; its global default is "configuredByTheme", and some themes disable it. This extension sets a per-language default of true for gotmpl, but that only takes effect once the host is relaunched (not merely reloaded).
  2. The theme doesn't colour these token types. Some themes have no semantic rules for variable/property, so those stay default-coloured — but comment, string, keyword, function, and number visibly change under a default theme (Dark+ / Default Dark Modern).

Diagnostic: open a template, place the cursor on a string or comment, and run Developer: Inspect Editor Tokens and Scopes from the Command Palette.

  • A semantic token type line appears → the provider is firing; the issue is theme colours. Switch to Default Dark Modern to confirm, or force colours:

    "editor.semanticTokenColorCustomizations": {
      "enabled": true,
      "rules": { "comment": "#6a9955", "string": "#ce9178", "keyword": "#c586c0", "function": "#dcdcaa", "number": "#b5cea8" }
    }
    
  • No semantic token line → the provider isn't being asked. Confirm the panel header doesn't say "semantic highlighting: disabled", set "editor.semanticHighlighting.enabled": true, and relaunch the host so the configurationDefaults load. Check Help → Toggle Developer Tools → Console for any error thrown from provideDocumentSemanticTokens.

Folding

A FoldingRangeProvider folds control blocks using the same keyword markers the rainbow layer colours (if/else/end/range/with/block/define). A fold is created for each segment between consecutive markers of a block, so:

  • {{define}}…{{end}} folds to a single region.
  • {{range}}…{{else}}…{{end}} folds into two regions (the loop body and the empty-case body).
  • {{if}}…{{else if}}…{{else}}…{{end}} folds into one region per branch.

Every {{else}} / {{else if}} and the closing {{end}} stay visible when a region is collapsed. Nested blocks fold independently — only a block's own keywords bound its folds. node verify.js prints the computed ranges, and the logic lives in the vscode-free folding-core.js.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft