Getting started

KeySnap lives in the notification area and watches for the abbreviations you define. When you type one, it deletes what you typed and puts your replacement in its place — in whatever program you happen to be typing in.

Your first shortcut

  1. Open KeySnap and click New shortcut.
  2. In Shortcut, type something you would never type by accident. A leading semicolon is a good habit: ;sig rather than sig.
  3. In Replacement, type what you want to appear.
  4. That is it. There is no save button — KeySnap writes changes to disk a couple of seconds after you stop typing.

Switch to any other program, type ;sig, and watch it happen. If it does not, jump to troubleshooting.

Choosing abbreviations. The best ones are short, memorable and impossible to type by accident. A prefix character does that work for you: ;, / and \ almost never begin a real word. Without one, a shortcut like addr will fire in the middle of "address" unless you leave the "stands alone as a word" option on.

How shortcuts fire

Every shortcut inherits a default from Settings → Matching, and can override it on its own Options tab.

ModeFiresGood for
As soon as I finish typing it The instant the last character of the abbreviation is typed Prefixed shortcuts like ;sig. The default.
After a space or punctuation When you type a space, full stop, comma, Enter or Tab afterwards Word-like shortcuts such as btw, where you want to be able to type btwn without it firing.
Only after a prefix character When the abbreviation is immediately preceded by one of your prefix characters Keeping shortcut names clean while still requiring a deliberate signal.

Standing alone

Only fire when the shortcut stands alone as a word is on by default. With it on, btw fires in "well btw" but not in "abcbtw". Turn it off for shortcuts you deliberately want to fire inside a word — expanding ing into something, for instance.

Keeping what you typed

By default KeySnap deletes the abbreviation before inserting the replacement. Turn Delete what I typed off and the replacement is appended instead, leaving the abbreviation in place. Useful when the abbreviation is itself part of the output.

Capitals

Under Settings → Matching → Capitals, choosing Follow what I type makes one shortcut do the work of three:

You typeYou getWhy
btwby the wayAs authored.
BtwBy the wayYou capitalised, so the replacement is capitalised.
BTWBY THE WAYYou shouted, so it shouts back.

An abbreviation you deliberately wrote in capitals — ABN, say — is exempt, so it never comes out shouting.

Token reference

Anything in braces is worked out when the shortcut fires. Write {{ and }} when you want literal braces. A token KeySnap does not recognise is left exactly as you typed it, so snippets full of JSON or code come out unharmed.

TokenWhat it doesExample
{date}Today's date{date}
{date:format}Date with a custom format{date:dd/MM/yyyy}
{date:+7d}Date shifted by an offset{date:+7d:dd MMM yyyy}
{time}Current time{time}
{time:HH:mm}Time with a custom format{time:HH:mm}
{datetime}Date and time together{datetime}
{day}Day name{day}
{month}Month name{month}
{year}Four-digit year{year}
{clipboard}Whatever is on the clipboard{clipboard}
{selection}The text you had selected{selection}
{cursor}Where the caret lands afterwardsDear {cursor},
{input:Label}Ask for a value before expanding{input:First name}
{input:Label|default}Ask, with a value pre-filled{input:Company|Acme}
{textarea:Label}Ask for a multi-line value{textarea:Notes}
{choice:Label|A,B,C}Ask, offering a drop-down{choice:Priority|Low,Normal,High}
{key:Name}Press a key{key:Enter}
{key:Ctrl+A}Press a combination{key:Ctrl+A}
{key:Tab*3}Press a key several times{key:Tab*3}
{delay:ms}Pause mid-expansion{delay:250}
{waitkey}Wait for you to press a key{waitkey}
{uuid}A fresh identifier{uuid}
{random:1-100}A random number in a range{random:1-6}
{counter:name}A number that increments each use{counter:invoice}
{math:expr}Work out a sum{math:19.99*1.1}
{upper:text}Force upper case{upper:{clipboard}}
{lower:text}Force lower case{lower:{clipboard}}
{titlecase:text}Force title case{titlecase:{input:Name}}
{trim:text}Strip surrounding whitespace{trim:{clipboard}}
{env:NAME}An environment variable{env:USERNAME}
{user}Your Windows user name{user}
{machine}This computer's name{machine}
{app}The app you are typing into{app}
{window}The active window's title{window}
{file:path}Insert a text file's contents{file:C:\notes\legal.txt}
{snippet:trigger}Insert another snippet{snippet:;sig}
{nl}A line break{nl}
{tab}A tab character{tab}
{{A literal opening brace{{

Date formats and offsets

Formats are standard .NET date formats: d, dd, ddd, dddd, M to MMMM, yy, yyyy, HH, mm, ss, tt.

Offsets come before the format and are separated from it with a colon. Units are d days, w weeks, mo months, y years, h hours, m minutes, s seconds, and you can chain them: {date:+1mo-1d:d MMMM yyyy} is a day short of a month from now.

Arithmetic

{math:...} understands + - * / % ^, brackets, and the functions abs, round, floor, ceil, sqrt, min, max and pow. It can read values from fill-in fields, which is what makes it useful: {math:round({input:Hours} * 145, 2)}.

It is arithmetic and nothing more. There is no scripting engine behind it, and a snippet cannot use it to run anything.

Fill-in fields

A shortcut containing {input:...}, {textarea:...} or {choice:...} asks you for those values before it types anything. The same field used twice is asked for once and inserted in both places.

Shortcut: ;booking
Hi {input:Name},

You are booked in for {choice:Service|Service,Repair,Quote}
on {date:+2d:dddd d MMMM} at {input:Time|9:00 am}.

{textarea:Anything else}

Thanks,
{user}

Press Enter to move between fields and Enter on the last one to insert. Esc cancels — and puts back exactly what you typed, so nothing is lost.

Keys and pauses

{key:...} presses keys rather than typing characters, which lets a shortcut drive a form. Names are the obvious ones: Enter, Tab, Esc, Home, End, Delete, Backspace, Arrow Left and friends, F1 to F12, and any letter or digit. Add modifiers with + and repeats with *.

Shortcut: ;newjob — fills three fields in a form
{input:Customer}{key:Tab}{input:Reference}{key:Tab}{delay:150}{input:Description}{key:Tab*2}{key:Enter}

{delay:250} waits a quarter of a second, which some slow web forms need between fields. {waitkey} stops until you press any key, so you can check something before the rest of the shortcut runs.

Scope rules

Each shortcut works everywhere by default. On the Scope tab you can restrict it to particular windows, or exclude particular windows.

Each rule can match on contains, is exactly, a wildcard using * and ?, or a regular expression. The Use the window in front button fills the pattern in from whatever you were last working in, which is easier than guessing an executable name.

The same abbreviation, twice. Scope is what makes that useful. Give ;addr your work address scoped to Outlook and your home address everywhere else, and the right one fires in each.

Groups and hotkeys

Groups are folders. Put a client's shortcuts in their own group and you can switch all of them off at once when the job ends, without deleting anything. Turning a group off turns off everything inside it, including nested groups.

Any shortcut can also have a global hotkey, on its Options tab. Click the box, press the combination, and it works system-wide. Shortcuts with a hotkey and no abbreviation are perfectly normal — sometimes a key combination is what you want.

Shortcuts → Check for conflicts lists abbreviations defined twice, hotkeys claimed twice, and shortcuts that another one hides by ending the same way.

Importing

From ShortKeys

ShortKeys stores its library in a closed binary .shk file that nothing else can read. In ShortKeys, choose File → Export → Text File and save as CSV. Then in KeySnap, File → Import → From a file. Shortkey, replacement, scope and notes all come across, and a scope of anything other than "Global" becomes a Only in these windows rule you can refine.

From AutoHotkey

Import the .ahk directly. KeySnap reads hotstrings — ::btw::by the way — including the *, ?, C and O option flags, backtick escapes, continuation blocks and {Enter}-style key syntax. AutoHotkey commands inside a replacement are not executed; they come across as literal text for you to review.

From espanso

Import the match .yml. Triggers, replacements, block scalars, propagate_case and word are all read. The script, shell and form extensions are not, and matches that used them keep their placeholders so you can see what needs rebuilding.

From a spreadsheet

Any CSV or tab-separated file with a header row. KeySnap recognises the usual column names — Shortkey, Trigger, Abbreviation, Replacement, Phrase, Notes, Category, Scope, Enabled — in any order. Without a recognisable header it reads column one as the shortcut and column two as the replacement, and tells you it has done so.

Exporting

File → Export writes JSON (lossless), CSV, TSV, AutoHotkey, a Markdown table for a team wiki, or a printable HTML page. Protected snippets are left out unless you explicitly confirm, because an export is a plain file with no encryption behind it.

Sync and backups

Under Settings → Files, point the library at a folder that already syncs — OneDrive, Dropbox, a mapped drive. KeySnap watches the file and reloads when another machine changes it, and holds off while you have unsaved edits so nothing is overwritten mid-sentence.

Every save takes a timestamped backup first, keeping the most recent fifteen by default. File → Restore from a backup lists them, and takes a backup of what you have now before replacing it.

Protected snippets do not sync usefully: they are encrypted for the Windows account that created them and will be unreadable elsewhere. KeySnap keeps the encrypted data intact rather than destroying it, so returning to the original machine restores access.

Security

KeySnap sees every keystroke, so it is worth knowing what it does with them. They are compared against your list in memory and discarded. Nothing is written to disk, nothing is transmitted, and KeySnap makes no network connections at all.

Protected snippets

Ticking Protect this snippet encrypts it on disk with Windows DPAPI, tied to your user account. In the list it shows as dots. In an export it is left out unless you confirm. It cannot be searched by its contents.

This protects a file that gets copied, backed up or synced. It cannot protect you from software already running as your user, which can read the keyboard directly regardless. Use a password manager for credentials; use KeySnap for the licence key you are sick of typing.

Where KeySnap holds back

Keyboard shortcuts

KeysDoesWhere
Ctrl+Shift+SpaceQuick-insert paletteAnywhere
Ctrl+Alt+KShow the KeySnap windowAnywhere
Ctrl+Alt+ZUndo the last expansionAnywhere
Alt+`Suspend and resumeAnywhere
Ctrl+NNew shortcutKeySnap window
Ctrl+DDuplicateKeySnap window
Ctrl+FSearchKeySnap window
Ctrl+SSave nowKeySnap window
Ctrl+OOpen another libraryKeySnap window
DeleteDelete the selected shortcutsKeySnap window

All of the global ones can be changed under Settings → Hotkeys.

Where things live

WhatWhere
Your shortcuts%APPDATA%\KeySnap\snippets.json
Preferences%APPDATA%\KeySnap\settings.json
Backups%APPDATA%\KeySnap\Backups\
Diagnostic log, if switched on%APPDATA%\KeySnap\keysnap.log
Startup entryHKCU\Software\Microsoft\Windows\CurrentVersion\Run

The snippet file is documented, readable JSON. You can open it, diff it, put it in version control, and edit it by hand if you want to — KeySnap repairs anything obviously broken on load rather than refusing to start.

Troubleshooting

Nothing expands anywhere

It expands everywhere except one program

Characters are repeated, or come out as one letter over and over

If ;eml produces mmmmmmmm rather than your address — the same number of characters, but all of them the last one — the program you are typing into is not keeping up with the keystrokes KeySnap is sending it.

Windows delivers typed Unicode as VK_PACKET events, and some controls read each event against the most recent packet rather than the one it arrived with. Send them faster than the program drains its queue and every character in the run resolves to the last one. Windows Notepad does this; so do a few others.

The cure is a small gap between keystrokes, which KeySnap leaves by default. If you still see it, raise Between keystrokes under Settings → Typing to 10 or 15 milliseconds. Setting it to zero is what causes this, so do not.

Characters are dropped or arrive out of order

Same setting, same reasoning. Older Java applications, some remote desktop sessions and a few terminal emulators need more room than the default allows. Raise Between keystrokes a few milliseconds at a time — it is a tax on every expansion, so do not go further than you need.

Part of what I typed goes missing, or the abbreviation is left behind

A shortcut fires on the last character of the abbreviation, and the replacement follows a few hundredths of a second later. If you are typing quickly — and you usually are, right after fixing a typo — the next few characters land in the document during that gap.

KeySnap keeps track of them, erases past them, and types them again after the replacement, so ;sig now comes out as your sign-off followed by now. Nothing needs configuring. If you press Backspace back over the abbreviation in that same moment, or click somewhere else, KeySnap takes it that you changed your mind and leaves the text alone rather than guessing.

Keeping a password in a shortcut

People do this. KeySnap is built on the assumption that they will, so here is exactly what it does and where it stops.

Mark a shortcut protected and its contents are encrypted on disk against your Windows account. A copy of your snippet file — in a backup, in OneDrive, on a laptop somebody walks off with — is useless to anyone else. On its own that is all it does: any program running as you can ask Windows to decrypt it, exactly as KeySnap does.

Add a passphrase under Settings → Security and that changes. The passphrase is something the computer does not know, so it has to be typed. KeySnap asks the first time you use a protected shortcut, not when it starts, and forgets it again after fifteen minutes of not using one. Everything that is not protected keeps working the whole time.

Protected shortcuts are also decrypted only at the moment one is used, never when the library is opened, so their contents are not sitting in memory while you get on with your day. They are never pasted through the clipboard, never written to the log, never shown in a notification, and a shortcut that is not protected cannot pull one in with {snippet:}.

There is no way to recover a forgotten passphrase. Not by us, not by anyone. If you lose it, the contents of every protected shortcut are gone. Write it down somewhere you trust before you set one.

What none of this stops: software that is already running as you and watching your keyboard. It sees what you type as you type it, before KeySnap is involved at all. A text expander cannot fix a compromised computer, and you should be suspicious of one that says it can.

KeySnap expanded something into a password box

It should not. Settings → Security → Do not expand in password boxes is on by default, and covers both the standard Windows password field and the ones browsers and newer apps draw for themselves.

The check is a good net rather than a guarantee — a field that identifies itself as neither will not be recognised. If you find one, the reliable fix is a scope rule: open the shortcut, choose Except in, and name the program.

A shortcut fires when I did not want it to

The clipboard keeps changing

Long replacements are pasted rather than typed, because typing three hundred characters one at a time is slow. KeySnap puts the clipboard back afterwards. If you would rather it never touched the clipboard, set Settings → Typing to Type it out.

Still stuck

Switch on Settings → Security → Keep a diagnostic log, reproduce the problem, and send us the log. It records what KeySnap did and never what you typed or what a snippet contains, so it is safe to share.