Accent Letters
Insert any of 682 accented letters from a searchable picker, and strip accents back out when
text has to become an identifier, a slug or plain ASCII.
Works offline. No account, no telemetry, no network calls of any kind.
Commands
Open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and type "Accent":
| Command |
What it does |
| Insert Accented Letter… |
A searchable picker over all 682 letters. Inserts at every cursor. |
| Insert Accented Letter by Language… |
Pick a language first, then one of its letters. 55 languages. |
| Copy Accented Letter to Clipboard… |
The same picker, but it copies instead of inserting. |
| Remove Accents |
Crème brûlée in São Paulo → Creme brulee in Sao Paulo. Works on the selection, or the whole file if nothing is selected. Also on the editor's right-click menu. |
| Convert to URL Slug |
Crème brûlée in São Paulo → creme-brulee-in-sao-paulo. |
Searching the picker
Search matches the letter, its Unicode name, its accent mark, the languages that use it, its code
point and its Windows Alt code — so all of these find é:
é e acute acute spanish 00e9 alt+0233 é
Plain-English wordings work too: two dots finds ä ë ï ö ü, accent going up finds the acute
letters, hacek finds č š ž.
Letters you pick are remembered and float to the top. You can pin your own with
accentLetters.favourites.
Settings
| Setting |
Default |
What it does |
accentLetters.favourites |
[] |
Letters pinned to the top of the picker, e.g. ["é", "ñ", "ü"]. |
accentLetters.removeAccents.convertSpecial |
true |
Also convert ø ł đ ħ ı ŧ ß æ œ þ ð, which Unicode does not decompose. |
accentLetters.removeAccents.germanStyle |
false |
ä → ae, ö → oe, ü → ue instead of a, o, u. |
accentLetters.removeAccents.lowercase |
false |
Lowercase the result. Slugs always lowercase. |
Keyboard shortcuts
None are set by default, so nothing you already use gets taken. To add one, open Keyboard Shortcuts,
search for "Accent Letters", and bind whatever is free on your layout.
What "remove accents" actually does
Most accented letters decompose: é (U+00E9) is e (U+0065) followed by U+0301 COMBINING ACUTE
ACCENT, so Unicode NFD normalization plus deleting every combining mark leaves the plain letter.
Some letters do not decompose at all — ø, ł, đ, ß, æ, œ, þ and Turkish dotless ı are
separate letters, not decorated ones, and NFD leaves them exactly as they are. Those need a lookup
table, which is what convertSpecial switches on.
Removing accents is not always safe. In Spanish, año (year) becomes ano, a different word.
In German, ü is traditionally written ue, not u. In Turkish, dotless ı and dotted i are
different letters. Keep the accents in names and in anything a native reader will see.
Privacy
The extension reads a JSON file that ships inside it and writes to your editor. That is all.
- No network requests. Nothing is fetched, and nothing is sent.
- No telemetry, analytics or crash reporting.
- No account, no sign-in.
- The only thing stored is the list of letters you recently picked, in VS Code's own global state
on your machine.
It runs in untrusted workspaces and in virtual workspaces, because it never executes workspace code.
Where the data comes from
682 letters and 55 languages, generated from the Unicode Character Database 16.0.0 and
CLDR 48.2.0. The same file is shared byte-for-byte with the Accent Letters website, iOS and
Android apps, browser extensions and every other add-on, so the letters cannot drift between them.
Verification
Two suites, because they catch different things:
node preview.mjs # 24 checks: the logic, with the `vscode` module stubbed
npm test # 10 checks: the real extension inside a real VS Code
npm test downloads VS Code and runs the extension in an actual extension host — it activates the
extension, confirms VS Code registers every contributed command, and applies real edits through the
TextEditor API, including the multi-cursor case. The logic suite cannot see any of that.
That split is not academic. The LibreOffice build of the same feature passed its data checks and was
still completely broken when finally run in LibreOffice, because that host's InStr is
case-insensitive by default. Run the real thing in the real host.
More