[PR #6778] feat(tui): add configurable readline-style text transformations #12100

Open
opened 2026-02-16 18:17:02 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/6778

State: open
Merged: No


Summary

Adds missing Emacs/Readline-style text editing shortcuts to the TUI (terminal) prompt input, improving text editing efficiency in the terminal.

Closes #9234.

Changes

New shortcuts

Shortcut Action
alt+u Uppercase word from cursor
alt+l Lowercase word from cursor
alt+c Capitalize word from cursor
ctrl+y Yank (paste) last killed text
ctrl+t Transpose characters (requires rebind)

User-facing behavior

Case transformations (alt+u, alt+l, alt+c)

  • When cursor is on a word character: transforms the word starting from cursor position
  • When cursor is on whitespace: transforms the next word
  • When no next word exists: transforms the previous word
  • With text selection: transforms the selected text
  • After transformation: cursor moves to end of the transformed word

Kill ring support (ctrl+y)

  • The ctrl+k, ctrl+u, ctrl+w, and alt+d delete commands now save deleted text to a kill buffer
  • ctrl+y inserts the contents of the kill buffer at the current cursor position
  • Simple single-entry buffer (full kill ring can be added later)

Transpose characters (ctrl+t)

  • Swaps the character under the cursor with the character immediately preceding it
  • At beginning of line: swaps first two characters
  • At end of line: swaps last two characters
  • Cursor advances one position to the right (unless already at end of line)

Configuration

All new shortcuts are configurable via opencode.json:

{
  "keybinds": {
    "input_lowercase_word": "alt+l",
    "input_uppercase_word": "alt+u",
    "input_capitalize_word": "alt+c",
    "input_yank": "ctrl+y",
    "input_transpose_characters": "ctrl+t"
  }
}

Note on ctrl+t conflict:
By default, ctrl+t is bound to variant_cycle (cycle model variants). To use ctrl+t for transpose characters, you can rebind, e.g.:

{
  "keybinds": {
    "variant_cycle": "<leader>v",
    "input_transpose_characters": "ctrl+t"
  }
}

Technical details

  • TUI uses OpenTUI's TextareaRenderable which has limited built-in actions
  • Implementation adds helper functions for word boundary detection matching Readline behavior
  • Tests added for word boundary detection and transformation functions

Files

  • packages/opencode/src/config/config.ts - Added keybind schema entries
  • packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx - Implemented shortcuts
  • packages/web/src/content/docs/keybinds.mdx - Updated documentation
  • packages/sdk/js/src/v2/gen/types.gen.ts - Regenerated from schema
  • packages/opencode/test/tui/text-transform.test.ts - Added 17 tests
**Original Pull Request:** https://github.com/anomalyco/opencode/pull/6778 **State:** open **Merged:** No --- ## Summary Adds missing Emacs/Readline-style text editing shortcuts to the TUI (terminal) prompt input, improving text editing efficiency in the terminal. Closes #9234. ## Changes ### New shortcuts | Shortcut | Action | |----------|--------| | `alt+u` | Uppercase word from cursor | | `alt+l` | Lowercase word from cursor | | `alt+c` | Capitalize word from cursor | | `ctrl+y` | Yank (paste) last killed text | | `ctrl+t` | Transpose characters (requires rebind) | ### User-facing behavior **Case transformations (`alt+u`, `alt+l`, `alt+c`)** - When cursor is on a word character: transforms the word starting from cursor position - When cursor is on whitespace: transforms the next word - When no next word exists: transforms the previous word - With text selection: transforms the selected text - After transformation: cursor moves to end of the transformed word **Kill ring support (`ctrl+y`)** - The `ctrl+k`, `ctrl+u`, `ctrl+w`, and `alt+d` delete commands now save deleted text to a kill buffer - `ctrl+y` inserts the contents of the kill buffer at the current cursor position - Simple single-entry buffer (full kill ring can be added later) **Transpose characters (`ctrl+t`)** - Swaps the character under the cursor with the character immediately preceding it - At beginning of line: swaps first two characters - At end of line: swaps last two characters - Cursor advances one position to the right (unless already at end of line) ### Configuration All new shortcuts are configurable via `opencode.json`: ```json { "keybinds": { "input_lowercase_word": "alt+l", "input_uppercase_word": "alt+u", "input_capitalize_word": "alt+c", "input_yank": "ctrl+y", "input_transpose_characters": "ctrl+t" } } ``` **Note on `ctrl+t` conflict:** By default, `ctrl+t` is bound to `variant_cycle` (cycle model variants). To use `ctrl+t` for transpose characters, you can rebind, e.g.: ```json { "keybinds": { "variant_cycle": "<leader>v", "input_transpose_characters": "ctrl+t" } } ``` ## Technical details - TUI uses OpenTUI's `TextareaRenderable` which has limited built-in actions - Implementation adds helper functions for word boundary detection matching Readline behavior - Tests added for word boundary detection and transformation functions ## Files - `packages/opencode/src/config/config.ts` - Added keybind schema entries - `packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx` - Implemented shortcuts - `packages/web/src/content/docs/keybinds.mdx` - Updated documentation - `packages/sdk/js/src/v2/gen/types.gen.ts` - Regenerated from schema - `packages/opencode/test/tui/text-transform.test.ts` - Added 17 tests
yindo added the pull-request label 2026-02-16 18:17:02 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#12100