Instantly replace typed text using your own substitution rules — TeXShop-style "key bindings" for VS Code / Cursor.
🇯🇵 日本語版 README はこちら (Japanese README)
TypeSwap watches what you type and replaces it the moment it appears, based on a list of rules you define. It is inspired by the key bindings feature of TeXShop, the macOS TeX editor — but works for any language, not just TeX.
Typical uses:
- Type
¥on a Japanese keyboard and get\in your LaTeX source - Type
$with text selected and get the selection wrapped as$…$, cursor placed at the end - Type
"and get proper TeX quotation marks``…'' - Convert full-width spaces to half-width spaces as you type
Install the extension — it works immediately. These rules are preconfigured:
| From | To | Languages | Effect |
|---|---|---|---|
(full-width space) |
(half-width space) |
all | fixes accidental full-width spaces |
¥ |
\ |
TeX/LaTeX | yen sign → backslash |
" |
``#SEL##INS#'' |
TeX/LaTeX | TeX-style quotes around the selection |
$ |
$#SEL##INS#$ |
TeX/LaTeX | wraps the selection in inline math |
To customize the rules, run TypeSwap: Edit Replacement Rules (GUI) from the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) — no need to touch settings.json. You can also edit typeswap.rules in settings.json directly if you prefer.
If to contains #SEL#, the text selected just before typing is inserted at that position. With no selection, #SEL# simply disappears.
| From | To | Action | Result |
|---|---|---|---|
$ |
$#SEL#$ |
select E=mc^2, type $ |
$E=mc^2$ |
[ |
[#SEL#] |
select link, type [ |
[link] |
#SEL# may appear multiple times; every occurrence receives the same selected text.
If to contains #INS#, the cursor moves to that position after the replacement. The marker itself is removed from the output. Multiple #INS# markers create multiple cursors (multi-cursor mode).
| From | To | Cursor after typing |
|---|---|---|
$ |
$#INS#$ |
between the two $ |
[ |
[#SEL##INS#] |
right after the selection, before ] |
Combining #SEL# and #INS# gives you snippet-like behavior from plain typing.
Each entry of typeswap.rules supports:
| Property | Type | Default | Description |
|---|---|---|---|
from |
string | — (required) | Text to replace. Literal match (no regex). Must be a single character to react to keyboard input. |
to |
string | — (required) | Replacement text. Empty string deletes the input. May contain #SEL# / #INS#. |
replaceOnPaste |
boolean | false |
Also apply the rule to pasted text. |
enabled |
boolean | true |
Turn the rule off without deleting it. |
enabledLanguages |
string[] | [] |
Language IDs where this rule is active. Empty = follow the global setting. |
disabledLanguages |
string[] | [] |
Language IDs where this rule is inactive. Wins over enabledLanguages. |
description |
string | — | Free-form note; no effect on behavior. |
typeswap.enabledLanguages(global): language IDs where TypeSwap is active at all. Empty array (default) = all languages. This one is editable directly in the Settings UI.- Per-rule override: each rule's
enabledLanguages/disabledLanguagesrefine or override the global setting.
Evaluation order (first match wins):
- Language is in the rule's
disabledLanguages→ inactive - The rule's
enabledLanguagesis non-empty → active iff the language is listed (overrides the global setting) - Otherwise → follow the global
typeswap.enabledLanguages
By default, pasted text is not modified. Set replaceOnPaste: true on a rule to apply it to pasted content too.
How paste is detected: the VS Code API cannot distinguish keystrokes from paste, so any change of two or more characters is treated as paste-like. IME commits (e.g. Japanese input) may therefore also count as "paste".
fromis a literal string — regular expressions are not supported.- Rules whose
fromis longer than one character never trigger on keystrokes, only on paste (withreplaceOnPaste: true). - When several rules match the same change, they are applied in list order.
- A single Undo (
Cmd+Z/Ctrl+Z) restores the text exactly as typed. - In
settings.json, a backslash intomust be written as"\\"(JSON escaping). - The yen sign (
¥, U+00A5) and the backslash (\, U+005C) are distinct characters; the¥key on Japanese keyboards produces U+00A5, so you can write¥literally infrom.