Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): forward bash completions of third party subcommands #15247

Conversation

titaniumtraveler
Copy link
Contributor

What does this PR try to resolve?

Currently third party subcommands like cargo asm from cargo-show-asm don't
support shell completions, even when the corresponding cargo-<cmd> command does.
(I'm using cargo asm as example because it was the first subcommand that came
into mind that provides completions)

This PR fixes this for bash by using bash-completion's
_comp_command_offset function to generate these completions.
(Assuming these completions are available to bash-completion)

bash-completion is the package that is used by all major unix-like operating
systems to provide bash completions.

If the subcommand has no completion, that falls back to the default bash.
(That might not be exactly the same as _filedir, but should be correct anyway)

Note that _comp_command_offset is only supported since bash-completion >= 2.12.0,
which requires bash >= 4.2.0, which means that the default
bash version shipped with MacOs is not supported.
In that case we fall back to the previous behavior with _filedir.

How should we test and review this PR?

I'm not sure if there is any testing setup for shell completions for cargo.
I have just tested it manually by running these commands:
(In the working directory of this PR)

#!/usr/bin/env bash

# Install the subcommand
cargo install cargo-show-asm
# Load the completions for `cargo-asm`
eval "$(cargo-asm --bpaf-complete-style-bash)"
# (Re)source the new cargo completions
source src/etc/cargo.bashcomp.sh

and then tab-completing from cargo asm <TAB>.

Additional information

Further Possibilities

The same trick with _comp_command_offset could be used to get completions
for the command run with cargo run -- , assuming there is an easy way to get
the name of the binary that would be run. (And maybe something to dynamically (re)-load the completions.)

Prior Art

The zsh-completions already support the zsh-equivalent of this with

cargo/src/etc/_cargo

Lines 368 to 372 in 58cfd96

# allow plugins to define their own functions
if ! _call_function ret _cargo-${words[1]}; then
# fallback on default completion for unknown commands
_default && ret=0
fi

@rustbot
Copy link
Collaborator

rustbot commented Feb 28, 2025

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-completions Area: shell completions S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 28, 2025
@titaniumtraveler
Copy link
Contributor Author

Whoops. I did not notice that cargo.bashcomp.sh uses tabs not spaces ...

@epage
Copy link
Contributor

epage commented Feb 28, 2025

Feel free to clean up your commit history.

Not looking too much at this atm as I'm not much of a bash or shell completion expert.

I did want to give you a heads up that we are working on replacing our shell completions (#14520) and so this change will be short-lived unless someone gets that working with the new stuff. I wonder if we should freeze development of our existing completions because of that.

@titaniumtraveler
Copy link
Contributor Author

Feel free to clean up your commit history.

Kinda hoped that github supports git commit --fixup commits.

Not looking too much at this atm as I'm not much of a bash or shell completion expert.

I did want to give you a heads up that we are working on replacing our shell completions (#14520) and so this change will be short-lived unless someone gets that working with the new stuff. I wonder if we should freeze development of our existing completions because of that.

Yeah, I know about it.
I didn't know that native clap completions are already that far 😮
Considering how simple the change is I think it should be fine to include this change anyway.

@epage
Copy link
Contributor

epage commented Feb 28, 2025

Kinda hoped that github supports git commit --fixup commits.

I wish

Considering how simple the change is I think it should be fine to include this change anyway.

And the regression in behavior when we switch? Or further blocking switching until this is fixed? Those are my concerns.

@titaniumtraveler
Copy link
Contributor Author

Considering how simple the change is I think it should be fine to include this change anyway.

And the regression in behavior when we switch? Or further blocking switching until this is fixed? Those are my concerns.

Ahh. To be fair, since it is only shell completions and only for bash I would be fine with it.

I guess I will look into how that is handled in the native completions.

@titaniumtraveler titaniumtraveler force-pushed the pr/bash-completion-forward-to-subcommand branch from 656f058 to 4d38888 Compare February 28, 2025 17:36
@weihanglo
Copy link
Member

And the regression in behavior when we switch? Or further blocking switching until this is fixed? Those are my concerns.

I don't think a regression in completing custom subcommands will be a blocker. Also, Cargo's zsh completion has provided such a feature, so seems reasonable for bash to follow. Already added offsetting to custom subcommand as a task in native completion tracking issue. We could consider the support before stabilization.

Copy link
Member

@weihanglo weihanglo left a comment

Choose a reason for hiding this comment

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

Thanks for the contributions. It is nice!

@weihanglo weihanglo added this pull request to the merge queue Mar 1, 2025
Merged via the queue into rust-lang:master with commit 48a54c9 Mar 1, 2025
21 checks passed
@pacak
Copy link
Contributor

pacak commented Mar 1, 2025

I'm using cargo asm as example because it was the first subcommand that came
into mind that provides completions

FWIW if as long as we are talking about cargo-show-asm - you can invoke it via cargo-asm bypassing cargo and configure your shell accordingly.

@weihanglo
Copy link
Member

weihanglo commented Mar 1, 2025

FWIW if as long as we are talking about cargo-show-asm - you can invoke it via cargo-asm bypassing cargo and configure your shell accordingly.

That is true if you don't user any toolchain override, otherwise running cargo-asm directly might invoke cargo from a wrong toolchain because of missing $CARGO.

@titaniumtraveler
Copy link
Contributor Author

I'm using cargo asm as example because it was the first subcommand that came
into mind that provides completions

FWIW if as long as we are talking about cargo-show-asm - you can invoke it via cargo-asm bypassing cargo and configure your shell accordingly.

I mean yeah. That is the whole reason this entire thing works.
But it still feels like a workaround. And if that is just not necessary that is definitely nicer.

@titaniumtraveler titaniumtraveler deleted the pr/bash-completion-forward-to-subcommand branch March 1, 2025 22:25
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 8, 2025
Update cargo

22 commits in 2622e844bc1e2e6123e54e94e4706f7b6195ce3d..ab1463d632528e39daf35f263e10c14cbe590ce8
2025-02-28 12:33:57 +0000 to 2025-03-08 01:45:05 +0000
- test: redact host target when comparing CARGO_ENV path (rust-lang/cargo#15279)
- feat: add completions for install --path (rust-lang/cargo#15266)
- fix(package): report lockfile / workspace manifest is dirty  (rust-lang/cargo#15276)
- feat(tree): Add `--depth public` behind `-Zunstable-options` (rust-lang/cargo#15243)
- Don't use `$CARGO_BUILD_TARGET` in `cargo metadata` (rust-lang/cargo#15271)
- feat: show extra build description from bootstrap (rust-lang/cargo#15269)
- Upgrade to `rustc-stable-hash v0.1.2` (rust-lang/cargo#15268)
- fix: Respect --frozen everywhere --offline or --locked is accepted (rust-lang/cargo#15263)
- feat(tree): Color the output (rust-lang/cargo#15242)
- fix(vendor): dont remove non-cached source  (rust-lang/cargo#15260)
- docs: lockfile is always included since 1.84 (rust-lang/cargo#15257)
- Remove `Cargo.toml` from `package.include` in example (rust-lang/cargo#15253)
- Small cleanup: remove unneeded result (rust-lang/cargo#15256)
- Fix typo in build-scripts.md (rust-lang/cargo#15254)
- chore(deps): update rust crate pulldown-cmark to 0.13.0 (rust-lang/cargo#15250)
- chore(deps): update compatible (rust-lang/cargo#15249)
- feat(cli): forward bash completions of third party subcommands (rust-lang/cargo#15247)
- feat: add completions for `--lockfile-path` (rust-lang/cargo#15238)
- fix: reset $CARGO if the running program is real `cargo[.exe]`  (rust-lang/cargo#15208)
- Get all members as `available targets` even though default-members was specified. (rust-lang/cargo#15199)
- refactor: control byte display precision with std::fmt options (rust-lang/cargo#15246)
- fix(package): Ensure we can package directories ending with '.rs' (rust-lang/cargo#15240)
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 8, 2025
Update cargo

22 commits in 2622e844bc1e2e6123e54e94e4706f7b6195ce3d..ab1463d632528e39daf35f263e10c14cbe590ce8
2025-02-28 12:33:57 +0000 to 2025-03-08 01:45:05 +0000
- test: redact host target when comparing CARGO_ENV path (rust-lang/cargo#15279)
- feat: add completions for install --path (rust-lang/cargo#15266)
- fix(package): report lockfile / workspace manifest is dirty  (rust-lang/cargo#15276)
- feat(tree): Add `--depth public` behind `-Zunstable-options` (rust-lang/cargo#15243)
- Don't use `$CARGO_BUILD_TARGET` in `cargo metadata` (rust-lang/cargo#15271)
- feat: show extra build description from bootstrap (rust-lang/cargo#15269)
- Upgrade to `rustc-stable-hash v0.1.2` (rust-lang/cargo#15268)
- fix: Respect --frozen everywhere --offline or --locked is accepted (rust-lang/cargo#15263)
- feat(tree): Color the output (rust-lang/cargo#15242)
- fix(vendor): dont remove non-cached source  (rust-lang/cargo#15260)
- docs: lockfile is always included since 1.84 (rust-lang/cargo#15257)
- Remove `Cargo.toml` from `package.include` in example (rust-lang/cargo#15253)
- Small cleanup: remove unneeded result (rust-lang/cargo#15256)
- Fix typo in build-scripts.md (rust-lang/cargo#15254)
- chore(deps): update rust crate pulldown-cmark to 0.13.0 (rust-lang/cargo#15250)
- chore(deps): update compatible (rust-lang/cargo#15249)
- feat(cli): forward bash completions of third party subcommands (rust-lang/cargo#15247)
- feat: add completions for `--lockfile-path` (rust-lang/cargo#15238)
- fix: reset $CARGO if the running program is real `cargo[.exe]`  (rust-lang/cargo#15208)
- Get all members as `available targets` even though default-members was specified. (rust-lang/cargo#15199)
- refactor: control byte display precision with std::fmt options (rust-lang/cargo#15246)
- fix(package): Ensure we can package directories ending with '.rs' (rust-lang/cargo#15240)
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 10, 2025
Update cargo

22 commits in 2622e844bc1e2e6123e54e94e4706f7b6195ce3d..ab1463d632528e39daf35f263e10c14cbe590ce8
2025-02-28 12:33:57 +0000 to 2025-03-08 01:45:05 +0000
- test: redact host target when comparing CARGO_ENV path (rust-lang/cargo#15279)
- feat: add completions for install --path (rust-lang/cargo#15266)
- fix(package): report lockfile / workspace manifest is dirty  (rust-lang/cargo#15276)
- feat(tree): Add `--depth public` behind `-Zunstable-options` (rust-lang/cargo#15243)
- Don't use `$CARGO_BUILD_TARGET` in `cargo metadata` (rust-lang/cargo#15271)
- feat: show extra build description from bootstrap (rust-lang/cargo#15269)
- Upgrade to `rustc-stable-hash v0.1.2` (rust-lang/cargo#15268)
- fix: Respect --frozen everywhere --offline or --locked is accepted (rust-lang/cargo#15263)
- feat(tree): Color the output (rust-lang/cargo#15242)
- fix(vendor): dont remove non-cached source  (rust-lang/cargo#15260)
- docs: lockfile is always included since 1.84 (rust-lang/cargo#15257)
- Remove `Cargo.toml` from `package.include` in example (rust-lang/cargo#15253)
- Small cleanup: remove unneeded result (rust-lang/cargo#15256)
- Fix typo in build-scripts.md (rust-lang/cargo#15254)
- chore(deps): update rust crate pulldown-cmark to 0.13.0 (rust-lang/cargo#15250)
- chore(deps): update compatible (rust-lang/cargo#15249)
- feat(cli): forward bash completions of third party subcommands (rust-lang/cargo#15247)
- feat: add completions for `--lockfile-path` (rust-lang/cargo#15238)
- fix: reset $CARGO if the running program is real `cargo[.exe]`  (rust-lang/cargo#15208)
- Get all members as `available targets` even though default-members was specified. (rust-lang/cargo#15199)
- refactor: control byte display precision with std::fmt options (rust-lang/cargo#15246)
- fix(package): Ensure we can package directories ending with '.rs' (rust-lang/cargo#15240)
@rustbot rustbot added this to the 1.87.0 milestone Mar 10, 2025
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Mar 11, 2025
Update cargo

22 commits in 2622e844bc1e2e6123e54e94e4706f7b6195ce3d..ab1463d632528e39daf35f263e10c14cbe590ce8
2025-02-28 12:33:57 +0000 to 2025-03-08 01:45:05 +0000
- test: redact host target when comparing CARGO_ENV path (rust-lang/cargo#15279)
- feat: add completions for install --path (rust-lang/cargo#15266)
- fix(package): report lockfile / workspace manifest is dirty  (rust-lang/cargo#15276)
- feat(tree): Add `--depth public` behind `-Zunstable-options` (rust-lang/cargo#15243)
- Don't use `$CARGO_BUILD_TARGET` in `cargo metadata` (rust-lang/cargo#15271)
- feat: show extra build description from bootstrap (rust-lang/cargo#15269)
- Upgrade to `rustc-stable-hash v0.1.2` (rust-lang/cargo#15268)
- fix: Respect --frozen everywhere --offline or --locked is accepted (rust-lang/cargo#15263)
- feat(tree): Color the output (rust-lang/cargo#15242)
- fix(vendor): dont remove non-cached source  (rust-lang/cargo#15260)
- docs: lockfile is always included since 1.84 (rust-lang/cargo#15257)
- Remove `Cargo.toml` from `package.include` in example (rust-lang/cargo#15253)
- Small cleanup: remove unneeded result (rust-lang/cargo#15256)
- Fix typo in build-scripts.md (rust-lang/cargo#15254)
- chore(deps): update rust crate pulldown-cmark to 0.13.0 (rust-lang/cargo#15250)
- chore(deps): update compatible (rust-lang/cargo#15249)
- feat(cli): forward bash completions of third party subcommands (rust-lang/cargo#15247)
- feat: add completions for `--lockfile-path` (rust-lang/cargo#15238)
- fix: reset $CARGO if the running program is real `cargo[.exe]`  (rust-lang/cargo#15208)
- Get all members as `available targets` even though default-members was specified. (rust-lang/cargo#15199)
- refactor: control byte display precision with std::fmt options (rust-lang/cargo#15246)
- fix(package): Ensure we can package directories ending with '.rs' (rust-lang/cargo#15240)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-completions Area: shell completions S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants