Command Inbox
Reference

Keyboard shortcuts

Complete shortcut registry from src/lib/shortcuts.ts

Source: src/lib/shortcuts.ts. Mod = on Mac, Ctrl on Windows/Linux.

Registry

IDKeyModShiftContextActionRequires threadPalette only
next-threadjlistnextThread
prev-threadklistprevThread
archiveethreadarchiveyes
replyrthreadreplyyes
meetingmthreadmeetingyes
snoozesthreadsnoozeyes
search/globalsearch
help/yesglobalhelp
selectxlistselect
palettekyesglobalpalette
advanced-searchfyesyesglobaladvancedSearch
sendEnteryescomposersend
cancel-composerEscapecomposercancelComposer
cancel-meetingthreadcancelMeetingyesyes

Hotkey bindings (react-hotkeys-hook)

Internal binding format from toHotkeyBinding():

ShortcutBinding
next-threadj
prev-threadk
archivee
replyr
meetingm
snoozes
search/
helpshift+/
selectx
palettemod+k
advanced-searchmod+shift+f
sendmod+enter
cancel-composerescape

Gating logic (isShortcutEnabled)

  1. paletteOnly shortcuts never bind to keys
  2. Single-key shortcuts disabled when any overlay open (composer, palette, snooze, availability, cheatsheet, search, advanced search)
  3. requiresThread shortcuts need selectedThreadId
  4. Composer context shortcuts only when composer open
  5. Non-global, non-composer shortcuts blocked while composer open

Helper functions

FunctionPurpose
getShortcutsByContext(context)Filter by global | list | thread | composer
getPaletteShortcuts()All except send/cancel-composer
formatShortcut(shortcut, isMac)Display string for cheat sheet
isSingleKeyLayerOpen(state)Whether modals block single-key shortcuts

ShortcutContext type

type ShortcutContext = "global" | "list" | "thread" | "composer";

ShortcutGateState

Used by useInboxShortcuts hook:

interface ShortcutGateState {
  composerOpen: boolean;
  paletteOpen: boolean;
  snoozeOpen: boolean;
  availabilityOpen: boolean;
  cheatsheetOpen: boolean;
  searchOpen: boolean;
  advancedSearchOpen: boolean;
  selectedThreadId: string | null;
}