Skip to main content

CLI

Snippety ships with a snippety command that lets you create, search, and expand snippets straight from the terminal.

The CLI doesn't touch the database on its own - it talks to the running Snippety app. Everything you do stays in sync with the app window and iCloud, exactly as if you did it by hand.

info

The CLI requires Snippety Pro and a running Snippety app.

Installation

Open App Settings -> Integrations -> CLI and click Install.

Installing only creates a symlink at /usr/local/bin/snippety pointing to the binary bundled inside the app. Updating Snippety therefore updates the CLI as well, and uninstalling is just removing the symlink.

Because /usr/local/bin is owned by root, the two builds ask for permission in different ways:

  • Standalone: macOS asks for your administrator password.
  • App Store: the app is sandboxed and cannot ask for elevated privileges, so you need to add the symlink manually. See Manual Installation below.

The Status section shows whether the CLI server inside the app is running.

warning

If a different snippety binary is already on your PATH (for example one installed with Homebrew), Snippety will not overwrite it. Remove it first, or install the symlink manually.

Manual Installation

sudo mkdir -p /usr/local/bin && sudo ln -sf "/Applications/Snippety.app/Contents/Tools/snippety" /usr/local/bin/snippety

Auto-Completion

Snippety bundles completion scripts for commands, subcommands, and parameters. In App Settings -> Integrations -> CLI click Copy Completion Command and add the copied line to your shell profile (~/.zshrc):

source "/Applications/Snippety.app/Contents/Resources/completions/snippety.zsh"

The script is shipped inside the bundle, so sourcing it doesn't launch the CLI on every new shell.

Basics

snippety --help # every command
snippety <command> --help # options of a single command
snippety status # is the app reachable?

Selecting a Snippet

Most commands take a snippet selector: a name, a keyword, an id, or a snippety:// deeplink. The form is inferred from what you type:

snippety get "Email signature"
snippety get sig
snippety get snippety://snippet?id=SNIPPET_ID

If the guess is wrong, force the interpretation:

OptionMatches
--id <id>Snippet id
--match-name <name>Exact name
--match-keyword <keyword>Expansion keyword
--match-deeplink <url>snippety:// deeplink
--lastMost recently expanded snippet
--most-usedMost frequently expanded one

Ids can be abbreviated to the short form printed by snippety list, the same way git accepts short commit hashes. Add more characters if more than one snippet matches:

snippety get 113A25BB

Global Options

Every command accepts:

OptionDescription
--jsonPrint raw JSON instead of formatted output.
--no-colorNever colorize output. The NO_COLOR environment variable works too.
--timeout <seconds>How long to wait for Snippety. Defaults to 30s, or 600s for backups and fill forms.

Exit Codes

CodeMeaning
0Success
1Error
3Snippety is not running
4Snippety Pro required
5Snippet not found
6Timeout
7Fill form dismissed
64Usage error

Commands

Snippets

CommandDescription
expandPrint a snippet with its placeholders resolved.
listList snippets matching provided criteria.
getPrint snippet details.
addCreate a snippet.
editEdit an existing snippet.
deleteDelete one or more snippets.

Grouping

CommandDescription
collection listList collections and how many snippets each holds.
collection renameRename a collection, moving every snippet in it.
collection deleteDelete a collection and every snippet inside it.
tag listList tags and how many snippets carry each.
tag addCreate a tag with no snippets attached.
tag renameRename a tag everywhere it's used.
tag deleteDelete a tag and strip it from every snippet.
tag assignAttach tags to snippets.
tag unassignDetach tags from snippets.

App

CommandDescription
app-showReveal a snippet in the Snippety window.
app-show-collectionReveal a collection in the Snippety window.
app-editOpen a snippet in Snippety's editor.
app-newOpen Snippety's new-snippet editor.

Backup

CommandDescription
exportExport every snippet and setting to a file.
importImport snippets from a file produced by export.

Other

CommandDescription
statusCheck the connection to Snippety.
statsShow usage statistics.
formatsList the syntax formats accepted by --format.
configRead and change Snippety settings.

Expanding Snippets

snippety expand writes the resolved text to stdout with no trailing newline of its own, so it composes with other tools:

snippety expand sig | pbcopy
git commit -m "$(snippety expand --match-keyword fixmsg)"

Passing Values

Snippets that ask for input take values with --var, applied in the order the placeholders appear in the template - the same order the app's search bar fills them:

snippety expand invite --var "Alice" --var "Monday 10am"

The search bar's inline form works too, but < is a shell redirect, so the whole argument has to be quoted:

snippety expand "invite < Alice < Monday 10am"

Placeholders you leave uncovered fall back to their defaults.

Fill Form

Pass --show-form to be asked for the missing values instead. Snippety opens its normal fill form, pre-filled with whatever you supplied, and the resolved text is printed once you confirm:

snippety expand invite --show-form
snippety expand invite --var "Alice" --show-form | pbcopy

Dismissing the form exits with code 7 and prints nothing.

Expanding In The Front App

With --in-app the text never comes back to the terminal. Snippety expands the snippet the way it does from its own search bar - pasting into whatever app is in front (or copying, depending on your expansion mode) and asking for any values you left out. The command returns immediately:

snippety expand sig --in-app
snippety expand invite --var "Alice" --in-app
tip

Placeholders that run scripts or call AI can take a while. Raise --timeout if you hit it.

This is the mode you want when a snippet is triggered by a global hotkey - see Global Hotkeys with skhd.

Listing & Searching

Without a query every snippet is listed. With one, it goes through the same search engine as the app.

snippety list
snippety list "reply email" --scope name --collection Work --json
snippety list --tag email --tag urgent
snippety list --expand
OptionDescription
-s, --scope <scope>Where to look: name, keyword, content, everywhere (default).
-c, --collection <name>Only snippets in this collection. Repeatable.
-t, --tag <name>Only snippets carrying this tag. Repeatable.
-e, --expandResolve placeholders that need no input.

Filters combine with OR.

Creating & Editing

The template can be given inline, read from a file, or piped in:

snippety add "License header" --template-file LICENSE.txt
pbpaste | snippety add "Clipboard grab"
snippety add "Signature" --keyword sig --tag email --template "Best,\nWojciech"

snippety edit touches only the fields you pass. Because an omitted option means "leave alone", clearing a value needs an explicit flag:

snippety edit "Signature" --keyword sig
snippety edit --id 4F2C1A0B --template-file new.txt
snippety edit "Old note" --clear-tags --name "Archived note"

Available flags: --name, --template, --template-file, --keyword, --description, --format, --collection, --tag, --quick-access / --no-quick-access, --clear-collection, --clear-tags.

Deleting resolves every target first, so a typo in one name aborts the whole command instead of leaving it half-applied:

snippety delete "Old note"
snippety delete --id 4F2C1A0B --id 91BA33DE --yes

Collections & Tags

Collections have no records of their own - one exists as long as a snippet names it. That's why there is no create: assign a collection when adding or editing a snippet.

snippety collection list
snippety collection rename Work "Work Notes"
snippety collection delete Archive

For tags, add, rename, and delete act on the tag itself, while assign and unassign change which snippets carry it:

snippety tag list
snippety tag assign email urgent --snippet "Signature" --snippet "Follow-up"
snippety tag unassign urgent --snippet "Signature"
warning

snippety collection delete also deletes every snippet inside the collection. Deleting a tag only strips it from your snippets.

Export & Import

snippety export writes the same JSON as the app's Export button, so the two files are interchangeable.

snippety export ~/Backups/snippety.json
snippety export > snippety.json
snippety export --no-settings snippets-only.json

Importing replaces the database by default, exactly like the app's Import button. Use --mode append to add to what's already there:

snippety import snippety.json
snippety import snippety.json --settings
snippety import team-snippets.json --mode append --collection Team
cat snippety.json | snippety import --yes

Settings are left alone unless --settings is passed, so restoring snippets on a machine you already configured doesn't undo that configuration. See also Import app settings.

Replacing asks for confirmation first. Piping the dump in takes stdin away from the prompt, so that form needs --yes.

info

Snippety reads and writes these files itself, because a database of formatted snippets can run to hundreds of megabytes - more than the CLI connection carries. On the App Store build the app is sandboxed, so a path outside its container will be refused. Redirect stdout or pipe the dump in instead.

Settings

snippety config get lists every exposed setting with its current value. Booleans take true or false.

snippety config get
snippety config set expansion-mode copyToClipboard
snippety config set prefix ":"
snippety config set suffixes "space return . ,"
KeyDescription
expansion-modeWhat happens after expanding: pasteToApplication, copyToClipboard, pasteAndCopy.
expand-with-prefixRequire a prefix character before the keyword.
prefixThe prefix character, or 2x space.
expand-with-suffixExpand only once a suffix character is typed.
suffixesWhich suffixes trigger it, space-separated: . , ! space return tab nbsp.
keep-suffixLeave the typed suffix in place after expanding.
require-double-suffixNeed the suffix twice, so ordinary punctuation doesn't expand.
expand-within-wordsExpand even when the keyword is glued to other characters.
expand-selectedExpand only snippets in the collection and tags selected in the app.

See Snippet Expander for what these options do.

Global Hotkeys with skhd

Snippety gives its own hotkeys to the search bar and the Quick Access Menu, but not to individual snippets. With the CLI you can bind any snippet to any key combination yourself, using skhd - a tiny hotkey daemon for macOS.

brew install koekeishiya/formulae/skhd
skhd --start-service

macOS will ask for Accessibility permission the first time the service starts. Hotkeys are declared in ~/.config/skhd/skhdrc, one per line, as modifiers - key : command:

# Paste the signature into whatever app is in front
cmd + alt - s : /usr/local/bin/snippety expand sig --in-app

# Placeholders you don't pass are asked for in Snippety's fill form
cmd + alt - i : /usr/local/bin/snippety expand invite --in-app

# Put an expanded snippet on the clipboard instead
cmd + alt - c : /usr/local/bin/snippety expand sig | pbcopy

Reload the config after editing it:

skhd --restart-service
warning

Always use the full path /usr/local/bin/snippety. skhd runs commands from a non-interactive shell that doesn't load your ~/.zshrc, so a bare snippety may not be found.

--in-app is what makes this useful: the text goes to the front app exactly as if you expanded the snippet from Snippety's search bar, and any values you left out are asked for in the fill form. Without it the output would be printed to a terminal that isn't there.

A Leader Key for Snippets

Binding one combination per snippet runs out of free keys quickly. skhd modes let you press a leader key first and then a single letter, the way tmux and Vim leader mappings work:

:: default
:: snippets @

# Enter the snippet layer
cmd + alt - space ; snippets

# Inside the layer, one letter per snippet
snippets < s : /usr/local/bin/snippety expand sig --in-app; skhd -k 'escape'
snippets < i : /usr/local/bin/snippety expand invite --in-app; skhd -k 'escape'
snippets < m : /usr/local/bin/snippety expand meeting --in-app; skhd -k 'escape'

# Leave the layer
snippets < escape ; default

The @ marks the mode as capturing, so keys that aren't mapped do nothing instead of reaching the app underneath. Each action ends with skhd -k 'escape', which triggers the last line and drops you back to default.

tip

snippety list --json prints every snippet with its keyword, which makes it easy to see what is worth a hotkey - and snippety stats shows what you expand most often.

Troubleshooting

  • Snippety is not running (exit code 3): start the app. The CLI needs it.
  • Snippety Pro required (exit code 4): the CLI is a Pro feature. Run snippety status to confirm the license state.
  • Command not found: the symlink was not installed, or /usr/local/bin is not on your PATH. Reinstall from App Settings -> Integrations -> CLI or use the manual command above.
  • A different snippety is on the PATH: remove the other binary, then install again.
  • An skhd hotkey does nothing: run the same line in a terminal first. If it works there but not from skhd, use the absolute path to the binary and check that skhd has Accessibility permission.