Skip to content

Commit 01a2283

Browse files
committed
feat(cli): generate autocomplete shell stuff via -c | --completions argument (#37)
Signed-off-by: Sven Kanoldt <[email protected]>
1 parent de238f7 commit 01a2283

File tree

4 files changed

+57
-12
lines changed

4 files changed

+57
-12
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

curlz/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ include = ["src/**/*", "LICENSE", "*.md"]
1111
env_logger = "0.10"
1212
log = "0.4"
1313
clap = { version = "4.1", features = ["derive", "std", "cargo", "usage", "help"] }
14-
#clap_complete = "4.1"
14+
clap_complete = "4.1"
1515
clap-verbosity-flag = "2.0"
1616
serde = { version = "1.0", features = ["derive"] }
1717
serde_yaml = "0.9"

curlz/src/curlz/cli/execute.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
use super::sub_commands::*;
22

3-
use clap::Parser;
3+
use clap::{Command, CommandFactory, Parser};
4+
use clap_complete::{generate, generator::Generator, Shell};
45
use clap_verbosity_flag::{InfoLevel, Verbosity};
56
use env_logger::Target;
67

78
#[derive(Clone, Debug, Parser)]
89
#[command(author, version, about, long_about = None )]
9-
#[clap(subcommand_required = true, arg_required_else_help = true)]
10+
#[command(arg_required_else_help = true)]
1011
#[command(propagate_version = true)]
1112
#[command(name = "curlz")]
1213
pub struct Cli {
14+
/// increased verbosity will show more debug output of curlz itself
1315
#[command(flatten)]
1416
verbose: Verbosity<InfoLevel>,
17+
18+
/// Generate a SHELL completion script and print to stdout
19+
#[clap(long, short, value_name = "SHELL")]
20+
pub completions: Option<Shell>,
21+
1522
#[command(subcommand)]
16-
pub command: SubCommands,
23+
pub cmd: Option<SubCommands>,
1724
}
1825

1926
pub fn execute() -> crate::Result<()> {
@@ -23,12 +30,26 @@ pub fn execute() -> crate::Result<()> {
2330
.target(Target::Stderr)
2431
.init();
2532

26-
match args.command {
27-
SubCommands::Request(ref r) => r.execute(),
28-
SubCommands::Bookmark(_b) => {
29-
todo!()
33+
if let Some(shell) = args.completions {
34+
let mut cmd = Cli::command();
35+
print_completions(shell, &mut cmd);
36+
std::process::exit(0);
37+
}
38+
39+
if let Some(cmd) = &args.cmd {
40+
match cmd {
41+
SubCommands::Request(ref r) => r.execute(),
42+
SubCommands::Bookmark(_b) => {
43+
todo!()
44+
}
45+
#[cfg(feature = "x-http-lang")]
46+
SubCommands::HttpFile(ref hf) => hf.execute(),
3047
}
31-
#[cfg(feature = "x-http-lang")]
32-
SubCommands::HttpFile(ref hf) => hf.execute(),
48+
} else {
49+
Ok(())
3350
}
3451
}
52+
53+
fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
54+
generate(gen, cmd, cmd.get_name().to_string(), &mut std::io::stdout());
55+
}

curlz/tests/basics.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,27 @@ mod testlib;
99
#[test]
1010
fn should_show_usage_when_no_args_passed() {
1111
#[cfg(windows)]
12-
let pattern = predicate::str::contains("Usage: curlz.exe [OPTIONS] <COMMAND>");
12+
let pattern = predicate::str::contains("Usage: curlz.exe [OPTIONS] [COMMAND]");
1313
#[cfg(not(windows))]
14-
let pattern = predicate::str::contains("Usage: curlz [OPTIONS] <COMMAND>");
14+
let pattern = predicate::str::contains("Usage: curlz [OPTIONS] [COMMAND]");
1515

1616
binary().assert().failure().stderr(pattern);
1717
}
1818

19+
#[test]
20+
fn should_show_completions() {
21+
#[cfg(windows)]
22+
let pattern = predicate::str::contains("#compdef curlz");
23+
#[cfg(not(windows))]
24+
let pattern = predicate::str::contains("#compdef curlz");
25+
26+
binary()
27+
.args(["--completions", "zsh"])
28+
.assert()
29+
.success()
30+
.stdout(pattern);
31+
}
32+
1933
#[tokio::test]
2034
async fn should_send_as_get() {
2135
CurlzTestSuite::new()

0 commit comments

Comments
 (0)