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
- Open KeySnap and click New shortcut.
- In Shortcut, type something you would never type by accident. A leading
semicolon is a good habit:
;sigrather thansig. - In Replacement, type what you want to appear.
- 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.
| Mode | Fires | Good 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 type | You get | Why |
|---|---|---|
btw | by the way | As authored. |
Btw | By the way | You capitalised, so the replacement is capitalised. |
BTW | BY THE WAY | You 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.
| Token | What it does | Example |
|---|---|---|
{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 afterwards | Dear {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.
;bookingHi {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 *.
;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.
- Program — the executable name without the extension, such as
outlookorchrome. - Window title — matches what is in the title bar, so you can target a particular document or web page.
- Window class — for the rare case where two programs share a name.
- Full path — to distinguish two copies of the same executable.
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
- Standard Windows password boxes — expansion is suspended while one has focus. This covers desktop applications and dialogs. Browsers and some modern apps draw their own fields and cannot be detected this way.
- Sign-in and consent prompts.
- Windows belonging to programs running as administrator. KeySnap runs without administrator rights on purpose and will not type into those.
Keyboard shortcuts
| Keys | Does | Where |
|---|---|---|
| Ctrl+Shift+Space | Quick-insert palette | Anywhere |
| Ctrl+Alt+K | Show the KeySnap window | Anywhere |
| Ctrl+Alt+Z | Undo the last expansion | Anywhere |
| Alt+` | Suspend and resume | Anywhere |
| Ctrl+N | New shortcut | KeySnap window |
| Ctrl+D | Duplicate | KeySnap window |
| Ctrl+F | Search | KeySnap window |
| Ctrl+S | Save now | KeySnap window |
| Ctrl+O | Open another library | KeySnap window |
| Delete | Delete the selected shortcuts | KeySnap window |
All of the global ones can be changed under Settings → Hotkeys.
Where things live
| What | Where |
|---|---|
| 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 entry | HKCU\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
- Check the tray icon: it says "suspended" when expansion is paused. Alt+` toggles it.
- Check the shortcut is switched on — the tick box in the list.
- Check the group it lives in is switched on.
- If you have just installed something that also hooks the keyboard, restart KeySnap. Windows removes a keyboard hook whose owner is too slow to respond, and a badly behaved neighbour can take yours down with it.
It expands everywhere except one program
- That program is probably running as administrator. Windows blocks ordinary applications from typing into elevated windows. KeySnap will say so when it happens.
- If it is a remote desktop or virtual machine window, try switching the shortcut to Type it out under Options, and adding 5–10 ms of keystroke delay under Settings → Typing.
- Check the shortcut's scope rules.
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
- Press Ctrl+Alt+Z straight away — that puts back exactly what you typed.
- Then either add a prefix character to the abbreviation, or switch that shortcut to After a space or punctuation.
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.