Skip to content

fix(tui): restore cancelled prompt on ctrl-c#1764

Closed
nightt5879 wants to merge 5 commits into
Hmbown:mainfrom
nightt5879:nightt5879/restore-cancelled-prompt
Closed

fix(tui): restore cancelled prompt on ctrl-c#1764
nightt5879 wants to merge 5 commits into
Hmbown:mainfrom
nightt5879:nightt5879/restore-cancelled-prompt

Conversation

@nightt5879

@nightt5879 nightt5879 commented May 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Record the last prompt accepted into an active request.
  • Restore it into an empty composer when Ctrl+C cancels an active request, with the cursor at the end.
  • Preserve any draft the user typed while the request was in flight.
  • Reuse the same local cancel state for Ctrl+C/Esc and suppress late stream events after cancellation, including the race where Ctrl+C lands before TurnStarted resets the engine token.
  • Stabilize Windows test isolation for config/home/git-root/pandoc cases so the full workspace test suite passes on this checkout.
  • Remove two needless returns in the Windows keyboard enhancement helper so workspace clippy passes.

Root cause: submitting a prompt clears the composer, while the active-turn cancel path only stopped the request and updated status text. It did not keep a recoverable copy of the submitted input, and queued stream events could still render after the UI had returned focus to the composer.

Testing

  • cargo fmt --all -- --check
  • cargo build
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test -p deepseek-tui --bin deepseek-tui restore_last_submitted_prompt
  • cargo test -p deepseek-tui --bin deepseek-tui dispatch_user_message_records_prompt_for_cancel_restore
  • cargo test -p deepseek-tui --bin deepseek-tui ctrl_c_disposition
  • cargo test -p deepseek-tui --bin deepseek-tui local_cancel_marks_late_stream_events_for_suppression
  • cargo test --workspace --all-features
  • Manual TUI verification on Windows with deepseek --provider deepseek --model deepseek-v4-flash
    • Ctrl+C during streaming interrupts the turn, restores the submitted prompt into the composer, and leaves the status as Request cancelled.

Checklist

  • Updated docs or comments as needed
  • Added or updated tests where relevant
  • Verified TUI behavior manually if UI changes

Closes #1757

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a feature to restore the last submitted prompt to the composer when a request is cancelled via Ctrl+C. It adds a last_submitted_prompt field to the App state, updates it during message dispatch and steering, and provides a restoration method with accompanying tests. Feedback suggests using more idiomatic Rust by applying as_deref instead of cloned when retrieving the prompt and recommends adding test coverage for the steer_user_message function.

Comment thread crates/tui/src/tui/app.rs Outdated
Comment thread crates/tui/src/tui/ui.rs
@nightt5879

Copy link
Copy Markdown
Contributor Author

Manual verification passed on Windows.

Verified with:

deepseek --provider deepseek --model deepseek-v4-flash

Result:

  • Ctrl+C interrupts the active streaming turn.
  • The previously submitted prompt is restored into the composer.
  • The partial assistant output is marked [interrupted].
  • The status line shows Request cancelled.
  • The TUI no longer keeps streaming new output after cancellation.
image

@nightt5879

Copy link
Copy Markdown
Contributor Author

Follow-up commit bc4b3b5 fixes the Windows checkout test failures that were previously listed in the PR body.

What changed:

  • Isolated App::new//change tests from real user settings and API-key environment.
  • Stopped filesystem-root .git markers such as C:\.git\HEAD from making unrelated temp workspaces look like the same repo.
  • Stabilized the Windows pandoc child-process profile environment so getXdgDirectory:sHGetFolderPath no longer flakes during the full suite.
  • Isolated skills/project-context tests from real user global files, and renamed the skill_install integration test target to avoid Windows UAC installer-name detection (os error 740).

Verified after the commit:

  • cargo fmt --all -- --check
  • cargo build
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-features

@nightt5879

Copy link
Copy Markdown
Contributor Author

Follow-up commit d34c031 addresses both Gemini review comments:

  • Replaced the prompt-restore lookup with the suggested as_deref() pattern, then assign with prompt.to_string().
  • Added steer_user_message_records_prompt_for_cancel_restore so the steer path has the same last_submitted_prompt coverage as normal dispatch.

Verified after the change:

  • cargo fmt --all -- --check
  • git diff --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test -p deepseek-tui --bin deepseek-tui restore_last_submitted_prompt
  • cargo test -p deepseek-tui --bin deepseek-tui dispatch_user_message_records_prompt_for_cancel_restore
  • cargo test -p deepseek-tui --bin deepseek-tui steer_user_message_records_prompt_for_cancel_restore
  • cargo test --workspace --all-features

@nightt5879 nightt5879 marked this pull request as ready for review May 18, 2026 09:48

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d34c031c47

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/tui/src/project_context.rs Outdated

@aboimpinto aboimpinto left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on this — focused, well-tested, and hits the right behaviour. A few observations:

✅ What Works Well

  • Recording the last prompt in dispatch_user_message / steer_user_message is the right place — it captures exactly what was sent, not what's in the composer at cancel time.
  • Only restores into an empty composer — this is the correct edge-case handling. If the user started typing something new while waiting, their draft is preserved instead of being overwritten by the old prompt. This directly addresses @superzmy's concern from the issue discussion.
  • Race condition fix — the tokio::select! with biased ordering on the cancel token before create_message_stream is clean. Prevents the ugly case where Ctrl+C lands before TurnStarted resets the engine token.
  • Late stream event suppressionsuppress_stream_events_until_turn_complete is a good safeguard. Prevents stale deltas from leaking into the UI after the user has already cancelled and moved on.
  • Test coverage — 6 new test functions covering the core paths: prompt recording, Ctrl+C disposition, late event suppression, and the Windows isolation fixes.

💡 One Thought (non-blocking)

The ESC vs Ctrl+C differentiation is now implicit: ESC cancels but doesn't restore (the composer keeps whatever draft the user had), while Ctrl+C cancels AND restores the last sent prompt into an empty composer. This is a clean split and aligns with what we discussed in #1757. Might be worth a one-line note in the keybindings docs at some point so users discover it.

✅ Verified

  • Gates pass (fmt, clippy, build, workspace tests)
  • Manual TUI verification on Windows confirms the described behaviour
  • No regression risk — the change is scoped to the cancel path

Nice work @nightt5879! 🚀

@Hmbown Hmbown mentioned this pull request May 20, 2026
11 tasks
@Hmbown

Hmbown commented May 21, 2026

Copy link
Copy Markdown
Owner

Thanks for the Ctrl-C prompt-restore fix. This was harvested into v0.8.40 release PR #1823 as commits 4a03f83 and 710505d, and #1823 is now CI-green. Closing as superseded by the release branch; thank you for protecting interrupted drafts.

@Hmbown Hmbown closed this May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ctrl+C cancel and reinput the text into Composer

3 participants