rustup icon indicating copy to clipboard operation
rustup copied to clipboard

Install zsh completions for rustc

Open japaric opened this issue 8 years ago • 24 comments

We already install zsh completions for cargo. It would be nice if rustup also installed the rustc zsh completions from this repository.

japaric avatar Apr 30 '16 16:04 japaric

I like this.

nerdrew avatar Jun 22 '16 06:06 nerdrew

Fine by me, though I'd like to understand better how they are supposed to be installed. You say we already install cargo zsh completions, but we don't do anything special for them - they're just buried in the toolchain directory. That's not so user-friendly.

brson avatar Jun 24 '16 00:06 brson

@brson The completions file needs to be in a directory contained in fpath so probably the most direct way is to just create a symlink:

ln -s rust-lang/zsh-config/_rust /usr/local/share/zsh/site-functions/_rust

On OS X, I believe this is where brew usually links completions.

ghost avatar Jul 15 '16 20:07 ghost

@freebroccolo Thanks for the tips.

I see two problems that need to be solved: first, the completions could theoretically be toolchain-specific (and indeed the cargo zsh completions today come with the compiler, not rustup). So a single symlink isn't sufficient because it won't change when the active toolchain changes.

Second, installing to /usr/local typically requires root, and rustup installation today does not require root, which I see as a strong advantage. I don't want to require root just to install completions.

For the first, I'd suggest that the drift in the command sets of rustc, cargo and other potential tools is small enough that rustup could just install one global completion that more-or-less works with all toolchains. That is, the completions are distributed with rustup, not the toolchains. If the completions are smart enough they may even be able to change their behavior based on the compiler version. Oh, maybe the completions installed by rustup just detect the toolchain and then defer to the toolchain completions. That sounds plausible.

For the second I'm not sure. Maybe have a command rustup self install-completions. Maybe an optional install-time component that runs sudo.

brson avatar Jul 18 '16 22:07 brson

I think I'd prefer the simplicity of removing completions from the toolchain installer and just making rustup responsible for them. This has the downside that maybe the completions aren't exactly right for any particular toolchain (or the completions have to support multiple toolchains). Here's what I'd suggest the next steps are:

  • Add the cargo and rustc zsh completions to the rustup binary via include_str!()
  • Add a command rustup self install-shell-completions --zsh that does the copies with sudo on Unix (not sure about windows)
  • Punt on install-time configuration of shell completions for now
  • Then do the same for bash

cc @alexcrichton @nrc @aturon @japaric a strategy for distributing Rust tool shell-completions.

brson avatar Jul 18 '16 22:07 brson

Oh, probably also need a way to clean up the mess - rustup self uninstall-shell-completions. Also need to consider what happens when you run rustup self uninstall. It definitely should not silently leave the completions sitting on disk.

brson avatar Jul 18 '16 22:07 brson

@brson I may have missed this, but there's for sure no user-local place to install completions? I agree that rustup never calling sudo is quite nice :)

Other than that I think we'd still want to continue to distribute the completions in the other installers we have (e.g. tarballs) but having a command that's baked into rustup also seems good to me. The completions don't really change all that often anyway, and when they do it's mostly just adding features.

alexcrichton avatar Jul 18 '16 23:07 alexcrichton

I see two problems that need to be solved: first, the completions could theoretically be toolchain-specific (and indeed the cargo zsh completions today come with the compiler, not rustup). So a single symlink isn't sufficient because it won't change when the active toolchain changes.

Good point. In principle, you could add a directory to fpath (e.g., ~/.zfunctions, which some people already use) instead of creating a symlink under /usr/local. Then you could have multiple completion files or whatever in order to handle the different toolchains. But to make this approach usable you'd have to either modify the users login script or require that they manually set their fpath to include the directory. Neither of those seem ideal.

For the second I'm not sure. Maybe have a command rustup self install-completions. Maybe an optional install-time component that runs sudo.

Being able to avoid sudo entirely would be nice but I would definitely prefer this option.

ghost avatar Jul 18 '16 23:07 ghost

@brson I may have missed this, but there's for sure no user-local place to install completions? I agree that rustup never calling sudo is quite nice :)

Well, for zsh at least we can modify the $fpath variable, but that only helps zsh, not bash, and arranging for environment variables to be set a certain way kinda sucks (though I guess once we get to a place where we are reliably setting PATH we could also set any other variable).

brson avatar Jul 19 '16 00:07 brson

It may also be ok to print out "just run this one command, maybe with sudo" as part of this command to install completions.

alexcrichton avatar Jul 19 '16 16:07 alexcrichton

I hacked together zsh completions for rustup itself. Worth a PR? Long term solution: https://github.com/kbknapp/clap-rs should support zsh completion generation (my 2c; clap issue for bash completion generation=https://github.com/kbknapp/clap-rs/issues/376). _rustup.txt

nerdrew avatar Jul 21 '16 06:07 nerdrew

@nerdrew Yeah, if you have rustup zsh completions I'd like to have them in repo ... somewhere, with the intent of installing them with this rustup self install-shell-completions feature.

brson avatar Jul 22 '16 22:07 brson

I would suggest performing the installation like npm does it (https://docs.npmjs.com/cli/completion). That way, no root is required, and it is not hardcoded where completions are installed.

Rahix avatar Aug 03 '16 20:08 Rahix

I like this idea of rustup zsh-completions >> /some/path/that/makes/sense/for/me; it's simple. One downside, though, is that rustup update probably won't be able to automatically update the completion file whereas rustup self install-shell-completions can because it knows beforehand where the completion file must be installed.

japaric avatar Aug 04 '16 00:08 japaric

If you want automatic updating, you could add something like source <(rustup zsh-completions) to your .zshrc

Rahix avatar Aug 05 '16 10:08 Rahix

@Rahix Good idea!

japaric avatar Aug 06 '16 15:08 japaric

I wonder if all shells have completions that fit in a single file. If we're expecting the user to redirect the completions to the right place themselves then we'll need to be able to tell them how to do the completions.

In the npm example from the linked docs they pipe the same completions into both .bashrc and .zshrc. I did not realize the two systems were compatible! That can't be the case for all shells.

brson avatar Aug 11 '16 00:08 brson

Why not a $HOME/.cargo/.completion.zsh file followed by this in your .zshrc:

# ...
source $HOME/.cargo/.completion.zsh

Each time you update rustup, the file is updated and you don't call rustup completion each time you open a new shell

Kerollmops avatar Aug 16 '16 23:08 Kerollmops

At least include completions for Cargo on rustup completions.

Related: rust-lang/cargo/issues/5596, #1123, #1199.

ricvelozo avatar Jun 01 '18 20:06 ricvelozo

Happy to accept a PR for this.

Diggsey avatar Jun 01 '18 20:06 Diggsey

source <(rustup completions zsh)

_arguments:comparguments:319: can only be called from completion function

foxundermoon avatar Jan 20 '19 12:01 foxundermoon

Yeah that is what I am getting too, the command runs fine if not in a zshrc file though (which is weird)

Nokel81 avatar Oct 04 '19 19:10 Nokel81

% source <(rustup completions zsh)
_arguments:comparguments:319: can only be called from completion function

You're not supposed to source that. Type rustup completions for instructions or read them in The Rustup Book.

marlonrichert avatar Mar 10 '21 17:03 marlonrichert

I put this in my .zshrc (inspired by the link above):

if [ ! -e ~/.zfunc/_rustup -a $commands[rustup] ]; then
  mkdir -p ~/.zfunc
  rustup completions zsh > ~/.zfunc/_rustup
  fpath+=~/.zfunc
fi

# ...

autoload -Uz compinit && compinit

# ...

I think the idea behind generating _rustup and sourcing it, rather than sourcing rustup completions zsh directly, is that you don't have to run rustup completions zsh every time, but you can simply source the generated output from disk.

sshine avatar Dec 09 '21 16:12 sshine