Skip to content

feat(tui): add Vim normal-mode C binding to change to end of line #24238

@abatilo

Description

@abatilo

What variant of Codex are you using?

CLI (codex-tui).

What feature would you like to see?

Add a Vim normal-mode C binding to the composer. In Vim, C is equivalent to c$: delete from the cursor to the end of the line, then enter insert mode. Codex already implements the parallel D (delete to end of line) and Y (yank line) shortcuts; C is the natural missing piece for users with Vim muscle memory.

Additional information

I can't open a PR directly (outside collaborators are restricted on this repo), so the branch and commit live on my fork:

Happy to rework the change if a maintainer wants to pick it up; treat the linked branch as a reference implementation.

Implementation summary

Mirrors the existing delete_to_line_end (D) wiring across the configurable keymap stack:

  • codex-rs/config/src/tui_keymap.rs — adds change_to_line_end: Option<KeybindingsSpec> to TuiVimNormalKeymap.
  • codex-rs/tui/src/keymap.rs — adds the runtime field, the resolve_local! line, default bindings [shift-c, plain('C')], and a validate_unique entry.
  • codex-rs/tui/src/bottom_pane/textarea.rs — adds the handler in handle_vim_normal (calls kill_to_end_of_line() then switches to VimMode::Insert) and two unit tests covering both default bindings.
  • codex-rs/tui/src/keymap_setup/actions.rs — exposes the action in the keymap picker (catalog entry, binding_slot, bindings_for_action).
  • codex-rs/core/config.schema.json — regenerated via just write-config-schema.
  • 5 insta snapshots — picker action counts (93→94 total, 34→35 Vim).

Total diff: 10 files, +63 / -6.

Default bindings

shift-c and plain C, matching the cross-terminal shift-reporting pattern used by D, Y, A, I, and O in this codebase (see commit eb2275a feat(tui): support shift-letter vim bindings across terminal variants).

Validation

  • cargo test -p codex-tui --lib -- vim — all 43 vim tests pass, including the two new ones (vim_shift_c_changes_to_line_end_and_enters_insert_mode and vim_uppercase_c_changes_to_line_end_with_shift_only_binding).
  • cargo test -p codex-tui --lib -- keymap_setup — 157 keymap/picker tests pass after snapshot refresh.
  • just write-config-schema produces no further diff (manual edits matched the generator).
  • just fmt and just fix -p codex-tui clean.

Behavior note

This implementation reuses the existing kill_to_end_of_line() helper, which deletes the trailing newline when the cursor is already at EOL. The D binding already inherits this quirk; C now matches D for parity. Real Vim's C at EOL is a no-op (just enters insert mode), so if D's EOL behavior is ever aligned with upstream Vim, C should be aligned in lockstep.

Not in scope

A full c operator (so cw, cc, c$, etc. all work) is a separate change — it would also need a VimOperator::Change variant alongside the existing Delete and Yank operators. Happy to follow up on that if there's interest.

Metadata

Metadata

Assignees

Labels

TUIIssues related to the terminal user interface: text input, menus and dialogs, and terminal displayenhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions