cmux Keyboard Shortcuts for Pane Navigation: Complete Guide to Focus Commands
cmux provides four directional keyboard shortcuts—⌘⌥←, ⌘⌥→, ⌘⌥↑, and ⌘⌥↓—to instantly move focus between adjacent split panes, hard-wired in KeyboardShortcutSettings.swift and routed through the Bonsplit controller.
The manaflow-ai/cmux terminal multiplexer for macOS streamlines multi-pane workflows with intuitive cmux keyboard shortcuts for navigation. These shortcuts are defined centrally in Sources/KeyboardShortcutSettings.swift and persist via user defaults under specific keys. Understanding the default bindings and customization API allows developers to optimize their terminal layout management.
Default cmux Pane Navigation Shortcuts
The application ships with four built-in actions for directional pane focus. These are declared in the Action enum at lines 34‑38 of KeyboardShortcutSettings.swift and bound to specific key combinations via the defaultShortcut property at lines 156‑163.
Directional Focus Commands
- Focus Pane Left:
⌘⌥←(Command + Option + Left Arrow) — Mapped toAction.focusLeft - Focus Pane Right:
⌘⌥→(Command + Option + Right Arrow) — Mapped toAction.focusRight - Focus Pane Up:
⌘⌥↑(Command + Option + Up Arrow) — Mapped toAction.focusUp - Focus Pane Down:
⌘⌥↓(Command + Option + Down Arrow) — Mapped toAction.focusDown
Each shortcut is stored in user defaults under the keys shortcut.focusLeft, shortcut.focusRight, shortcut.focusUp, and shortcut.focusDown. The static constants focusLeftKey, focusRightKey, focusUpKey, and focusDownKey (defined at lines 286‑290) provide programmatic access to these storage keys for UI reset and clearing operations.
How cmux Shortcut Routing Works
The pane navigation system follows a declarative pipeline from key press to focus change. When a user invokes a shortcut, the system matches the keystroke to a StoredShortcut instance, resolves the corresponding Action enum case, and routes the command through the workspace hierarchy.
- Definition: The
KeyboardShortcutSettings.Actionenum declares the four navigation actions (focusLeft,focusRight,focusUp,focusDown). - Binding:
defaultShortcutsupplies aStoredShortcutinitialized with the appropriate arrow key and modifiers (command: true, option: true). - Persistence: Shortcuts serialize to user defaults under the
shortcut.focus*keys. - Execution:
AppDelegatecaptures the shortcut event and forwards it toworkspace.bonsplitController.focusPane(paneId), which performs the actual focus shift inWorkspaceContentView.swift.
The BonsplitController handles the spatial logic for determining which paneId resides in the requested direction, ensuring focus jumps to the correct adjacent split.
Customizing cmux Keyboard Shortcuts
Developers can override default bindings programmatically using the public API exposed in KeyboardShortcutSettings.swift. The StoredShortcut struct encapsulates the key code and modifier flags.
// Change "Focus Left" to ⌘⌥H
let newShortcut = StoredShortcut(
key: "h",
command: true,
shift: false,
option: true,
control: false
)
KeyboardShortcutSettings.setShortcut(newShortcut, for: .focusLeft)
After execution, the UI updates immediately and the underlying user default for shortcut.focusLeft persists the new binding. To retrieve the current binding for display in help overlays:
let current = KeyboardShortcutSettings.focusLeftShortcut()
print("Current focus-left shortcut: \(current.displayString)")
// Output: "⌘⌥H" (if customized) or "⌘⌥←" (default)
Programmatic Pane Navigation via Socket Commands
External scripts and CLI tools can trigger pane focus changes by sending socket commands to the running cmux instance. The command strings map directly to the Action enum cases.
// Send focus command via socket
let command = "focus_right"
socket.send(command) // Triggers Action.focusRight internally
Available socket commands correspond exactly to the directional actions:
focus_leftfocus_rightfocus_upfocus_down
These strings are interpreted by cmux’s CLI layer and routed to the same BonsplitController.focusPane(paneId) method invoked by physical keyboard shortcuts.
Summary
- cmux provides four default directional shortcuts (
⌘⌥←→↑↓) for pane navigation, defined inKeyboardShortcutSettings.swiftlines 34‑38 and 156‑163. - Shortcuts persist via user defaults under keys like
shortcut.focusLeft, referenced by static constants at lines 286‑290. - The routing chain flows from
AppDelegatetoworkspace.bonsplitController.focusPane(paneId)inWorkspaceContentView.swift. - Developers can customize bindings via
KeyboardShortcutSettings.setShortcut(_:for:)usingStoredShortcutobjects. - Socket commands (
focus_left,focus_right, etc.) enable external automation of pane focus.
Frequently Asked Questions
What are the default cmux keyboard shortcuts for pane navigation?
The defaults are ⌘⌥← (left), ⌘⌥→ (right), ⌘⌥↑ (up), and ⌘⌥↓ (down). These bindings are hard-coded in KeyboardShortcutSettings.swift at lines 156‑163 as StoredShortcut instances with Command and Option modifiers.
How do I change the default pane navigation shortcuts in cmux?
Use the KeyboardShortcutSettings.setShortcut(_:for:) API, passing a StoredShortcut object with your desired key and modifier flags. This updates both the active binding and the user default entry (e.g., shortcut.focusLeft) immediately.
Can I trigger pane navigation programmatically in cmux?
Yes. Send socket commands focus_left, focus_right, focus_up, or focus_down to the cmux instance. The CLI interprets these strings and routes them to BonsplitController.focusPane(paneId), executing the same logic as physical key presses.
Where are cmux keyboard shortcuts stored?
Shortcuts serialize to macOS user defaults under keys defined by KeyboardShortcutSettings.focusLeftKey and its directional counterparts (lines 286‑290). The format uses the StoredShortcut codable structure, allowing persistence across app launches.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →