Skip to content

Prompt input keybind analysis: hybrid emacs/monaco cheatsheet + patch inventory #32721

Closed as not planned

Description

@lkonga

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+b is captured by zellij → never reaches opencode
  • Only ctrl+b passthrough sequences work (e.g., ctrl+b then z for zoom)
  • This is why input_move_left and session_background needed remapping

When NOT inside zellij (plain alacritty):

  • ctrl+b would work for both, but tui.json overrides make it consistent
  • No zellij passthrough needed

Inconsistencies & Future Iteration Ideas

  1. ctrl+e still emacs, but ctrl+a is monaco — asymmetric. Consider remapping ctrl+e → End only, or keep both for muscle memory.
  2. ctrl+u deletes to line start (emacs), not universal-arg — fine for terminal, surprising for emacs users.
  3. ctrl+v paste (not emacs page-down) — already overridden upstream, matches terminal conventions.
  4. ctrl+a = select-all + auto-copy — unusual. Monaco selects but doesn't copy. Consider making copy optional.
  5. PageUp/PageDown local to prompt — good for long prompts, but users might expect message scrolling. Consider shift+PageUp for message scroll.
  6. No ctrl+z undo — upstream has no prompt undo. Future patch candidate.
  7. No ctrl+y redo — same, future candidate.
  8. ctrl+k kill-line is emacs — useful, keep. But no visual feedback like monaco.
  9. Home/End freed from global nav — good, but ctrl+g / ctrl+alt+g are 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-keybind disabled by default (INCLUDE_BACKGROUND_KEYBIND=false)
  • Re-enablable with --background-keybind flag
  • Current build: 1.17.7-dev-patched-380ddd193b (still has old patch)
  • Next build: will skip background_keybind, tui.json handles rebinding

Activity

  1. github-actions commented on Jun 17, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • No issue template was used. All issues must use one of the three templates: Bug Report, Feature Request (title starting with [FEATURE]:), or Question
    • This appears to be personal patch documentation/a cheatsheet rather than a bug report, feature request, or question — it does not fit any of the supported issue types

    Please 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

needs:complianceThis means the issue will auto-close after 2 hours.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions