Skip to content

fix(cli): Shell autocomplete polish#20411

Open
jacob314 wants to merge 4 commits intomainfrom
jacob314_fix_shell
Open

fix(cli): Shell autocomplete polish#20411
jacob314 wants to merge 4 commits intomainfrom
jacob314_fix_shell

Conversation

@jacob314
Copy link
Contributor

@jacob314 jacob314 commented Feb 26, 2026

Highlights

  • Improved Autocomplete Submission Logic: Prevented accidental auto-submission of prompts when navigating shell autocomplete suggestions, ensuring explicit selection by requiring that the user has not actively navigated the suggestions list.
  • Stabilized Autocomplete UI: Decoupled the resetting of disabled state from completion refresh to eliminate UI flickering in autocomplete suggestions, particularly when typing outside of shell mode.
  • Reduced Visual Noise: Suppressed shell autocompletion for completely empty or whitespace-only prompts, activating only when typing or cursor movement suggests a need for paths/commands.
  • Enhanced Windows Compatibility: Integrated common Windows built-in commands (e.g., 'dir', 'copy', 'del') into the shell autocomplete list, providing a consistent user experience for Windows users.
  • Prioritized Command Suggestions: Implemented logic to prioritize shorter command names in shell autocomplete results, making common built-in commands more accessible and relevant.
  • Refactored Completion Logic and Fixed Race Condition: Simplified useCommandCompletion by moving shell-specific tokenization into useShellCompletion and addressed a potential race condition in scanPathExecutables by caching the promise itself.
Changelog
  • packages/cli/src/ui/components/InputPrompt.tsx
    • Modified the condition for auto-submitting a prompt to include a check that the user has not actively navigated the suggestions list, preventing premature submission.
  • packages/cli/src/ui/hooks/useCommandCompletion.test.tsx
    • Imported useShellCompletion for testing.
    • Updated the mock for useShellCompletion to return default completion range and query.
    • Extended setupMocks to accept shellSuggestions and shellCompletionRange for comprehensive testing.
    • Added a mock implementation for useShellCompletion within setupMocks to simulate its behavior.
  • packages/cli/src/ui/hooks/useCommandCompletion.tsx
    • Removed getTokenAtCursor import as its logic was moved.
    • Refactored the useMemo block to remove shell-specific token parsing, delegating it entirely to useShellCompletion.
    • Introduced memoQuery to distinguish the query derived from useMemo from the one returned by useShellCompletion.
    • Updated the completionMode logic to set CompletionMode.IDLE when the shell prompt is empty.
    • Removed shellTokenIsCommand, shellTokens, shellCursorIndex, and shellCommandToken from the memoized return value.
    • Modified useShellCompletion call to pass line and cursorCol instead of pre-parsed tokens.
    • Introduced shellCompletionRange to capture the return value from useShellCompletion.
    • Adjusted the query variable to correctly use shellCompletionRange.query when in shell completion mode.
    • Updated logic for getCompletedText and getCompletionRange to use shellCompletionRange for shell mode.
    • Added shellCompletionRange to the dependency arrays of useCallback functions.
  • packages/cli/src/ui/hooks/useShellCompletion.test.ts
    • Added assertions to the scanPathExecutables test to verify the inclusion of specific Windows built-in commands (dir, cls, copy) when running on a Windows platform.
  • packages/cli/src/ui/hooks/useShellCompletion.ts
    • Imported useMemo hook.
    • Modified scanPathExecutables to explicitly add a predefined list of Windows built-in commands to the executable list if the operating system is Windows.
    • Updated UseShellCompletionProps to accept line and cursorCol instead of pre-parsed token information.
    • Introduced UseShellCompletionReturn interface to define the return type of the hook.
    • Moved the getTokenAtCursor logic into a useMemo block within useShellCompletion to derive token information from line and cursorCol.
    • Changed pathCacheRef to pathCachePromiseRef to store a Promise, preventing multiple calls to scanPathExecutables and addressing a potential race condition.
    • Added a sorting mechanism to performCompletion to prioritize shorter command names in shell autocomplete results.
    • Refactored useEffect hooks: one for resetting suggestions when enabled becomes false, and another for debounced completion.
    • Adjusted dependencies for performCompletion useCallback and the debounced useEffect.
    • Modified the useShellCompletion hook to return completionStart, completionEnd, and query.

Fixes #20410

How to test, try shell autocomplete and make sure it is reasonable on windows, mac, and linux

@jacob314 jacob314 requested a review from a team as a code owner February 26, 2026 09:02
@gemini-cli
Copy link
Contributor

gemini-cli bot commented Feb 26, 2026

Hi @jacob314, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.

We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: Improving Our Contribution Process & Introducing New Guidelines.

Key Update: Starting January 26, 2026, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.

Thank you for your understanding and for being a part of our community!

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jacob314, 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 significantly enhances the command-line interface's autocompletion system by addressing several usability, stability, and platform-specific issues. It refines the submission behavior to prevent unintended actions, eliminates UI flickering during completion, and reduces visual clutter by intelligently disabling completion for empty prompts. Furthermore, it improves the autocompletion experience for Windows users by including built-in commands and optimizes suggestion relevance by prioritizing shorter command names. The underlying completion logic has also been refactored for better maintainability and to prevent race conditions.

Highlights

  • Improved Autocomplete Submission Logic: Prevented accidental auto-submission of prompts when navigating shell autocomplete suggestions, ensuring explicit selection by requiring that the user has not actively navigated the suggestions list.
  • Stabilized Autocomplete UI: Decoupled the resetting of disabled state from completion refresh to eliminate UI flickering in autocomplete suggestions, particularly when typing outside of shell mode.
  • Reduced Visual Noise: Suppressed shell autocompletion for completely empty or whitespace-only prompts, activating only when typing or cursor movement suggests a need for paths/commands.
  • Enhanced Windows Compatibility: Integrated common Windows built-in commands (e.g., 'dir', 'copy', 'del') into the shell autocomplete list, providing a consistent user experience for Windows users.
  • Prioritized Command Suggestions: Implemented logic to prioritize shorter command names in shell autocomplete results, making common built-in commands more accessible and relevant.
  • Refactored Completion Logic and Fixed Race Condition: Simplified useCommandCompletion by moving shell-specific tokenization into useShellCompletion and addressed a potential race condition in scanPathExecutables by caching the promise itself.
Changelog
  • packages/cli/src/ui/components/InputPrompt.tsx
    • Modified the condition for auto-submitting a prompt to include a check that the user has not actively navigated the suggestions list, preventing premature submission.
  • packages/cli/src/ui/hooks/useCommandCompletion.test.tsx
    • Imported useShellCompletion for testing.
    • Updated the mock for useShellCompletion to return default completion range and query.
    • Extended setupMocks to accept shellSuggestions and shellCompletionRange for comprehensive testing.
    • Added a mock implementation for useShellCompletion within setupMocks to simulate its behavior.
  • packages/cli/src/ui/hooks/useCommandCompletion.tsx
    • Removed getTokenAtCursor import as its logic was moved.
    • Refactored the useMemo block to remove shell-specific token parsing, delegating it entirely to useShellCompletion.
    • Introduced memoQuery to distinguish the query derived from useMemo from the one returned by useShellCompletion.
    • Updated the completionMode logic to set CompletionMode.IDLE when the shell prompt is empty.
    • Removed shellTokenIsCommand, shellTokens, shellCursorIndex, and shellCommandToken from the memoized return value.
    • Modified useShellCompletion call to pass line and cursorCol instead of pre-parsed tokens.
    • Introduced shellCompletionRange to capture the return value from useShellCompletion.
    • Adjusted the query variable to correctly use shellCompletionRange.query when in shell completion mode.
    • Updated logic for getCompletedText and getCompletionRange to use shellCompletionRange for shell mode.
    • Added shellCompletionRange to the dependency arrays of useCallback functions.
  • packages/cli/src/ui/hooks/useShellCompletion.test.ts
    • Added assertions to the scanPathExecutables test to verify the inclusion of specific Windows built-in commands (dir, cls, copy) when running on a Windows platform.
  • packages/cli/src/ui/hooks/useShellCompletion.ts
    • Imported useMemo hook.
    • Modified scanPathExecutables to explicitly add a predefined list of Windows built-in commands to the executable list if the operating system is Windows.
    • Updated UseShellCompletionProps to accept line and cursorCol instead of pre-parsed token information.
    • Introduced UseShellCompletionReturn interface to define the return type of the hook.
    • Moved the getTokenAtCursor logic into a useMemo block within useShellCompletion to derive token information from line and cursorCol.
    • Changed pathCacheRef to pathCachePromiseRef to store a Promise, preventing multiple calls to scanPathExecutables and addressing a potential race condition.
    • Added a sorting mechanism to performCompletion to prioritize shorter command names in shell autocomplete results.
    • Refactored useEffect hooks: one for resetting suggestions when enabled becomes false, and another for debounced completion.
    • Adjusted dependencies for performCompletion useCallback and the debounced useEffect.
    • Modified the useShellCompletion hook to return completionStart, completionEnd, and query.
Activity
  • No human activity (comments, reviews, etc.) has been recorded on this pull request yet.
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.

@gemini-cli gemini-cli bot added area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Feb 26, 2026
Copy link
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 introduces valuable fixes and refactorings to the shell autocompletion functionality, enhancing user experience by addressing issues like accidental submission, UI flicker, and suggestion relevance, and improving overall robustness, including support for Windows shell built-ins and improved navigation. However, a critical high-severity command injection vulnerability was identified on Windows. The current implementation fails to properly escape or quote shell metacharacters in autocompleted filenames and commands, which could lead to arbitrary command execution. It is strongly recommended to address this by ensuring proper quoting/escaping within the escapeShellPath utility. Additionally, a performance improvement can be achieved by adding a dependency array to a useEffect hook to prevent it from running on every render.

@github-actions
Copy link

github-actions bot commented Feb 26, 2026

Size Change: +858 B (0%)

Total Size: 25.7 MB

ℹ️ View Unchanged
Filename Size Change
./bundle/gemini.js 25.2 MB +858 B (0%)
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 221 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 227 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 11.5 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 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-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B

compressed-size-action

… autocomplete suggestion

When using shell autocomplete, pressing Down then Up returns the activeSuggestionIndex to 0. If the first suggestion happened to be an exact match, the InputPrompt would bypass the normal autocomplete logic and eagerly submit the prompt on Enter because it ignored whether the user had actively navigated.

This fix updates the isPerfectMatch check to require that the user has not navigated the suggestions list, ensuring that explicitly selected items always autocomplete instead of submitting.

fix(cli): prevent autocomplete UI flicker by decoupling disabled state reset from completion refresh

When typing outside of shell mode (e.g., using `@` completion), the `useShellCompletion` hook was continuously re-rendering and executing its `useEffect` because `performCompletion` was recreated on every keystroke (since its `query` dependency changed).

Because `enabled` was false, the effect unconditionally called `setSuggestions([])`, rapidly overriding the suggestions populated by `useAtCompletion` and causing severe UI flickering.

This splits the effect to ensure `setSuggestions([])` is only called once when `enabled` becomes false, stabilizing the suggestions list.

fix(cli): disable shell autocompletion on completely empty prompts

To reduce visual noise and distraction, autocompletion is now suppressed when the shell prompt is entirely empty (or only contains whitespace). It remains active as soon as the user starts typing or moves the cursor to a position that would suggest paths/commands.

fix(cli): add Windows shell built-in commands to autocomplete list

On Windows, many common commands like `dir`, `copy`, `del`, etc., are internal to `cmd.exe` and do not exist as separate executables on the disk. This updates `scanPathExecutables` to explicitly include these built-ins when running on Windows, ensuring a consistent autocomplete experience for Windows users.

test(cli): update snapshots for shell autocompletion refinements

fix(cli): prioritize shorter command names in shell autocomplete results

refactor(cli): simplify command completion orchestration and fix shell cache race

- Simplified `useCommandCompletion.tsx` by moving shell-specific tokenization into `useShellCompletion.ts`.
- Reverted most changes to the `useCommandCompletion` `useMemo` block to keep it clean and consistent with other modes.
- Fixed a potential race condition in `useShellCompletion.ts` where `scanPathExecutables` could be called multiple times if it was slow. It now caches the Promise itself.
- Updated tests to match the refined hook interfaces.
@jacob314 jacob314 changed the title fix(cli): prevent auto-submit on Enter when navigating to first shell autocomplete suggestion fix(cli): Shell autocomplete polish Feb 26, 2026
@scidomino
Copy link
Collaborator

Could you clean up the description? It's a bit hard to read.

@jacob314 jacob314 enabled auto-merge February 26, 2026 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shell autocomplete polish

2 participants