Skip to content

fix(ui): Clear input prompt on Escape key press#13335

Merged
SandyTao520 merged 5 commits intomainfrom
st/fix/clear-input-on-escape
Nov 19, 2025
Merged

fix(ui): Clear input prompt on Escape key press#13335
SandyTao520 merged 5 commits intomainfrom
st/fix/clear-input-on-escape

Conversation

@SandyTao520
Copy link
Copy Markdown
Contributor

TLDR

This PR fixes a UX regression where pressing the Escape key to cancel a request would inadvertently restore the previous user prompt to the input buffer. This change ensures that pressing Escape clears the input field, while retaining the behavior of restoring the prompt for system-initiated cancellations like context window overflows.

Dive Deeper

The regression was introduced in #10719 ("feat(sessions): add resuming to geminiChat").

That PR updated the cancelHandlerRef in AppContainer.tsx to automatically populate the input buffer with the last user message whenever a request was cancelled. The intention was to help users recover their prompt if a request failed or was cancelled due to system limits (like context overflow). However, this logic was applied unconditionally to all cancellation events, including when the user explicitly pressed the Escape key, leading to the frustrating experience of having to clear the prompt manually.

This PR refactors the onCancelSubmit handler to accept a shouldRestorePrompt flag:

  • Escape Key: Calls onCancelSubmit(false), ensuring the input is cleared.
  • System Cancellations: Calls onCancelSubmit(true) (or defaults to true), preserving the user's prompt for editing.

Reviewer Test Plan

  1. Escape Key:

    • Send a long prompt to the CLI.
    • While it is streaming the response, press Escape.
    • Expected: The request cancels, and the input field is empty.
  2. Context Overflow:

    • Trigger a context window overflow event (if feasible).
    • Expected: The request cancels, and the input field contains the previous prompt.

Testing Matrix

🍏 🪟 🐧
npm run
npx
Docker
Podman - -
Seatbelt - -

Linked issues / bugs

Resolves #13306

@SandyTao520 SandyTao520 requested a review from a team as a code owner November 18, 2025 21:54
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @SandyTao520, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a user experience issue in the CLI where pressing the Escape key during an active request would inadvertently repopulate the input field with the last prompt. The changes introduce a more granular control over prompt restoration upon cancellation, ensuring that user-initiated cancellations clear the input while system-initiated cancellations continue to restore the prompt for user convenience. This improves the intuitiveness of the UI's cancellation behavior.

Highlights

  • UX Regression Fix: Addresses a regression where pressing the Escape key to cancel a request would inadvertently restore the previous user prompt to the input buffer, instead of clearing it.
  • Conditional Prompt Restoration: Modifies the cancellation logic to differentiate between user-initiated cancellations (e.g., via Escape key) and system-initiated cancellations (e.g., context window overflows), applying different behaviors for prompt restoration.
  • onCancelSubmit Refactor: The onCancelSubmit handler and its underlying cancelHandlerRef now accept an optional shouldRestorePrompt flag, allowing explicit control over whether the input buffer is cleared or the previous prompt is restored upon cancellation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

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

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 addresses a UX regression where pressing the Escape key would restore the previous prompt instead of clearing it. The fix introduces a shouldRestorePrompt flag to the onCancelSubmit handler, allowing differentiation between user-initiated cancellations (like pressing Escape) and system-initiated cancellations (like context window overflows). The changes in AppContainer.tsx and useGeminiStream.ts correctly implement this logic, ensuring that the Escape key now clears the input field while preserving the prompt restoration behavior for system events. The implementation is sound and effectively resolves the issue.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Nov 18, 2025

Size Change: +196 B (0%)

Total Size: 20.6 MB

ℹ️ View Unchanged
Filename Size Change
./bundle/gemini.js 20.6 MB +196 B (0%)
./bundle/sandbox-macos-permissive-closed.sb 1.03 kB 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-closed.sb 3.29 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B

compressed-size-action

@jacob314
Copy link
Copy Markdown
Contributor

I'm seeing this restoring the wrong prompt when the prompt is rejected.
Example:
https://screencast.googleplex.com/cast/NTAyNTY2MzM5NTI5OTMyOHxiOWIzMWMxZC0zOQ

@jacob314
Copy link
Copy Markdown
Contributor

From Gemini CLI:

I have reviewed the functional changes to AppContainer.tsx and useGeminiStream.ts, and they correctly implement the desired behavior of clearing the input on Escape while restoring it for system events like context overflow. The logic for handling queuedText also appears correct.

However, I've identified a few issues with the tests:

  1. Fixed Waits in AppContainer.test.tsx: The new tests in AppContainer.test.tsx use await act(async () => { await new Promise((resolve) => setTimeout(resolve, 0)); });. This introduces a fixed wait, which can lead to flaky tests. Please replace this with our custom waitFor utility (from src/test-utils/async.ts) with a proper predicate, or remove it if the state update is synchronous.
  2. waitFor Implementation: Ensure that all waitFor calls within packages/cli (including the newly added ones) utilize the waitFor utility imported from src/test-utils/async.ts, not vi.waitFor or setTimeout. This is crucial for correctly wrapping state updates in act() and preventing flakiness.
  3. Fragile Mock Access (Nit): The test accesses onCancelSubmit using mockedUseGeminiStream.mock.lastCall![14]. While this pattern exists elsewhere in the codebase, it is brittle as it relies on the exact argument order. Consider if there's a more robust way to access this specific mock function (e.g., by giving it a name when mocking useGeminiStream). This is a minor point, but worth noting for future improvements.

The default shouldRestorePrompt to true in AppContainer.tsx is a good, safe default.

Overall, the approach is sound, but addressing the test issues will significantly improve stability and adherence to best practices.

Removes fixed waits and improves test stability per review feedback. Also fixes waitFor usage inside act and abstracts positional argument access.
Comment thread packages/cli/src/ui/AppContainer.test.tsx Outdated
Copy link
Copy Markdown
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

lgtm

@SandyTao520 SandyTao520 added this pull request to the merge queue Nov 19, 2025
Merged via the queue into main with commit b644f03 Nov 19, 2025
22 checks passed
@SandyTao520 SandyTao520 deleted the st/fix/clear-input-on-escape branch November 19, 2025 03:25
@guidedways
Copy link
Copy Markdown

@SandyTao520 thank you this works!

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.

Hitting Escape while CLI is working re-displays the previous prompt

3 participants