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

Generate subcommand alias #4289

Merged
merged 10 commits into from
Sep 29, 2022
18 changes: 15 additions & 3 deletions clap_complete/examples/completion-derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,30 @@
//! . ./value_hints_derive.fish
//! ./target/debug/examples/value_hints_derive --<TAB>
//! ```
use clap::{Command, CommandFactory, Parser, ValueHint};
use clap::{Args, Command, CommandFactory, Parser, Subcommand, ValueHint};
use clap_complete::{generate, Generator, Shell};
use std::ffi::OsString;
use std::io;
use std::path::PathBuf;

#[derive(Parser, Debug, PartialEq)]
#[command(name = "value_hints_derive")]
#[command(name = "completion-derive")]
struct Opt {
/// If provided, outputs the completion file for given shell
// If provided, outputs the completion file for given shell
#[arg(long = "generate", value_enum)]
generator: Option<Shell>,
#[clap(subcommand)]
command: Option<Commands>,
}

#[derive(Subcommand, Debug, PartialEq)]
enum Commands {
#[clap(visible_alias = "hint")]
ValueHint(ValueHintOpt),
}

#[derive(Args, Debug, PartialEq)]
struct ValueHintOpt {
// Showcasing all possible ValueHints:
#[arg(long, value_hint = ValueHint::Unknown)]
unknown: Option<String>,
Expand Down
16 changes: 10 additions & 6 deletions clap_complete/examples/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,8 @@ use clap_complete::{generate, Generator, Shell};
use std::io;

fn build_cli() -> Command {
Command::new("value_hints")
.arg(
Arg::new("generator")
.long("generate")
.value_parser(value_parser!(Shell)),
)
let value_hint_command = Command::new("value-hint")
.visible_alias("hint")
.arg(
Arg::new("unknown")
.long("unknown")
Expand Down Expand Up @@ -87,7 +83,15 @@ fn build_cli() -> Command {
Arg::new("email")
.long("email")
.value_hint(ValueHint::EmailAddress),
);

Command::new("completion")
.arg(
Arg::new("generator")
.long("generate")
.value_parser(value_parser!(Shell)),
)
.subcommand(value_hint_command)
}

fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
Expand Down
4 changes: 0 additions & 4 deletions clap_complete/src/generator/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ pub fn subcommands(p: &Command) -> Vec<(String, String)> {

let mut subcmds = vec![];

if !p.has_subcommands() {
return subcmds;
}

for sc in p.get_subcommands() {
let sc_bin_name = sc.get_bin_name().unwrap();

Expand Down
64 changes: 45 additions & 19 deletions clap_complete/src/shells/bash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ impl Generator for Bash {

for i in ${{COMP_WORDS[@]}}
do
case \"${{i}}\" in
\"$1\")
case \"${{cmd}},${{i}}\" in
\",$1\")
cmd=\"{cmd}\"
;;{subcmds}
*)
Expand Down Expand Up @@ -75,26 +75,52 @@ complete -F _{name} -o bashdefault -o default {name}
fn all_subcommands(cmd: &Command) -> String {
debug!("all_subcommands");

let mut subcmds = vec![String::new()];
let mut scs = utils::all_subcommands(cmd)
.iter()
.map(|x| x.0.clone())
.collect::<Vec<_>>();

scs.sort();
scs.dedup();
fn add_command(
parent_fn_name: &str,
cmd: &Command,
subcmds: &mut Vec<(String, String, String)>,
) {
let fn_name = format!(
"{parent_fn_name}__{cmd_name}",
parent_fn_name = parent_fn_name,
cmd_name = cmd.get_name().to_string().replace('-', "__")
);
subcmds.push((
parent_fn_name.to_string(),
cmd.get_name().to_string(),
fn_name.clone(),
));
for alias in cmd.get_visible_aliases() {
subcmds.push((
parent_fn_name.to_string(),
alias.to_string(),
fn_name.clone(),
));
}
for subcmd in cmd.get_subcommands() {
add_command(&fn_name, subcmd, subcmds);
}
}
let mut subcmds = vec![];
let fn_name = cmd.get_name().replace('-', "__");
for subcmd in cmd.get_subcommands() {
add_command(&fn_name, subcmd, &mut subcmds);
}
subcmds.sort();

subcmds.extend(scs.iter().map(|sc| {
format!(
"{name})
cmd+=\"__{fn_name}\"
let mut cases = vec![String::new()];
for (parent_fn_name, name, fn_name) in subcmds {
cases.push(format!(
"{parent_fn_name},{name})
cmd=\"{fn_name}\"
;;",
name = sc,
fn_name = sc.replace('-', "__")
)
}));
parent_fn_name = parent_fn_name,
name = name,
fn_name = fn_name,
));
}

subcmds.join("\n ")
cases.join("\n ")
}

fn subcommand_details(cmd: &Command) -> String {
Expand Down
4 changes: 1 addition & 3 deletions clap_complete/src/shells/zsh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,7 @@ fn subcommands_of(p: &Command) -> String {
help = escape_help(&subcommand.get_about().unwrap_or_default().to_string())
);

if !text.is_empty() {
ret.push(text);
}
ret.push(text);
}

// The subcommands
Expand Down
1 change: 1 addition & 0 deletions clap_complete/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ pub fn sub_subcommands_command(name: &'static str) -> clap::Command {
feature_sample_command(name).subcommand(
clap::Command::new("some_cmd")
.about("top level subcommand")
.visible_alias("some_cmd_alias")
.subcommand(
clap::Command::new("sub_cmd").about("sub-subcommand").arg(
clap::Arg::new("config")
Expand Down
4 changes: 2 additions & 2 deletions clap_complete/tests/snapshots/aliases.bash
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ _my-app() {

for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
case "${cmd},${i}" in
",$1")
cmd="my__app"
;;
*)
Expand Down
18 changes: 12 additions & 6 deletions clap_complete/tests/snapshots/basic.bash
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ _my-app() {

for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
case "${cmd},${i}" in
",$1")
cmd="my__app"
;;
help)
cmd+="__help"
my__app,help)
cmd="my__app__help"
;;
test)
cmd+="__test"
my__app,test)
cmd="my__app__test"
;;
my__app__help,help)
cmd="my__app__help__help"
;;
my__app__help,test)
cmd="my__app__help__test"
;;
*)
;;
Expand Down
18 changes: 12 additions & 6 deletions clap_complete/tests/snapshots/feature_sample.bash
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ _my-app() {

for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
case "${cmd},${i}" in
",$1")
cmd="my__app"
;;
help)
cmd+="__help"
my__app,help)
cmd="my__app__help"
;;
test)
cmd+="__test"
my__app,test)
cmd="my__app__test"
;;
my__app__help,help)
cmd="my__app__help__help"
;;
my__app__help,test)
cmd="my__app__help__test"
;;
*)
;;
Expand Down
53 changes: 37 additions & 16 deletions clap_complete/tests/snapshots/quoting.bash
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,51 @@ _my-app() {

for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
case "${cmd},${i}" in
",$1")
cmd="my__app"
;;
cmd-backslash)
cmd+="__cmd__backslash"
my__app,cmd-backslash)
cmd="my__app__cmd__backslash"
;;
cmd-backticks)
cmd+="__cmd__backticks"
my__app,cmd-backticks)
cmd="my__app__cmd__backticks"
;;
cmd-brackets)
cmd+="__cmd__brackets"
my__app,cmd-brackets)
cmd="my__app__cmd__brackets"
;;
cmd-double-quotes)
cmd+="__cmd__double__quotes"
my__app,cmd-double-quotes)
cmd="my__app__cmd__double__quotes"
;;
cmd-expansions)
cmd+="__cmd__expansions"
my__app,cmd-expansions)
cmd="my__app__cmd__expansions"
;;
cmd-single-quotes)
cmd+="__cmd__single__quotes"
my__app,cmd-single-quotes)
cmd="my__app__cmd__single__quotes"
;;
help)
cmd+="__help"
my__app,help)
cmd="my__app__help"
;;
my__app__help,cmd-backslash)
cmd="my__app__help__cmd__backslash"
;;
my__app__help,cmd-backticks)
cmd="my__app__help__cmd__backticks"
;;
my__app__help,cmd-brackets)
cmd="my__app__help__cmd__brackets"
;;
my__app__help,cmd-double-quotes)
cmd="my__app__help__cmd__double__quotes"
;;
my__app__help,cmd-expansions)
cmd="my__app__help__cmd__expansions"
;;
my__app__help,cmd-single-quotes)
cmd="my__app__help__cmd__single__quotes"
;;
my__app__help,help)
cmd="my__app__help__help"
;;
*)
;;
Expand Down
39 changes: 27 additions & 12 deletions clap_complete/tests/snapshots/special_commands.bash
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,39 @@ _my-app() {

for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
case "${cmd},${i}" in
",$1")
cmd="my__app"
;;
help)
cmd+="__help"
my__app,help)
cmd="my__app__help"
;;
some-cmd-with-hyphens)
cmd+="__some__cmd__with__hyphens"
my__app,some-cmd-with-hyphens)
cmd="my__app__some__cmd__with__hyphens"
;;
some-hidden-cmd)
cmd+="__some__hidden__cmd"
my__app,some-hidden-cmd)
cmd="my__app__some__hidden__cmd"
;;
some_cmd)
cmd+="__some_cmd"
my__app,some_cmd)
cmd="my__app__some_cmd"
;;
test)
cmd+="__test"
my__app,test)
cmd="my__app__test"
;;
my__app__help,help)
cmd="my__app__help__help"
;;
my__app__help,some-cmd-with-hyphens)
cmd="my__app__help__some__cmd__with__hyphens"
;;
my__app__help,some-hidden-cmd)
cmd="my__app__help__some__hidden__cmd"
;;
my__app__help,some_cmd)
cmd="my__app__help__some_cmd"
;;
my__app__help,test)
cmd="my__app__help__test"
;;
*)
;;
Expand Down