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 to Action.focusLeft
  • Focus Pane Right: ⌘⌥→ (Command + Option + Right Arrow) — Mapped to Action.focusRight
  • Focus Pane Up: ⌘⌥↑ (Command + Option + Up Arrow) — Mapped to Action.focusUp
  • Focus Pane Down: ⌘⌥↓ (Command + Option + Down Arrow) — Mapped to Action.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.

  1. Definition: The KeyboardShortcutSettings.Action enum declares the four navigation actions (focusLeft, focusRight, focusUp, focusDown).
  2. Binding: defaultShortcut supplies a StoredShortcut initialized with the appropriate arrow key and modifiers (command: true, option: true).
  3. Persistence: Shortcuts serialize to user defaults under the shortcut.focus* keys.
  4. Execution: AppDelegate captures the shortcut event and forwards it to workspace.bonsplitController.focusPane(paneId), which performs the actual focus shift in WorkspaceContentView.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_left
  • focus_right
  • focus_up
  • focus_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 in KeyboardShortcutSettings.swift lines 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 AppDelegate to workspace.bonsplitController.focusPane(paneId) in WorkspaceContentView.swift.
  • Developers can customize bindings via KeyboardShortcutSettings.setShortcut(_:for:) using StoredShortcut objects.
  • 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →