Open japaric opened 8 years ago
I like this.
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 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.
@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
.
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:
include_str!()
rustup self install-shell-completions --zsh
that does the copies with sudo
on Unix (not sure about windows)cc @alexcrichton @nrc @aturon @japaric a strategy for distributing Rust tool shell-completions.
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 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.
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 runssudo
.
Being able to avoid sudo
entirely would be nice but I would definitely prefer this option.
@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).
It may also be ok to print out "just run this one command, maybe with sudo" as part of this command to install completions.
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 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.
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.
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.
If you want automatic updating, you could add something like source <(rustup zsh-completions)
to your .zshrc
@Rahix Good idea!
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.
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
At least include completions for Cargo on rustup completions
.
Related: rust-lang/cargo/issues/5596, #1123, #1199.
Happy to accept a PR for this.
source <(rustup completions zsh)
_arguments:comparguments:319: can only be called from completion function
Yeah that is what I am getting too, the command runs fine if not in a zshrc file though (which is weird)
% source <(rustup completions zsh) _arguments:comparguments:319: can only be called from completion function
You're not supposed to
source
that. Typerustup completions
for instructions or read them in The Rustup Book.
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.
We already install zsh completions for cargo. It would be nice if rustup also installed the rustc zsh completions from this repository.