fix(cli): prevent infinite loop in ghost text wrapping when inputWidth is narrower than a codepoint#27747
Conversation
…h is narrower than a codepoint When `inputWidth` is 0 or smaller than a wide character's rendered width (e.g. an emoji rendered at width 2 in a 1-column terminal), the inner for-loop in `getGhostTextLines` could not fit any codepoint so `splitIndex` stayed 0. `cpSlice(word, 0)` then returned the full word unchanged, trapping the outer while-loop forever and freezing the CLI. Force-advance by one codepoint when `splitIndex` is still 0 after the inner scan, so the loop always makes progress and terminates. Fixes google-gemini#19985
Summary of ChangesHello, 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 addresses a critical issue where the CLI would freeze when rendering ghost text in extremely narrow terminal windows. By ensuring the text wrapping logic always makes progress even when individual characters exceed the available display width, the fix guarantees that the rendering loop terminates correctly. Highlights
Using Gemini Code AssistThe 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
Customization To customize the 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 Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. 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. Footnotes
|
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
📊 PR Size: size/S
|
There was a problem hiding this comment.
Code Review
This pull request fixes an infinite loop bug in InputPrompt that occurs when wrapping ghost text containing wide characters (such as emojis) when the inputWidth is narrower than the character's rendered width. It resolves this by force-advancing the loop by one codepoint if no characters fit. A regression test has also been added to verify this behavior. I have no feedback to provide as there are no review comments.
Summary
Fixes #19985 — the CLI freezes when an
@filename:linecompletion is active and the terminal is too narrow to display a wide character (e.g. an emoji rendered at width 2 in a 1-column window).Root cause:
getGhostTextLinesinInputPrompt.tsxcontains awhile (stringWidth(wordToProcess) > inputWidth)loop that splits an oversized word into lines. An innerfor-loop scans codepoints and advancessplitIndexonly whenpartWidth + charWidth <= inputWidth. WheninputWidthis 0 — or smaller than a single codepoint's rendered width — no codepoint ever fits, sosplitIndexstays0.cpSlice(wordToProcess, 0)then returns the full word unchanged, and the outerwhileloops forever, freezing the renderer.Fix: After the inner scan, if
splitIndexis still0and the word is non-empty, force-advance by one codepoint. This guarantees the loop always makes progress and terminates.Test plan
does not freeze when ghost text contains wide chars and inputWidth is narrowinInputPrompt.test.tsx: setsinputWidth=1with an emoji ghost text (😀, width 2), which would have hung the test runner before this fixpnpm testinpackages/cli— existing suite passes