Skip to content

Commit 2c4418b

Browse files
committed
feat: Add native completions with CompleteEnv and under the nightly features
1 parent 7fe6a7d commit 2c4418b

File tree

7 files changed

+176
-0
lines changed

7 files changed

+176
-0
lines changed

src/bin/cargo/main.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![allow(clippy::self_named_module_files)] // false positive in `commands/build.rs`
22

3+
use cargo::core::features;
34
use cargo::core::shell::Shell;
45
use cargo::util::network::http::http_handle;
56
use cargo::util::network::http::needs_custom_http_transport;
@@ -28,6 +29,13 @@ fn main() {
2829
}
2930
};
3031

32+
let nightly_features_allowed = matches!(&*features::channel(), "nightly" | "dev");
33+
if nightly_features_allowed {
34+
clap_complete::CompleteEnv::with_factory(|| cli::cli(&mut gctx))
35+
.var("CARGO_COMPLETE")
36+
.complete();
37+
}
38+
3139
let result = if let Some(lock_addr) = cargo::ops::fix_get_proxy_lock_addr() {
3240
cargo::ops::fix_exec_rustc(&gctx, &lock_addr).map_err(|e| CliError::from(e))
3341
} else {

src/doc/src/reference/unstable.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ Each new feature described below should explain how to use it.
116116
* [gitoxide](#gitoxide) --- Use `gitoxide` instead of `git2` for a set of operations.
117117
* [script](#script) --- Enable support for single-file `.rs` packages.
118118
* [lockfile-path](#lockfile-path) --- Allows to specify a path to lockfile other than the default path `<workspace_root>/Cargo.lock`.
119+
* [native-completions](#native-completion) --- Move cargo shell completions to native completions
119120

120121
## allow-features
121122

@@ -1643,6 +1644,27 @@ Example:
16431644
cargo +nightly metadata --lockfile-path=$LOCKFILES_ROOT/my-project/Cargo.lock -Z unstable-options
16441645
```
16451646

1647+
## native-completions
1648+
* Original Issue: [#6645](https://github.com/rust-lang/cargo/issues/6645)
1649+
* Tracking Issue: [#14520](https://github.com/rust-lang/cargo/issues/14520)
1650+
1651+
This feature moves the handwritten completion scripts to Rust native, making it
1652+
easier for us to add, extend and test new completions. This feature is enabled with the
1653+
nightly channel, without requiring additional `-Z` options.
1654+
1655+
### How to use native-completions feature:
1656+
- bash:
1657+
Add `source <(CARGO_COMPLETE=bash cargo)` to your .bashrc.
1658+
1659+
- zsh:
1660+
Add `source <(CARGO_COMPLETE=zsh cargo)` to your .zshrc.
1661+
1662+
- fish:
1663+
Add `source (CARGO_COMPLETE=fish cargo | psub)` to `$XDG_CONFIG_HOME/fish/completions/cargo.fish`
1664+
1665+
- elvish:
1666+
Add `eval (E:CARGO_COMPLETE=elvish cargo | slurp)` to `$XDG_CONFIG_HOME/elvish/rc.elv`
1667+
16461668
# Stabilized and removed features
16471669

16481670
## Compile progress
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use cargo_test_support::cargo_test;
2+
use snapbox::assert_data_eq;
3+
4+
use crate::shell_completions;
5+
6+
#[cargo_test]
7+
fn test_register_native_completions() {
8+
let input = "cargo \t\t";
9+
let expected = snapbox::str![
10+
"%
11+
--version --help check install read-manifest update
12+
--list -V clean locate-project remove vendor
13+
--explain -v config login report verify-project
14+
--verbose -q doc logout run version
15+
--quiet -C fetch metadata rustc yank
16+
--color -Z fix new rustdoc
17+
--locked -h generate-lockfile owner search
18+
--offline add help package test
19+
--frozen bench info pkgid tree
20+
--config build init publish uninstall "
21+
];
22+
let actual = shell_completions::common::complete(input, "bash");
23+
assert_data_eq!(actual, expected);
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use cargo_test_support::cargo_test;
2+
use snapbox::assert_data_eq;
3+
4+
use crate::shell_completions;
5+
6+
#[cargo_test]
7+
fn test_register_native_completions() {
8+
let input = "cargo \t\t";
9+
let expected = snapbox::str![
10+
"% cargo
11+
COMPLETING argument
12+
--color --version check install read-manifest update
13+
--config -C clean locate-project remove vendor
14+
--explain -V config login report verify-project
15+
--frozen -Z doc logout run version
16+
--help -h fetch metadata rustc yank
17+
--list -q fix new rustdoc
18+
--locked -v generate-lockfile owner search
19+
--offline add help package test
20+
--quiet bench info pkgid tree
21+
--verbose build init publish uninstall "
22+
];
23+
let actual = shell_completions::common::complete(input, "elvish");
24+
assert_data_eq!(actual, expected);
25+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use cargo_test_support::cargo_test;
2+
use snapbox::assert_data_eq;
3+
4+
use crate::shell_completions;
5+
6+
#[cargo_test]
7+
fn test_register_native_completions() {
8+
let input = "cargo \t\t";
9+
let expected = snapbox::str![
10+
"% cargo
11+
--version (Print version info and exit)
12+
--list (List installed commands)
13+
--explain (Provide a detailed explanation of a rustc error message)
14+
--verbose (Use verbose output (-vv very verbose/build.rs output))
15+
--quiet (Do not print cargo log messages)
16+
--color (Coloring: auto, always, never)
17+
--locked (Assert that `Cargo.lock` will remain unchanged)
18+
--offline (Run without accessing the network)
19+
--frozen (Equivalent to specifying both --locked and --offline)
20+
--config (Override a configuration value)
21+
--help (Print help)
22+
-V (Print version info and exit)
23+
-v (Use verbose output (-vv very verbose/build.rs output))
24+
-q (Do not print cargo log messages)
25+
-C (Change to DIRECTORY before doing anything (nightly-only))
26+
-Z (Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details)
27+
-h (Print help)
28+
add (Add dependencies to a Cargo.toml manifest file)
29+
bench (Execute all benchmarks of a local package)
30+
build (Compile a local package and all of its dependencies)
31+
check (Check a local package and all of its dependencies for errors)
32+
clean (Remove artifacts that cargo has generated in the past)
33+
config (Inspect configuration values)
34+
doc (Build a package's documentation)
35+
fetch (Fetch dependencies of a package from the network)
36+
fix (Automatically fix lint warnings reported by rustc)
37+
generate-lockfile (Generate the lockfile for a package)
38+
help (Displays help for a cargo subcommand)
39+
info (Display information about a package in the registry)
40+
init (Create a new cargo package in an existing directory)
41+
install (Install a Rust binary)
42+
locate-project (Print a JSON representation of a Cargo.toml file's location)
43+
login (Log in to a registry.)
44+
logout (Remove an API token from the registry locally)
45+
metadata (Output the resolved dependencies of a package, the concrete used versions including overrides, in machine-r…)
46+
new (Create a new cargo package at <path>)
47+
owner (Manage the owners of a crate on the registry)
48+
package (Assemble the local package into a distributable tarball)
49+
pkgid (Print a fully qualified package specification)
50+
publish (Upload a package to the registry)
51+
read-manifest (Print a JSON representation of a Cargo.toml manifest.)
52+
remove (Remove dependencies from a Cargo.toml manifest file)
53+
report (Generate and display various kinds of reports)
54+
run (Run a binary or example of the local package)
55+
rustc (Compile a package, and pass extra options to the compiler)
56+
rustdoc (Build a package's documentation, using specified custom flags.)
57+
search (Search packages in the registry. Default registry is crates.io)
58+
test (Execute all unit and integration tests and build examples of a local package)
59+
tree (Display a tree visualization of a dependency graph)
60+
uninstall (Remove a Rust binary)
61+
update (Update dependencies as recorded in the local lock file)
62+
vendor (Vendor all dependencies for a project locally)
63+
verify-project (Check correctness of crate manifest)
64+
version (Show version information)
65+
yank (Remove a pushed crate from the index)"];
66+
67+
let actual = shell_completions::common::complete(input, "fish");
68+
assert_data_eq!(actual, expected);
69+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
pub mod common;
22

3+
mod bash;
4+
mod elvish;
5+
mod fish;
6+
mod zsh;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use cargo_test_support::cargo_test;
2+
use snapbox::assert_data_eq;
3+
4+
use crate::shell_completions;
5+
6+
#[cargo_test]
7+
fn test_register_native_completions() {
8+
let input = "cargo \t\t";
9+
let expected = snapbox::str![
10+
"% cargo
11+
--color --version check install read-manifest update
12+
--config -C clean locate-project remove vendor
13+
--explain -V config login report verify-project
14+
--frozen -Z doc logout run version
15+
--help -h fetch metadata rustc yank
16+
--list -q fix new rustdoc
17+
--locked -v generate-lockfile owner search
18+
--offline add help package test
19+
--quiet bench info pkgid tree
20+
--verbose build init publish uninstall "
21+
];
22+
let actual = shell_completions::common::complete(input, "zsh");
23+
assert_data_eq!(actual, expected);
24+
}

0 commit comments

Comments
 (0)