[FEATURE] A standard text-editing model for the prompt input: selection, cut/copy/paste, word navigation (built on OSC 52, bracketed paste, kitty keyboard protocol)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Preflight
I searched existing issues. The closest ones, as they looked when I checked:
- #23396 — Shift+Arrow selection, Ctrl+X/C/V (closed as duplicate)
- #27561 — click-to-position, selection, standard editing (closed)
- #63058 — word-jump cursor actions (closed as not planned / stale)
- #68935 — shortcut to copy the input buffer (tracked in the meta issue #81472)
These keep being filed and closed one key at a time. This request is different in scope: it asks for one coherent editing model (selection + clipboard + navigation), says exactly which terminal protocol carries each piece, and points out that most of the machinery already exists elsewhere in Claude Code. If it should be folded into an existing canonical issue, please point me to it.
Problem
The prompt is the one text field every Claude Code user types into for hours a day, and it is the only text field on my machine where I cannot select a piece of text, cut it, copy it, or paste over it.
| Operation | Today | Expected (HTML <textarea>, Far Manager / far2l) |
|---|---|---|
| Select by character / line | ✗ | Shift+←/→/↑/↓ |
| Select by word | ✗ | Ctrl+Shift+←/→ |
| Select to line start / end | ✗ | Shift+Home/End |
| Select all | ✗ (Ctrl+A = line start) | Ctrl+A / Cmd+A |
| Move by word | Alt+B/F only (macOS: needs "Option as Meta") | Ctrl+←/→, Alt+←/→ |
| Cut / copy selection | ✗ (only the kill-ring: Ctrl+K/U/W) | Ctrl+X / Ctrl+C / Ctrl+Insert / Shift+Delete / Cmd+X/C |
| Paste over a selection | ✗ | Ctrl+V / Shift+Insert / Cmd+V |
| Typing / Backspace replaces or deletes the selection | ✗ | yes |
| Delete word right | Alt+D only | Ctrl+Delete |
The pieces already exist, just not in the prompt in normal mode:
- Vim mode has a selection (
v/V,y,d,p) — so the input widget already has selection state. - Fullscreen mode has
selection:extendLeft/Right/Up/Down/LineStart/LineEndonShift+arrows/Shift+Home/End, aselectionBgtheme token, andselection:copy(Cmd+C/Ctrl+Shift+C) that reaches the system clipboard — evidently via OSC 52. - There is a kill-ring (
Ctrl+K/U/W,Ctrl+Y,Alt+Y),/copy, andchat:undo.
But the Chat context in keybindings.json exposes no cursor, selection or clipboard actions, so none of this can be reached or remapped (cf. #63058). Three unrelated selection models, none of them available to a user in default mode.
There are also deliberate conflicts that a proposal has to resolve rather than ignore:
Ctrl+Vischat:imagePaste.Ctrl+Xis a chord prefix (Ctrl+X Ctrl+E,Ctrl+X Enter, …).Ctrl+A/Ctrl+Eare readline line-start/end.Shift+arrowsandCtrl+Home/Endare already used by theScrollcontext in fullscreen.
Why this is feasible now: what the terminal can actually carry
1. Selection and word navigation need no protocol negotiation at all. The xterm modifier scheme (parameter = 1 + Shift·1 + Alt·2 + Ctrl·4 + Meta·8) is old and widely implemented:
Shift+Left ESC [ 1 ; 2 D Ctrl+Left ESC [ 1 ; 5 D
Ctrl+Shift+Left ESC [ 1 ; 6 D Shift+End ESC [ 1 ; 2 F
Ctrl+Insert ESC [ 2 ; 5 ~ Shift+Insert ESC [ 2 ; 2 ~
Shift+Delete ESC [ 3 ; 2 ~
Phase 1 below is therefore doable with today's input parser, on almost every terminal.
2. What the legacy encoding cannot express — Ctrl+Shift+<letter> (arrives as plain Ctrl+<letter>), Cmd/Super+<key>, Ctrl+Enter, and Ctrl shortcuts under non-Latin layouts — is exactly what the kitty keyboard protocol fixes: push flags CSI > 5 u (disambiguate + report alternate keys), query CSI ? u, pop CSI < u; key events arrive as CSI code ; modifiers u, with super as bit 8. "Report alternate keys" delivers the base-layout key, which is what makes Ctrl+С on a Russian layout behave as Ctrl+C. Support is broad (kitty, Ghostty, WezTerm, iTerm2, Alacritty, foot, Windows Terminal, xterm.js, …), and detection is CSI ? u followed by DA1. Claude Code already uses it (the docs describe kitty-based layout matching and Super detection), and upstream Ink exposes it (render(..., {kittyKeyboard}), key.super). Fallbacks: xterm modifyOtherKeys (CSI > 4 ; 2 m), and on Windows win32-input-mode (CSI ? 9001 h) which delivers full KEY_EVENT_RECORDs from ConPTY / Windows Terminal.
3. Writing to the clipboard = OSC 52: ESC ] 52 ; c ; <base64> ST (p for PRIMARY). Widely supported (kitty, iTerm2, WezTerm, Alacritty, foot, Konsole, Windows Terminal, tmux, far2l …), not by GNOME Terminal/VTE or macOS Terminal.app. tmux ignores applications' OSC 52 under its default set-clipboard external; it needs set-clipboard on or passthrough. Claude Code already emits OSC 52 for /copy and selection:copy, so what remains is making it reliable (see "Known clipboard bugs" below) and using it from the prompt. Native tools (pbcopy, wl-copy, xclip, clip.exe) are the local fallback; over SSH only OSC 52 works.
4. Pasting = bracketed paste, and this is the easy half. With CSI ? 2004 h the terminal wraps pastes in ESC[200~ … ESC[201~. Every terminal-initiated paste (Ctrl+Shift+V, Cmd+V, right-click, middle-click, usually Shift+Insert) arrives this way, with no permission prompt, no clipboard read, and it works over SSH. Ink's usePaste does exactly this.
5. Application-initiated paste (the app's own Ctrl+V) is the hard half: the app must read the clipboard. Options: (a) native tools on a local session (already done for images); (b) kitty's OSC 5522 type=read (permission-gated; probe with CSI ? 5522 $ p); (c) OSC 52 query ? — usually disabled or gated, so it must have a short timeout. Proposed order is local native → 5522 → 52-query → a one-line hint: "use your terminal's paste (Ctrl+Shift+V / Cmd+V)". Nothing else in the design depends on this half.
6. far2l is the UX reference — and its terminal extensions are not far2l-only. far2l ships a layered set of TTY backends (TTY, TTY|X, TTY|Xi, TTY|k for the kitty protocol, TTY|F for its own extension protocol) precisely because no single terminal feature is guaranteed: it probes what is available and degrades gracefully. Far/far2l editing (Shift+arrows selection, Ctrl+Ins/Shift+Ins/Shift+Del, Ctrl+←/→) is the CUA layout, which never conflicts with terminal signals.
The far2l terminal extensions (a private APC channel that carries full key events and the clipboard) are also implemented by other software:
- KiTTY (the PuTTY fork at https://www.9bis.net/kitty/ — unrelated to Kovid Goyal's kitty, despite the name) and other PuTTY forks;
- f4 (https://github.com/unxed/f4), a Go TUI file manager that speaks the extensions with its host terminal and also answers the handshake for programs run in its built-in terminal — so Claude Code launched there sees an extension-capable terminal.
I am not asking for a bespoke integration in phases 1–3. I am asking for the same probe-and-degrade discipline, and that the existing OSC 52 / bracketed-paste / kitty paths keep working in these terminals. Treating the extension channel as one more optional capability (a possible phase 4) would give their users desktop-grade keys and clipboard even over a remote connection.
Proposed solution
Phase 1 — one selection model in the prompt (no negotiation).
- Anchor + cursor in the input buffer; render with the existing
selectionBg. Share the model with vim VISUAL and, where sensible, withselection:*. - Textarea semantics: typing, Backspace, Delete and paste replace/delete the selection; unshifted
←/→collapse it to its start/end;Shift+↑/↓preserves the visual column in multi-line input. - New bindable actions in the
Chatcontext, e.g.chat:cursorWordLeft/Right,chat:selectLeft/Right/Up/Down,chat:selectWordLeft/Right,chat:selectLineStart/End,chat:selectAll,chat:copy,chat:cut,chat:paste,chat:deleteWordRight— with defaults on the non-conflicting keys above (Shift/Ctrl+arrows,Shift+Home/End,Ctrl+Insert,Shift+Insert,Shift+Delete,Ctrl+Delete). - Conflicts, resolved deliberately:
Ctrl+Ccopies only while a selection exists; otherwise it keeps today's interrupt behaviour (the convention in Windows Terminal, VS Code, JetBrains).Ctrl+Xcuts only while a selection exists; otherwise it stays the chord prefix.Ctrl+V: image if the clipboard has one, text otherwise.Ctrl+Astays line-start by default; select-all isCmd+A/Ctrl+Shift+Awhere the terminal can report them, andCtrl+Ain an opt-in "standard" flavour (e.g.editorMode: "standard").- The prompt must take precedence over
ScrollforShift+arrowswhile it has focus. - A
[Pasted text #N]placeholder must be atomic under selection, and copying it must copy the underlying content.
Phase 2 — clipboard and keyboard capability layer.
- Push kitty flags
1|4on start; pop them on exit and around every child process (Ctrl+Gexternal editor,!shell mode, suspend), or$EDITORwill receiveCSI uit cannot parse. - Probe with
CSI ? u+ DA1;Cmd+C/X/V/A/Zviasuper;modifyOtherKeysandwin32-input-modefallbacks. - The clipboard read/write layering from points 3–5.
- Pasted text replaces the selection, and one paste is one undo step.
Phase 3 — mouse in the prompt (fullscreen only, where mouse reporting is already on): click to position, drag to select, double-click for a word, triple-click for a line, Shift+click to extend. In non-fullscreen mode the terminal keeps the mouse.
Known clipboard bugs this should not step on
#66098 (OSC 52 corrupts multi-byte UTF-8, e.g. Cyrillic), #79482 (/copy writes Latin-1), #57654 (OSC 52 should set both CLIPBOARD and PRIMARY), #63061 (OSC 52 regression under tmux), #67576 (OSC 52 does not reach RDP clipboard redirection), #73098 (vim mode: unbracketed paste turns newlines into j). Most of them are fixed by one UTF-8-correct OSC 52 writer.
Alternatives considered
- Vim mode — great for those who use it; not a substitute for muscle memory built on every other text field.
Ctrl+Gexternal editor — heavyweight for a one-word fix.- Terminal-native selection — unreliable: the prompt sits under an alt-screen or mouse capture, the
>gutter and hard wraps come along (#81472). - Kill-ring only — deletes, doesn't select or copy, and can't paste from outside.
- Minimum fallback if the full model is too big: at least expose
chat:cursorWordLeft/Rightandchat:deleteWordRightas bindable actions and makeCtrl+←/→work by default.
Acceptance tests
The sequences above are deterministic, so this can be tested headlessly by feeding bytes into the input component and asserting buffer, selection and emitted OSC 52:
ESC[1;6D× 2 selects two words to the left.ESC[200~foo\nbar ESC[201~over a selection replaces it, inserts the newline literally, doesn't submit, and is undone in one step.ESC[99;5u(Ctrl+C) with a selection emitsESC]52;c;<base64(utf-8)>; without one, it interrupts as today.- Cyrillic text round-trips through copy/paste.
- Kitty flags are popped before spawning
$EDITORand restored afterwards.
Priority
High — significant impact on productivity. It is a daily-friction item for everyone who edits multi-line prompts.
Feature category
Interactive mode (TUI)
References
- xterm control sequences (OSC 52, DECSET 2004, modifyOtherKeys, modifier encoding): https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
- kitty keyboard protocol: https://sw.kovidgoyal.net/kitty/keyboard-protocol/
- kitty clipboard protocol (OSC 5522): https://sw.kovidgoyal.net/kitty/clipboard/
- win32-input-mode: https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
- tmux and OSC 52 (
set-clipboard): https://github.com/tmux/tmux/wiki/Clipboard - OSC 52 terminal support table: https://github.com/ojroques/vim-oscyank
- far2l (TTY backends, OSC 52 notes, terminal extensions): https://github.com/elfmz/far2l
- KiTTY, a PuTTY fork with far2l terminal extensions support: https://www.9bis.net/kitty/
- f4, a TUI file manager that speaks the far2l terminal extensions (layered probe-and-degrade in Go, see
docs/TTYX.md): https://github.com/unxed/f4 - Ink
useInput/usePaste/kittyKeyboard: https://github.com/vadimdemedes/ink - Related: #23396, #27561, #63058, #81472, #42712
Priority
Medium - Would be very helpful
Feature Category
CLI commands and flags
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗