mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
tui: preserve kill buffer across submit and slash-command clears (#12006)
## Problem Before this change, composer paths that cleared the textarea after submit or slash-command dispatch also cleared the textarea kill buffer. That meant a user could `Ctrl+K` part of a draft, trigger a composer action that cleared the visible draft, and then lose the ability to `Ctrl+Y` the killed text back. This was especially awkward for workflows where the user wants to temporarily remove text, run a composer action such as changing reasoning level or dispatching a slash command, and then restore the killed text into the now-empty draft. ## Mental model This change separates visible draft state from editing-history state. The visible draft includes the current textarea contents and text elements that should be cleared when the composer submits or dispatches a command. The kill buffer is different: it represents the most recent killed text and should survive those composer-driven clears so the user can still yank it back afterward. After this change, submit and slash-command dispatch still clear the visible textarea contents, but they no longer erase the most recent kill. ## Non-goals This does not implement a multi-entry kill ring or change the semantics of `Ctrl+K` and `Ctrl+Y` beyond preserving the existing yank target across these clears. It also does not change how submit, slash-command parsing, prompt expansion, or attachment handling work, except that those flows no longer discard the textarea kill buffer as a side effect of clearing the draft. ## Tradeoffs The main tradeoff is that clearing the visible textarea is no longer equivalent to fully resetting all editing state. That is intentional here, because submit and slash-command dispatch are composer actions, not requests to forget the user's most recent kill. The benefit is better editing continuity. The cost is that callers must understand that full-buffer replacement resets visible draft state but not the kill buffer. ## Architecture The behavioral change is in `TextArea`: full-buffer replacement now rebuilds text and elements without clearing `kill_buffer`. `ChatComposer` already clears the textarea after successful submit and slash-command dispatch by calling into those textarea replacement paths. With this change, those existing composer flows inherit the new behavior automatically: the visible draft is cleared, but the last killed text remains available for `Ctrl+Y`. The tests cover both layers: - `TextArea` verifies that the kill buffer survives full-buffer replacement. - `ChatComposer` verifies that it survives submit. - `ChatComposer` also verifies that it survives slash-command dispatch. ## Observability There is no dedicated logging for kill-buffer preservation. The most direct way to reason about the behavior is to inspect textarea-wide replacement paths and confirm whether they treat the kill buffer as visible-buffer state or as editing-history state. If this regresses in the future, the likely failure mode is simple and user-visible: `Ctrl+Y` stops restoring text after submit or slash-command clears even though ordinary kill/yank still works within a single uninterrupted draft. ## Tests Added focused regression coverage for the new contract: - `kill_buffer_persists_across_set_text` - `kill_buffer_persists_after_submit` - `kill_buffer_persists_after_slash_command_dispatch` Local verification: - `just fmt` - `cargo test -p codex-tui` --------- Co-authored-by: Josh McKinney <joshka@openai.com>
This commit is contained in:
@@ -118,6 +118,12 @@ the input starts with `!` (shell command).
|
||||
The same preparation path is reused for slash commands with arguments (for example `/plan` and
|
||||
`/review`) so pasted content and text elements are preserved when extracting args.
|
||||
|
||||
The composer also treats the textarea kill buffer as separate editing state from the visible draft.
|
||||
After submit or slash-command dispatch clears the textarea, the most recent `Ctrl+K` payload is
|
||||
still available for `Ctrl+Y`. This supports flows where a user kills part of a draft, runs a
|
||||
composer action such as changing reasoning level, and then yanks that text back into the cleared
|
||||
draft.
|
||||
|
||||
### Numeric auto-submit path
|
||||
|
||||
When the slash popup is open and the first line matches a numeric-only custom prompt with
|
||||
|
||||
Reference in New Issue
Block a user