Opencode Keybindings
OpenCode provides a complete keyboard shortcut system covering application control, session management, message browsing, model switching, and input editing operations.
All shortcuts can be customized via the `tui.json` file.
* * *
## Configuration File
Shortcut configurations are written under the `keybinds` field in the `tui.json` file. Each record uses the operation name as the key and the corresponding shortcut as the value:
## Example
{
"$schema": "https://opencode.ai/tui.json",
"keybinds": {
"leader": "ctrl+x", // Leader key setting (see explanation below)
"session_new": "n", // New session: press leader key first, then n
"model_list": "m", // Open model list: press leader key first, then m
"session_compact": "none" // Set value to "none" to disable this shortcut
}
}
An operation can be bound to multiple shortcuts, separated by English commas. Any of them can trigger the operation:
## Example
{
"$schema": "https://opencode.ai/tui.json",
"keybinds": {
// The following means: pressing pageup or ctrl+alt+b both scroll up one page
"messages_page_up": "pageup,ctrl+alt+b"
}
}
* * *
## Leader Key
Most shortcuts in OpenCode use the **Leader Key** mechanism: press the leader key first, then press the function key, and the two-key combination triggers the corresponding operation. This design avoids conflicts with the terminal's own shortcuts.
The default leader key is `ctrl+x`. For example, the shortcut for creating a new session is `n`, which means: press `ctrl+x` first, then press `n`.
You can change the leader key to any key combination:
## Example
{
"$schema": "https://opencode.ai/tui.json",
"keybinds": {
"leader": "ctrl+x" // Change leader key to other keys, such as "ctrl+space", "alt+x", etc.
// The placeholder in the configuration will be automatically replaced with the key set here
}
}
> It is not mandatory to use the leader key mechanism for shortcutsβyou can also directly bind ordinary keys or key combinations. However, it is recommended to use the leader key to avoid conflicts with terminal shortcuts.
* * *
## Disabling Shortcuts
Set any shortcut's value to `"none"` to disable that operation. After disabling, pressing any key will not trigger it:
## Example
{
"$schema": "https://opencode.ai/tui.json",
"keybinds": {
"session_compact": "none", // Disable "compact session" shortcut
"scrollbar_toggle": "none", // Disable "toggle scrollbar" shortcut
"tips_toggle": "none" // Disable "toggle tips" shortcut
}
}
* * *
## Complete Shortcut List
### 1. Application and Interface
| Operation Name | Default Shortcut | Description |
| --- | --- | --- |
| `app_exit` | `ctrl+c`, `ctrl+d`, `q` | Exit OpenCode |
| `editor_open` | `e` | Open current input content in external editor |
| `theme_list` | `t` | Open theme list to switch interface theme |
| `sidebar_toggle` | `b` | Show or hide sidebar |
| `scrollbar_toggle` | None (disabled by default) | Show or hide scrollbar |
| `username_toggle` | None (disabled by default) | Show or hide username |
| `status_view` | `s` | View current status information |
| `tool_details` | None (disabled by default) | View tool call details |
| `command_list` | `ctrl+p` | Open command palette to search all available commands |
| `tips_toggle` | `h` | Show or hide usage tips |
| `display_thinking` | None (disabled by default) | Show or hide model's thinking process |
| `terminal_suspend` | `ctrl+z` | Suspend terminal (put OpenCode in background, return to shell; type `fg` to resume) |
| `terminal_title_toggle` | None (disabled by default) | Show or hide terminal title bar |
### 2. Session Management
| Operation Name | Default Shortcut | Description |
| --- | --- | --- |
| `session_new` | `n` | Create a new session |
| `session_list` | `l` | View all historical session list |
| `session_export` | `x` | Export current session content |
| `session_timeline` | `g` | View current session timeline |
| `session_fork` | None (disabled by default) | Create a forked session from current position |
| `session_rename` | None (disabled by default) | Rename current session |
| `session_share` | None (disabled by default) | Share current session |
| `session_unshare` | None (disabled by default) | Unshare current session |
| `session_interrupt` | `escape` | Interrupt currently running response |
| `session_compact` | `c` | Compact current session context to reduce token usage |
| `session_child_first` | `β` | Jump to first child session |
| `session_child_cycle` | `β` | Cycle forward through child sessions |
| `session_child_cycle_reverse` | `β` | Cycle backward through child sessions |
| `session_parent` | `β` | Return to parent session |
### 3. Message Browsing
| Operation Name | Default Shortcut | Description |
| --- | --- | --- |
| `messages_page_up` | `pageup`, `ctrl+alt+b` | Scroll up one page of messages |
| `messages_page_down` | `pagedown`, `ctrl+alt+f` | Scroll down one page of messages |
| `messages_line_up` | `ctrl+alt+y` | Scroll up one line |
| `messages_line_down` | `ctrl+alt+e` | Scroll down one line |
| `messages_half_page_up` | `ctrl+alt+u` | Scroll up half a page |
| `messages_half_page_down` | `ctrl+alt+d` | Scroll down half a page |
| `messages_first` | `ctrl+g`, `home` | Jump to earliest first message |
| `messages_last` | `ctrl+alt+g`, `end` | Jump to latest last message |
| `messages_next` | None (disabled by default) | Jump to next message |
| `messages_previous` | None (disabled by default) | Jump to previous message |
| `messages_last_user` | None (disabled by default) | Jump to last user message |
| `messages_copy` | `y` | Copy current message content to clipboard |
| `messages_undo` | `u` | Undo last operation |
| `messages_redo` | `r` | Redo undone operation |
| `messages_toggle_conceal` | `h` | Collapse or expand hidden content in messages |
### 4. Model and Agent
| Operation Name | Default Shortcut | Description |
| --- | --- | --- |
| `model_list` | `m` | Open model list to select and switch current model |
| `model_cycle_recent` | `f2` | Cycle forward through recently used models |
| `model_cycle_recent_reverse` | `shift+f2` | Cycle backward through recently used models |
| `model_cycle_favorite` | None (disabled by default) | Cycle forward through favorite models |
| `model_cycle_favorite_reverse` | None (disabled by default) | Cycle backward through favorite models |
| `variant_cycle` | `ctrl+t` | Cycle through variants of current model (such as thinking mode) |
| `agent_list` | `a` | Open agent list to select and switch current agent |
| `agent_cycle` | `tab` | Cycle forward through agents |
| `agent_cycle_reverse` | `shift+tab` | Cycle backward through agents |
### 5. Input Box Editing
| Operation Name | Default Shortcut | Description |
| --- | --- | --- |
| `input_submit` | `return` | Send current input content |
| `input_newline` | `shift+return`, `ctrl+return`, `alt+return`, `ctrl+j` | Insert newline in input box (without sending) |
| `input_clear` | `ctrl+c` | Clear input box content |
| `input_paste` | `ctrl+v` | Paste clipboard content into input box |
| `input_move_left` | `left`, `ctrl+b` | Move cursor left one character |
| `input_move_right` | `right`, `ctrl+f` | Move cursor right one character |
| `input_move_up` | `up` | Move cursor up one line |
| `input_move_down` | `down` | Move cursor down one line |
| `input_word_forward` | `alt+f`, `alt+right`, `ctrl+right` | Move cursor forward one word |
| `input_word_backward` | `alt+b`, `alt+left`, `ctrl+left` | Move cursor backward one word |
| `input_line_home` | `ctrl+a` | Move to beginning of current line |
| `input_line_end` | `ctrl+e` | Move to end of current line |
| `input_visual_line_home` | `alt+a` | Move to beginning of current visual line (line as displayed with wrapping) |
| `input_visual_line_end` | `alt+e` | Move to end of current visual line |
| `input_buffer_home` | `home` | Jump to beginning of entire input box content |
| `input_buffer_end` | `end` | Jump to end of entire input box content |
| `input_delete_to_line_end` | `ctrl+k` | Delete all content from cursor to end of current line |
| `input_delete_to_line_start` | `ctrl+u` | Delete all content from beginning of current line to cursor |
| `input_delete_line` | `ctrl+shift+d` | Delete entire line where cursor is located |
| `input_backspace` | `backspace`, `shift+backspace` | Delete character before cursor |
| `input_delete` | `ctrl+d`, `delete`, `shift+delete` | Delete character after cursor |
| `input_delete_word_forward` | `alt+d`, `alt+delete`, `ctrl+delete` | Delete word after cursor |
| `input_delete_word_backward` | `ctrl+w`, `ctrl+backspace`, `alt+backspace` | Delete word before cursor |
| `input_undo` | `ctrl+-`, `super+z` | Undo last edit in input box |
| `input_redo` | `ctrl+.`, `super+shift+z` | Redo undone edit |
### 6. Text Selection
| Operation Name | Default Shortcut | Description |
| --- | --- | --- |
| `input_select_left` | `shift+left` | Select one character to the left |
| `input_select_right` | `shift+right` | Select one character to the right |
| `input_select_up` | `shift+up` | Select one line upward |
| `input_select_down` | `shift+down` | Select one line downward |
| `input_select_word_forward` | `alt+shift+f`, `alt+shift+right` | Select one word forward |
| `input_select_word_backward` | `alt+shift+b`, `alt+shift+left` | Select one word backward |
| `input_select_line_home` | `ctrl+shift+a` | Select from cursor position to beginning of current line |
| `input_select_line_end` | `ctrl+shift+e` | Select from cursor position to end of current line |
| `input_select_visual_line_home` | `alt+shift+a` | Select from cursor position to beginning of current visual line |
| `input_select_visual_line_end` | `alt+shift+e` | Select from cursor position to end of current visual line |
| `input_select_buffer_home` | `shift+home` | Select from cursor position to beginning of input box |
| `input_select_buffer_end` | `shift+end` | Select from cursor position to end of input box |
### 7. Input History
| Operation Name | Default Shortcut | Description |
| --- | --- | --- |
| `history_previous` | `up` | Recall previous historical input (effective when input box is empty) |
| `history_next` | `down` | Recall next historical input |
* * *
## Desktop Version Built-in Input Shortcuts
The prompt input box in OpenCode Desktop additionally has a set of **Readline / Emacs style** text editing shortcuts built-in. **These shortcuts are built-in functions and cannot be modified or disabled via `tui.json`**:
| Shortcut | Operation |
| --- | --- |
| `ctrl+a` | Move to beginning of current line |
| `ctrl+e` | Move to end of current line |
| `ctrl+b` | Move cursor backward one character |
| `ctrl+f` | Move cursor forward one character |
| `alt+b` | Move cursor backward one word |
| `alt+f` | Move cursor forward one word |
| `ctrl+d` | Delete character at cursor position |
| `ctrl+k` | Delete content from cursor to end of line |
| `ctrl+u` | Delete content from cursor to beginning of line |
| `ctrl+w` | Delete previous word |
| `alt+d` | Delete next word |
| `ctrl+t` | Swap positions of characters before and after cursor |
| `ctrl+g` | Cancel current popup window, or abort running response |
* * *
## Configuring Shift+Enter for Newline
Some terminals do not send modified Enter keys (such as `Shift+Enter`) as independent keys by default, causing `Shift+Enter` in OpenCode to send the message instead of inserting a newline. You need to manually configure the escape sequence for this key in the terminal.
### Windows Terminal Configuration Method
**Step 1:** Open Windows Terminal's `settings.json` file, located at:
%LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json
**Step 2:** Add the following configuration to the root-level `actions` array to define an action that sends the `Shift+Enter` escape sequence:
## Example
"actions": [
{
"command": {
"action": "sendInput",
"input": "\u001b[13;2u" // Standard escape sequence for Shift+Enter (CSI u format)
},
"id": "User.sendInput.ShiftEnterCustom"
}
]
**Step 3:** Add a keybinding to the root-level `keybindings` array to map `Shift+Enter` to the action defined above:
## Example
"keybindings": [
{
"keys": "shift+enter",
"id": "User.sendInput.ShiftEnterCustom"
}
]
**Step 4:** Save the `settings.json` file, then restart Windows Terminal or open a new tab for the configuration to take effect.
YouTip