# Terminal keyboard map

> Every terminal app shortcut, and how to rebind them in keybindings.json.

These tables come from the app's own keybinding definitions. `Ctrl`+`Y` shows the same list in the app.

*Terminal: The keybindings panel, opened with Ctrl+Y.*

```text
 ┌ New session ─────────── ▢ ─ ~/acme-api  0 user messages  0 turns  ctrl+shift+x session ┐
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │  ┌─ keybindings ──────────────────────────────────────────────────────── 38 actions ┐  │
 │  │                                                                                  │  │
 │  │   Global                                                                      ▀  │  │
 │  │     ctrl+o        settings                                                       │  │
 │  │                   open settings                                                  │  │
 │  │     ctrl+shift+x  session                                                        │  │
 │  │                   open session details: stats, export, rename, delete            │  │
 │  │     ctrl+n        new session                                                    │  │
 │  │                   start a new session with the current model                     │  │
 │  │     ctrl+m        model                                                          │  │
 │  │                   open the model picker                                          │  │
 │  │     ctrl+l        options                                                        │  │
 │  │                                                                                  │  │
 │  │   ▶ Edit keybindings file  ›                                                     │  │
 │  │     ~/.zidane/keybindings.json. Restart to apply.                                │  │
 │  │                                                                                  │  │
 │  │  ↵ edit file  esc close                                                          │  │
 │  └──────────────────────────────────────────────────────────────────────────────────┘  │
 └────────────────────────────────────────────────────────────────────────────────────────┘
 ┌──────────────────────── ↵ send  shift+↵ newline  ↑↓ history  ? search  ctrl+s messages ┐
 │ Ask zidane…                                                                            │
 └────────────────────────────────────────────────────────────────────────────────────────┘
 shift+tab Build  ctrl+m/l Opus 5.5 +1 medium  ctrl+shift+x session  ctrl+o settings
                                                                         ctx 0 / 1.00M (0%)
```

## Global

| Action | Keys | Description |
| - | - | - |
| Settings (`openSettings`) | `ctrl+O` | Open settings. |
| Session (`openSessionDetails`) | `ctrl+shift+X` | Open session details: stats, export, rename, delete. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| New session (`newSession`) | `ctrl+N` | Start a new session with the current model. |
| Model (`openModelPicker`) | `ctrl+M` | Open the model picker. |
| Options (`openEffortPicker`) | `ctrl+L` | Open model options, like reasoning effort and fast mode. |
| Todos (`openTodos`) | `ctrl+T` | Open the run's todo list. |
| Panel (`openArtifacts`) | `ctrl+shift+A` | Show or hide the side panel. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| Next panel (`panelNext`) | `ctrl+shift+]` | Open the next side-panel tab. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| Previous panel (`panelPrev`) | `ctrl+shift+[` | Open the previous side-panel tab. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| Next space (`nextSpace`) | `ctrl+shift+→` | Show the next space (Spaces on); from a chat, the sessions list opens on it. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| Previous space (`prevSpace`) | `ctrl+shift+←` | Show the previous space (Spaces on); from a chat, the sessions list opens on it. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| Context (`openContextPanel`) | `ctrl+shift+G` | Show what fills the context window. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| Main session (`openMainSession`) | `ctrl+shift+M` | Open the Main session for this directory, or create it. Needs the "Main session" and "Use daemon runtime" settings. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| Usage (`openUsagePanel`) | `ctrl+P` | Open plan limits and credits for each provider. |
| Keybindings (`openKeybindings`) | `ctrl+Y` | List every shortcut. |
| Palette (`openPalette`) | `ctrl+shift+P` | Search actions, commands, sessions and settings. Needs the kitty keyboard protocol: macOS Terminal.app drops shift, so rebind it there. |
| Cycle agent (`cycleAgent`) | `shift+tab` | Switch to the next agent profile. |
| Messages (`enterSelectTurnMode`) | `ctrl+S` | Select a previous message. |
| Cancel tool (`cancelToolCall`) | `ctrl+K` | Cancel one tool call and keep the run going. |
| Abort (`abortRun`) | `ctrl+esc` | Stop the run and deny pending approvals. If your terminal cannot send ctrl+esc, rebind it. Some terminals cannot report ctrl+esc: rebind it there. |
| Retry (`resumeRun`) | `ctrl+R` | Pick up the run that stopped: retry, continue, or sign in again when a sign-in stopped it. |
| Cwd (`changeCwd`) | `ctrl+H` | Change the working directory. |
| Paste clipboard (`attachClipboardImage`) | `ctrl+V` | Paste text or an image from the system clipboard. |
| Edit in $EDITOR (`openExternalEditor`) | `ctrl+G` | Write the prompt in $EDITOR or $VISUAL. Needs the "Edit prompt in $EDITOR" setting. |

Chords with `Ctrl`+`Shift` need a terminal that reports the kitty keyboard protocol, such as kitty, WezTerm or Ghostty. On macOS, Terminal.app drops Shift, so `Ctrl`+`Shift`+`X` arrives as `Ctrl`+`X`. In Terminal.app, rebind these actions to chords without Shift.

## Sessions list

| Action | Keys | Description |
| - | - | - |
| Next space (`cycleSpaceInList`) | `shift+tab` | Show the next space in the sessions list (wraps), also while typing a search. Needs 2 or more spaces. In a chat, shift+tab still cycles agents. |

These keys act only in the sessions list, so `Shift`+`Tab` still cycles agents in a chat. `←` `→` and a click on the space name in the title also switch spaces: [sessions and forks](https://zidane.si/docs/tui-sessions.md#the-sessions-list).

## Message queue

| Action | Keys | Description |
| - | - | - |
| Select queue (`enterQueueSelection`) | Unbound | Select the queued messages (or press ↑ on an empty prompt). |
| Push (`pushQueuedMessage`) | `ctrl+enter` | Send the selected queued message into the running turn. |
| Drop (`dropQueuedMessage`) | `backspace` | Remove the selected queued message. |

`↑` on an empty prompt enters the queue without a binding.

## Messages and session details

Keys inside an open message (fork, delete, copy, edit) and session details (export, compact, favorite and more) are on [sessions and forks](https://zidane.si/docs/tui-sessions.md). They rebind in the same file.

## Fixed keys

| Key | Where | Does |
| - | - | - |
| `Esc` | Chat | Go to the sessions list |
| `Esc` | Popups, modals, search, queue | Close or leave |
| `Esc` | File-edit approval | Deny |
| `Enter` | Prompt | Send |
| `Shift`+`Enter` | Prompt | New line |
| `Tab` | Completion popup | Pick |
| `?` | Empty prompt | Search the conversation |
| `!` | Empty prompt | Shell mode |
| `Ctrl`+`C` | Anywhere | Copy the selection of the prompt or an input, else quit (Settings › UI › Ctrl+C behavior) |
| `Ctrl`+`X` | Prompt or input with a selection | Cut |
| `←` `→` | Settings | Switch tab |
| `Ctrl`+`B` `Ctrl`+`F` | Settings › Keybindings and Logs | Scroll half a page up or down |
| `Home` `End` | Settings › Keybindings and Logs | Jump to the top or bottom |
| `Space` | Setup wizard | Pick the row, or turn it on or off |
| `Enter` | Setup wizard | Continue |
| `S` | Setup wizard | Skip the step, if it can be skipped |
| `Esc` | Setup wizard | Go back one step, or close a re-run on its first step |

Settings tabs also have their own `Ctrl` keys, such as `Ctrl`+`D` to clear an extension secret: [Settings](https://zidane.si/docs/tui-settings.md#keys), [MCP, skills and extensions](https://zidane.si/docs/tui-mcp.md), [remote hosts](https://zidane.si/docs/tui-remote.md).

## Rebind a key

Shortcuts live in `keybindings.json` in your config folder ([files and folders](https://zidane.si/docs/files.md)).

1. Open Settings › Keybindings and press `Enter`. If the file does not exist, zidane creates it with every action and its default. The file opens in `$VISUAL` or `$EDITOR`. If neither is set, the system opener opens it (`open` on macOS, `xdg-open` on Linux).
2. Change the values and save the file.
3. Restart the app. zidane reads the file only at start.

```jsonc title="keybindings.json"
{
  // Terminal.app drops shift: give the session modal a plain chord.
  "openSessionDetails": "ctrl+e",
  // Two chords for one action.
  "abortRun": "ctrl+escape | ctrl+q",
  // An array also lists several chords.
  "openUsagePanel": ["ctrl+p", "alt+u"]
}
```

| Example | Rule |
| - | - |
| `ctrl+shift+p` | Modifiers: `ctrl`, `shift`, `alt` (or `option`), `meta` (or `cmd`) |
| `"ctrl+w \| cmd+w"` | Several chords. An array (`["ctrl+w", "cmd+w"]`) also works. |
| `Shift+Ctrl+P` | Case and modifier order do not matter |
| `ctrl-p` | `-` also separates the parts |
| `esc`, `enter` | Key names: `escape` (`esc`), `return` (`enter`), `space`, `backspace`, `up`, `pgup`, `[` |

The file allows `//` and `/* */` comments. If zidane cannot parse an entry, the action keeps its default. An empty value (`""`) also keeps the default, so it does not unbind a built-in action. If the whole file does not parse, every action keeps its default.

Extension shortcuts use the same file, keyed by their id. Settings › Keybindings lists each id. An extension shortcut cannot take `Esc`, `Ctrl`+`Esc`, `Ctrl`+`C` or a single letter without `Ctrl`, `Alt` or `Cmd`.

Bindings are the same on macOS and Linux, because the terminal reports the keys. Most terminals cannot send `Cmd`. The desktop app has its own `Cmd` map and reloads it without a restart: [desktop keyboard](https://zidane.si/docs/desktop-keyboard.md).
