Make every keyboard shortcut rebindable and drop the iTerm2 preset - #1241
Merged
Conversation
Shortcuts were declared as data in keymap.ts but dispatched by hand-written modifier conditions in App.tsx, so a combo lived in two places and could not be rebound. keymap.ts now carries machine-readable bindings and every handler asks matchesShortcut(e, id); display strings are derived from those bindings. Settings gains a Keyboard category with a per-row combo recorder, conflict detection that names the losing shortcut, per-row and bulk reset, and read-only rows for structural bindings (g-chords, digit families, hold-modifier switcher, Esc) that state why they are fixed. The tmux keymap preset moves there from Terminal, and the reference overlay links to the editor. The app modifier is now strictly platform-exact, so macOS Ctrl aliases for Ctrl+, / Ctrl+= / Ctrl+` reach the terminal instead of the app.
… preset Every shortcut now carries two independently-editable slots instead of a flat binding list, so an alternative combo is something the user adds rather than an artifact of list order. Overrides persist per slot, where an absent slot keeps its default and null was deliberately emptied. The opt-in iTerm2 keymap preset is deleted along with all three of its toggles (Settings, the terminal info popover, and the native Terminal > Keyboard Mode menu). Its four pane combos are ordinary registry rows in the terminal conflict group, unbindable one at a time. Pane navigation is dropped rather than rebound: tmux already binds Alt+arrows prefix-free, which also removes the Cmd+bracket collision with app-level back/forward. The terminal info button now opens the unified shortcuts overlay on its Terminal tab, which leads with those four combos read from the registry.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes every app-level keyboard shortcut rebindable from Settings, and removes the "iTerm2 compatibility" preset in favour of always-on shortcuts you can change one at a time.
The keymap registry now dispatches
src/mainview/keymap.tsused to only document shortcuts — the combos were hand-written a second time as modifier conditions in a 320-lineif/elsechain inApp.tsx, which made rebinding impossible without editing two places. Every branch is nowmatchesShortcut(e, "<id>"), and display strings are derived from the bindings instead of authored twice.Bindings match
KeyboardEvent.code(layout-independent) with an exact modifier set. A consequence:Modis now strictly ⌘ on macOS, so the accidental(meta || ctrl)branches are gone and⌃,/⌃=/⌃`reach the terminal where they belong.Two slots per shortcut
Each shortcut carries a
primarycombo plus an optionalalias, set independently, rather than one flat binding list where "the second way to press it" was an artifact of ordering. Overrides persist per slot — an absent slot keeps its default,nullwas deliberately emptied — underGlobalSettings.keyboardShortcuts, sparse, so a changed default still reaches everyone who left that row alone.Settings → Keyboard
A new eighth Settings category. The key chips on each row are the control (no per-row "Change" button — 33 of those is button creep). Taking a combo someone else owns names them first and then empties only the slot that held it. Per-row reset, bulk reset behind
confirm(), and a filter that matches the rendered combo as well as the name.Seven structural shortcuts render read-only with a stated reason rather than being hidden: the
g …chord sequences, the ⌘1–9 / ⇧⌘1–9 digit families, the hold-modifier task switcher,Esc, and ⌘R.The iTerm2 preset is gone
It defaulted to on and existed only to switch four shortcuts off — something the editor now does per row. Deleted:
TerminalKeymapPreset,GlobalSettings.terminalKeymap,src/mainview/terminal-keymaps.ts, and all three of its toggles (Settings, the ⓘ popover beside the terminal, and the native Terminal ▸ Keyboard Mode menu).⌘D, ⌘⇧D, ⌘W and ⌘T are ordinary registry rows in the
terminalconflict group, dispatched only while a terminal has focus. Pane navigation (formerly ⌘[ / ⌘]) is dropped rather than rebound:src/bun/tmux/config.tsalready binds ⌥+arrows prefix-free, which also removes a latent collision where ⌘[ ran both app-level "back" and pane-focus in the same capture phase.The ⓘ button now opens the unified ⌘/ overlay on its Terminal tab, which leads with those four combos read from the registry, replacing a partial hover popover.
Also
keymap-store.tssuspends all dispatch while the recorder is open — both listeners sit onwindowin the capture phase and the dispatcher registered first, sostopPropagationis too late and a module flag is the only reliable gate.--text-muted(the ramp's decorative tier, ~2.99:1 on the light settings surface) to--text-tertiary; the Save button moved to--accent-fillbecause white on--accentis only 2.98:1 in dark theme.docs/ux/UX_DECISIONS.mdupdated; decision records195and196.