Keybinds
Matcha lets you remap every keyboard shortcut. Bindings live in plain JSON at ~/.config/matcha/keybinds.json and are written automatically the first time you launch the app.
File location
~/.config/matcha/keybinds.json
Plain text, not encrypted. Edit with any text editor. Restart matcha to apply changes.
Default bindings
{
"global": {
"quit": "ctrl+c",
"cancel": "esc",
"nav_up": "k",
"nav_down": "j",
"command_palette": "ctrl+k"
},
"inbox": {
"visual_mode": "v",
"toggle_threaded": "T",
"delete": "d",
"archive": "a",
"refresh": "r",
"search": "/",
"filter": "f",
"open": "enter",
"next_tab": "l",
"prev_tab": "h"
},
"email": {
"reply": "r",
"forward": "f",
"delete": "d",
"archive": "a",
"toggle_images": "i",
"rsvp_accept": "1",
"rsvp_decline": "2",
"rsvp_tentative": "3",
"focus_attachments": "tab"
},
"composer": {
"external_editor": "ctrl+e",
"next_field": "tab",
"prev_field": "shift+tab",
"undo_send": "u"
},
"folder": {
"next_folder": "tab",
"prev_folder": "shift+tab",
"move": "m",
"focus_preview": "]",
"focus_inbox": "["
},
"drafts": {
"open": "enter",
"delete": "d"
}
}
Command palette
Press command_palette (ctrl+k by default) from the start menu, inbox, folder
list, or an open email to bring up a searchable command palette — the same idea
as Zed or VS Code. Start typing to fuzzy-filter, ↑/↓ to move, enter to run,
esc to dismiss.
The palette lists the global navigation commands (Compose, Inbox, Drafts, Marketplace, Settings, Main menu, Quit) plus the actions for whatever view you opened it from (reply/forward/delete/archive in an email; refresh/search/filter/ toggle threaded/delete/archive in the inbox). Each palette action simply replays its keybinding, so it always matches whatever you've configured — and you can rely on the palette for less-common actions instead of memorizing every key.
The palette is suppressed while typing in the composer, login, and other text-entry views so the trigger key never interrupts editing.
Because the palette covers them, the bottom help bar stays intentionally short —
it shows only navigation essentials (folder/tab switching, split-pane focus) and
a commands hint for the palette. Every other action (visual mode, threaded
toggle, delete, archive, refresh, search, move to folder, …) is one ctrl+k
away. The keys themselves still work even when they're not printed on the bar.
Areas
| Area | Where it applies |
|---|---|
global | Quit, cancel, vertical navigation — everywhere |
inbox | Email list view (visual select, delete, archive, tabs) |
email | Single-email view (reply, forward, RSVP, attachments) |
composer | New email / reply / forward editor |
folder | Folder sidebar + split-pane preview |
drafts | Draft list |
The same key can appear in different areas without conflict — d is delete in both inbox and email, that's intentional. Conflicts only matter within one area.
Key syntax
Standard bubbletea key strings:
| Form | Examples |
|---|---|
| Single character | a, 1, ? |
| Modifier + key | ctrl+c, ctrl+e, shift+tab |
| Named key | enter, esc, tab, space |
| Arrow | up, down, left, right |
Conflict warning
If two actions inside the same area share a key, matcha shows a yellow warning at the top of the start menu:
⚠ keybind conflict in inbox: "d" used for both "delete" and "archive"
The warning stays until you fix the binding. Both actions still fire on the shared key, but only the first one wins.
What stays hardcoded
A few keys are never read from config — they exist as universal fallbacks:
- Arrow keys (
up,down,left,right) — always navigate y/non confirmation promptsenterinside modal pickers (file picker, account picker, move-to-folder)
This means even an empty or broken keybinds.json still leaves the app navigable.
Reset to defaults
Delete the file:
rm ~/.config/matcha/keybinds.json
Next launch writes a fresh default file.
Example: Emacs-style nav
{
"global": {
"quit": "ctrl+x",
"cancel": "esc",
"nav_up": "ctrl+p",
"nav_down": "ctrl+n"
}
}
Example: Single-key actions
{
"inbox": {
"delete": "x",
"archive": "e",
"refresh": "g",
"open": "enter",
"visual_mode": "V",
"next_tab": "n",
"prev_tab": "p"
}
}