Skip to content

tui: preserve kill buffer across submit and slash-command clears#12006

Merged
joshka-oai merged 2 commits intomainfrom
re/ctrl-k
Mar 3, 2026
Merged

tui: preserve kill buffer across submit and slash-command clears#12006
joshka-oai merged 2 commits intomainfrom
re/ctrl-k

Conversation

@rakan-oai
Copy link
Copy Markdown
Contributor

@rakan-oai rakan-oai commented Feb 17, 2026

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
@rakan-oai rakan-oai requested a review from joshka-oai February 17, 2026 17:37
@rakan-oai
Copy link
Copy Markdown
Contributor Author

This is so that we can kill the contents of a prompt, run something else (e.g. change the model reasoning level), and then paste that prompt back in.

@etraut-openai etraut-openai added the oai PRs contributed by OpenAI employees label Feb 17, 2026
Document that full-buffer textarea resets preserve the kill buffer so
Ctrl+Y still works after submit and slash-command clears.

Update the textarea and composer narrative docs to make the new
editing-state contract explicit for reviewers and future callers.
@joshka-oai
Copy link
Copy Markdown
Contributor

Added a docs follow-up on this branch to make the new kill-buffer contract explicit in the TUI docs and rustdoc.

I also updated the PR description/main comment with more detail about the behavior change, motivation, and test coverage.

Both the docs changes and the updated PR description were Codex-generated, then reviewed/edited in this thread.

@joshka-oai joshka-oai enabled auto-merge (squash) March 3, 2026 00:56
@joshka-oai joshka-oai merged commit 56cc2c7 into main Mar 3, 2026
71 of 75 checks passed
@joshka-oai joshka-oai deleted the re/ctrl-k branch March 3, 2026 02:06
@github-actions github-actions bot locked and limited conversation to collaborators Mar 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

oai PRs contributed by OpenAI employees

3 participants