Repository navigation
Closed as not planned
Closed as not planned
Copy link
Labels
needs:complianceThis means the issue will auto-close after 2 hours.This means the issue will auto-close after 2 hours.
Description
Context
OpenCode TUI defaults to emacs-style input keybindings. Our patch-selectall creates a hybrid emacs/monaco model inspired by VS Code Monaco editor chat input. This ticket documents the current state as a cheatsheet for future iteration.
Upstream Emacs Defaults (unpatched)
| Key | Action | Notes |
|---|---|---|
ctrl+a |
Line home (start of line) | Emacs standard |
ctrl+e |
Line end (end of line) | Emacs standard |
ctrl+b |
Move cursor left | Also zellij tmux prefix |
ctrl+f |
Move cursor right | Emacs standard |
ctrl+d |
Delete char forward | Emacs standard |
ctrl+k |
Delete to end of line | Emacs kill-line |
ctrl+u |
Delete to start of line | Emacs universal-arg (repurposed) |
ctrl+w |
Delete word backward | Emacs kill-word |
ctrl+v |
Paste | Override of emacs page-down |
ctrl+shift+d |
Delete line | Not emacs |
ctrl+shift+a |
Select to line start | Not emacs |
ctrl+shift+e |
Select to line end | Not emacs |
super+a |
Select all | Monaco style |
alt+f |
Move word forward | Emacs forward-word |
alt+b |
Move word backward | Emacs backward-word |
alt+d |
Delete word forward | Emacs kill-word |
pageup |
Scroll messages up by page | Global, not prompt-local |
pagedown |
Scroll messages down by page | Global, not prompt-local |
home |
Navigate to first message | Global, not prompt-local |
end |
Navigate to last message | Global, not prompt-local |
Our Hybrid (patch-selectall + tui.json)
Changes made by patch-selectall
| ID | What changed | Why |
|---|---|---|
| SA1 | input_line_home: ctrl+a → home |
Frees ctrl+a for select-all (monaco style) |
| SA1b | messages_first: removed home from ctrl+g,home |
Home key stays in prompt, not global jump |
| SA1b | messages_last: removed end from ctrl+alt+g,end |
End key stays in prompt, not global jump |
| SA1c | messages_page_up: removed pageup from pageup,ctrl+alt+b |
PageUp stays in prompt for scrolling |
| SA1c | messages_page_down: removed pagedown from pagedown,ctrl+alt+f |
PageDown stays in prompt for scrolling |
| SA2 | Added select-all to TEXTAREA_ACTIONS |
Enables native @OpenTui select-all |
| SA3 | input_select_all: super+a → ctrl+a |
Monaco-style select-all |
| SA3 | Added input_copy_selection: super+c,ctrl+shift+c |
Copy selected text (monaco style) |
| SA4 | Select-all copies to clipboard automatically | Select + copy in one action |
| SA4 | Home/End move within prompt line | Not global message navigation |
| SA4 | PageUp/PageDown scroll prompt content | Like monaco editor scrolling |
| SA5 | ESC clears text selection before interrupt | Prevents accidental interrupt when deselecting |
| SA6 | Dynamic interrupt label from keybind | Shows actual keybind instead of hardcoded "esc" |
Changes made by tui.json (runtime overrides)
| Key | Action | Why |
|---|---|---|
session_background |
ctrl+o (was ctrl+b) |
Zellij intercepts ctrl+b |
input_move_left |
left only (was left,ctrl+b) |
Zellij intercepts ctrl+b |
app_exit |
<leader>q (was ctrl+c,ctrl+d,<leader>q) |
Cleaner exit |
leader |
ctrl+x (same as upstream) |
Confirmed |
Changes made by patch-background-keybind (NOW DISABLED — tui.json handles it)
This patch was disabled in favor of tui.json runtime overrides:
session_background:ctrl+b→ctrl+o(same as tui.json)input_move_left:left,ctrl+b→left(same as tui.json)
Current Hybrid Cheatsheet
Prompt Input — Movement
| Key | Action | Source |
|---|---|---|
← (left) |
Move cursor left | tui.json (removed ctrl+b) |
→ (right) |
Move cursor right | upstream (ctrl+f also works) |
Home |
Start of line | patch SA1 (was ctrl+a) |
End |
End of line | upstream (ctrl+e still works) |
ctrl+e |
End of line | upstream emacs (kept) |
alt+f / ctrl+→ |
Move word forward | upstream |
alt+b / ctrl+← |
Move word backward | upstream |
Prompt Input — Selection
| Key | Action | Source |
|---|---|---|
ctrl+a |
Select all + copy | patch SA3+SA4 (monaco style) |
shift+← |
Select left | upstream |
shift+→ |
Select right | upstream |
shift+↑ |
Select up | upstream |
shift+↓ |
Select down | upstream |
shift+Home |
Select to buffer start | upstream |
shift+End |
Select to buffer end | upstream |
ctrl+shift+a |
Select to line start | upstream |
ctrl+shift+e |
Select to line end | upstream |
super+c / ctrl+shift+c |
Copy selection | patch SA3 |
Prompt Input — Editing
| Key | Action | Source |
|---|---|---|
ctrl+d / Delete |
Delete char forward | upstream |
ctrl+k |
Delete to end of line | upstream emacs |
ctrl+u |
Delete to start of line | upstream emacs |
ctrl+w / ctrl+⌫ |
Delete word backward | upstream emacs |
alt+d / ctrl+Delete |
Delete word forward | upstream emacs |
ctrl+shift+d |
Delete entire line | upstream |
ctrl+v |
Paste | upstream |
Escape |
Clear selection → interrupt | patch SA5 |
Prompt Input — Scrolling
| Key | Action | Source |
|---|---|---|
PageUp |
Scroll prompt content up | patch SA4 (was global msg scroll) |
PageDown |
Scroll prompt content down | patch SA4 (was global msg scroll) |
Global — Messages
| Key | Action | Source |
|---|---|---|
ctrl+alt+b |
Scroll messages up by page | patch SA1c (removed pageup) |
ctrl+alt+f |
Scroll messages down by page | patch SA1c (removed pagedown) |
ctrl+g |
Navigate to first message | patch SA1b (removed home) |
ctrl+alt+g |
Navigate to last message | patch SA1b (removed end) |
Global — Session
| Key | Action | Source |
|---|---|---|
ctrl+o |
Background subagents | tui.json (was ctrl+b, zellij conflict) |
ctrl+x |
Leader key | upstream |
<leader>q |
Exit app | tui.json |
ctrl+t |
Cycle model variants | upstream |
Tab |
Cycle agents | upstream |
escape |
Interrupt session | upstream (patched: clears selection first) |
Zellij Passthrough Notes
ctrl+b is zellij's tmux prefix key. When inside zellij:
ctrl+bis captured by zellij → never reaches opencode- Only
ctrl+bpassthrough sequences work (e.g.,ctrl+bthenzfor zoom) - This is why
input_move_leftandsession_backgroundneeded remapping
When NOT inside zellij (plain alacritty):
ctrl+bwould work for both, but tui.json overrides make it consistent- No zellij passthrough needed
Inconsistencies & Future Iteration Ideas
- ctrl+e still emacs, but ctrl+a is monaco — asymmetric. Consider remapping
ctrl+e→Endonly, or keep both for muscle memory. - ctrl+u deletes to line start (emacs), not universal-arg — fine for terminal, surprising for emacs users.
- ctrl+v paste (not emacs page-down) — already overridden upstream, matches terminal conventions.
- ctrl+a = select-all + auto-copy — unusual. Monaco selects but doesn't copy. Consider making copy optional.
- PageUp/PageDown local to prompt — good for long prompts, but users might expect message scrolling. Consider
shift+PageUpfor message scroll. - No ctrl+z undo — upstream has no prompt undo. Future patch candidate.
- No ctrl+y redo — same, future candidate.
- ctrl+k kill-line is emacs — useful, keep. But no visual feedback like monaco.
- Home/End freed from global nav — good, but
ctrl+g/ctrl+alt+gare less discoverable. Consider<leader>g/<leader>G.
Patch Dependency Graph
patch-selectall (always-on)
├── SA1: input_line_home ctrl+a → home
├── SA1b: messages_first/last freed from home/end
├── SA1c: messages_page_up/down freed from pageup/pagedown
├── SA2: select-all action (no-op on v1.17.4+)
├── SA3: input_select_all ctrl+a, input_copy_selection
├── SA4: prompt handlers (select-all, copy, home/end, pgup/pgdn)
├── SA5: ESC clears selection
└── SA6: dynamic interrupt label
patch-background-keybind (DISABLED — tui.json handles it)
├── session_background: ctrl+b → ctrl+o
└── input_move_left: left,ctrl+b → left
tui.json (runtime, no patch needed)
├── session_background: ctrl+o
├── input_move_left: left
├── app_exit: <leader>q
└── leader: ctrl+x
Build Status
patch-background-keybinddisabled by default (INCLUDE_BACKGROUND_KEYBIND=false)- Re-enablable with
--background-keybindflag - Current build:
1.17.7-dev-patched-380ddd193b(still has old patch) - Next build: will skip background_keybind, tui.json handles rebinding
Metadata
Metadata
Assignees
Labels
needs:complianceThis means the issue will auto-close after 2 hours.This means the issue will auto-close after 2 hours.
Activity
github-actions commentedon Jun 17, 2026
This issue doesn't fully meet our contributing guidelines.
What needs to be fixed:
[FEATURE]:), or QuestionPlease edit this issue to address the above within 2 hours, or it will be automatically closed.
For keybind-related issues, please also check our pinned keybinds documentation: #4997
If you believe this was flagged incorrectly, please let a maintainer know.