rust-lang / rustup

The Rust toolchain installer
https://rust-lang.github.io/rustup/
Apache License 2.0
6.08k stars 876 forks source link

Install zsh completions for rustc #387

Open japaric opened 8 years ago

japaric commented 8 years ago

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

nerdrew commented 8 years ago

I like this.

brson commented 8 years ago

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.

ghost commented 8 years ago

@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.

brson commented 8 years ago

@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 commented 8 years ago

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:

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

brson commented 8 years ago

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.

alexcrichton commented 8 years ago

@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.

ghost commented 8 years ago

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.

brson commented 8 years ago

@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).

alexcrichton commented 8 years ago

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

nerdrew commented 8 years ago

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

brson commented 8 years ago

@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.

Rahix commented 8 years ago

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.

japaric commented 8 years ago

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.

Rahix commented 8 years ago

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

japaric commented 8 years ago

@Rahix Good idea!

brson commented 8 years ago

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.

Kerollmops commented 8 years ago

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

ricvelozo commented 6 years ago

At least include completions for Cargo on rustup completions.

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

Diggsey commented 6 years ago

Happy to accept a PR for this.

foxundermoon commented 5 years ago
source <(rustup completions zsh)

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

Nokel81 commented 4 years ago

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

marlonrichert commented 3 years ago
% 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.

sshine commented 2 years ago

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.