Skip to content

Snippets plugin

Type a short prefix, press ++tab++, and it expands into a whole construct — a for loop, a class skeleton, a Markdown table — with the caret ready on the first blank you need to fill. Tab/Shift+Tab cycle the fields, Esc finishes. The plugin also provides File ▸ New from Template… for scaffolding whole files.

Expanding a snippet

  1. Type a snippet's prefix (say for in a C++ file).
  2. Press ++tab++. The prefix is replaced by the snippet body — as one undo step — and the first field is selected, ready to overtype.
  3. Press ++tab++ to jump to the next field, ++shift+tab++ to go back.
  4. After the last field, ++tab++ places the caret at the snippet's final position. ++esc++ ends the session at any point, leaving the text as typed.

If the word before the caret is not a snippet prefix, ++tab++ indents as usual — the key is only borrowed when there is something to expand. While the completion popup is open, ++tab++ belongs to the popup.

A multi-line expansion inherits the indentation of the line you typed it on, and its line endings follow the document's convention (CRLF/LF).

Snippets in the completion popup

Snippet prefixes also appear in the auto-completion popup, marked with a small glyph so they stand out from plain words. Accepting a snippet item expands it immediately and starts the field session — the same as typing the prefix and pressing ++tab++.

What a snippet can contain

Token Meaning
$1$9 Tab-stop fields, visited in numeric order (regardless of their position in the body).
${1:default} A field with initial content, selected when visited.
$0 Where the caret ends up after the last field (defaults to the end of the snippet).
$FILENAME The document's file name (empty for unsaved buffers).
$DATE Today's date, ISO format (2026-07-06).
$SELECTION The text selected when the snippet was triggered.
$CLIPBOARD The clipboard's current text.
\$ A literal dollar sign.

Anything malformed is inserted literally rather than failing. A field index repeated in the body keeps only its first occurrence as a live field.

Managing snippets

Preferences ▸ Snippets lists every snippet — the bundled sets and your own. From there you can:

  • Add… a new snippet: prefix, scope (comma-separated language ids such as cpp, c; empty or * applies everywhere), description, and the body.
  • Edit… your snippets. Editing a bundled snippet creates your own copy, which takes precedence over the bundled one (same prefix and scope).
  • Remove your snippets (bundled ones cannot be removed — shadow them instead).

Bundled sets ship for C/C++, Python, JavaScript/TypeScript and Markdown, plus two universal helpers (date, clip). Your snippets are stored as JSON in the plugin's data directory (snippets/user.json); you can also drop additional *.json files there — the format matches the bundled files:

{
    "language": ["cpp", "c"],
    "snippets": [
        {
            "prefix": "for",
            "description": "indexed for loop",
            "body": ["for (${1:int i = 0}; ${2:i < count}; ${3:++i})", "{", "\t$0", "}"]
        }
    ]
}

Bodies are arrays of lines. A per-snippet "scopes" array overrides the file-level "language" default.

File templates

File ▸ New from Template… opens a picker of file scaffolds — a C++ source with main, a header with an include guard, a Python script, a Markdown document, an HTML page. The chosen template opens as a new unsaved document with its variables ($DATE, $CLIPBOARD, …) already substituted; field tokens collapse to their default text.

Templates are JSON files too (templates/*.json, both bundled and in the plugin's data directory):

{
    "templates": [
        {
            "name": "Python script",
            "suggestedName": "script.py",
            "body": ["#!/usr/bin/env python3", "", ""]
        }
    ]
}

Limitations

  • A repeated field index is not mirrored (typing in field 1 does not update a second $1); later occurrences are plain text.
  • Nested placeholders (${1:${2:x}}) are not supported; the inner text is taken literally.
  • $FILENAME is empty in unsaved buffers.