Skip to content

Fix zsh completion showing all PATH entries for +toolchain arg#4763

Merged
rami3l merged 1 commit intorust-lang:mainfrom
simonhkswan:fix-zsh-completion-path-pollution
Mar 21, 2026
Merged

Fix zsh completion showing all PATH entries for +toolchain arg#4763
rami3l merged 1 commit intorust-lang:mainfrom
simonhkswan:fix-zsh-completion-path-pollution

Conversation

@simonhkswan
Copy link
Contributor

Problem

When using zsh completions generated by rustup completions zsh, typing rustup <TAB> shows every executable on $PATH alongside the actual rustup subcommands (install, update, show, etc.). This makes the completion menu nearly unusable — thousands of irrelevant entries mixed in with the ~15 real subcommand completions.

How to reproduce

  1. Generate zsh completions: rustup completions zsh > _rustup
  2. Place _rustup on your $fpath and reload the shell (exec zsh)
  3. Type rustup and press <TAB>
  4. Observe that all commands on $PATH appear in the completion list

Cause

The +toolchain optional positional argument in src/cli/rustup_mode.rs is defined without a value_hint. When clap_complete generates zsh completions, arguments with no hint default to ValueHint::Unknown, which the zsh generator maps to the _default completion action (source):

ValueHint::Unknown => "_default",

This produces the following in the generated completion script:

'::+toolchain -- Release channel (e.g. +stable) or custom toolchain to set override:_default'

In zsh, _default is a catch-all completer that suggests files and commands on $PATH. Since this is an optional positional argument (:: prefix), zsh offers these completions alongside the subcommand completions every time.

Fix

This PR adds value_hint = ValueHint::Other to the +toolchain argument. In the zsh generator, ValueHint::Other maps to an empty string — no completion action — which prevents the PATH pollution. Rustup subcommand completions continue to work as expected.

Future improvement

A more complete solution would be to provide dynamic completions for the +toolchain argument using clap_complete's ArgValueCompleter, which could call rustup toolchain list at completion time to suggest installed toolchains. That would be a larger change involving adoption of clap_complete's dynamic completion infrastructure, so this PR focuses on the minimal fix to eliminate the broken behavior.

@rami3l
Copy link
Member

rami3l commented Mar 20, 2026

@simonhkswan Thanks for investigating! Do you think your fix will address #2268 / #4532 as well, or at least a part of them? The symptoms look pretty similar...

Copy link
Member

@rami3l rami3l left a comment

Choose a reason for hiding this comment

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

I think this might need more testing by the impacted users, but otherwise LGTM!

View changes since this review

The optional +toolchain positional argument was defined without a
value_hint, causing clap_complete to generate zsh completions with
the `_default` action. In zsh, `_default` suggests all executables
on $PATH, polluting the completion menu with thousands of irrelevant
entries alongside the actual rustup subcommands.

Adding `value_hint = ValueHint::Other` prevents clap_complete from
emitting `_default`, so only the intended subcommand completions
appear.
@simonhkswan simonhkswan force-pushed the fix-zsh-completion-path-pollution branch from 5c4dfe4 to e378f84 Compare March 20, 2026 21:24
@simonhkswan
Copy link
Contributor Author

simonhkswan commented Mar 20, 2026

@simonhkswan Thanks for investigating! Do you think your fix will address #2268 / #4532 as well, or at least a part of them? The symptoms look pretty similar...

So I believe this PR directly addresses problem 1 from #2268rustup <TAB> showing file/PATH entries alongside the real subcommands. That's caused by clap_complete emitting the _default zsh completion action for the +toolchain positional arg, which this fix eliminates.

Problem 2 from #2268 (rustup toolchain <TAB> showing top-level commands instead of toolchain subcommands) is a deeper issue with how clap handles subcommand parsing when an optional positional arg precedes them. The more involved follow-up I mentioned in the PR description — using clap_complete's ArgValueCompleter to dynamically complete +toolchain values via rustup toolchain list — could potentially address this too, by giving clap proper knowledge of what values +toolchain accepts and helping it correctly distinguish the toolchain argument from the subcommand position.

#4532 seems closed as a duplicate but maybe the same approach mentioned above could address this too.

@rami3l
Copy link
Member

rami3l commented Mar 20, 2026

@simonhkswan Sounds good! Did you test this change on your machine?

If it works well I'd love to merge it and update the problem description to leave the second problem above for further discussion.

@simonhkswan
Copy link
Contributor Author

@simonhkswan Sounds good! Did you test this change on your machine?

If it works well I'd love to merge it and update the problem description to leave the second problem above for further discussion.

@rami3l - I did test it (and actually using it permanently now :)

rustup

@rami3l rami3l added this pull request to the merge queue Mar 21, 2026
Merged via the queue into rust-lang:main with commit bf429b1 Mar 21, 2026
29 checks passed
@rami3l
Copy link
Member

rami3l commented Mar 21, 2026

@simonhkswan Cool, and thanks again for your contribution!

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.

3 participants