feat(tui): add Vim normal-mode `C` binding to change to end of line
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:
- Branch: https://github.com/abatilo/codex/tree/feat/tui-vim-change-to-line-end
- Commit: https://github.com/abatilo/codex/commit/858312f20b288a267f3bd66eff7cfcd08ca946cf
- Compare view: https://github.com/openai/codex/compare/main...abatilo:codex:feat/tui-vim-change-to-line-end
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— addschange_to_line_end: Option<KeybindingsSpec>toTuiVimNormalKeymap.codex-rs/tui/src/keymap.rs— adds the runtime field, theresolve_local!line, default bindings[shift-c, plain('C')], and avalidate_uniqueentry.codex-rs/tui/src/bottom_pane/textarea.rs— adds the handler inhandle_vim_normal(callskill_to_end_of_line()then switches toVimMode::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 viajust 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 eb2275a64a 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_modeandvim_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-schemaproduces no further diff (manual edits matched the generator).just fmtandjust fix -p codex-tuiclean.
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.