Skip to main content

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

AreaWhere it applies
globalQuit, cancel, vertical navigation — everywhere
inboxEmail list view (visual select, delete, archive, tabs)
emailSingle-email view (reply, forward, RSVP, attachments)
composerNew email / reply / forward editor
folderFolder sidebar + split-pane preview
draftsDraft 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:

FormExamples
Single charactera, 1, ?
Modifier + keyctrl+c, ctrl+e, shift+tab
Named keyenter, esc, tab, space
Arrowup, 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 / n on confirmation prompts
  • enter inside 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"
}
}