mirror of
https://github.com/clap-rs/clap
synced 2024-11-15 00:57:15 +00:00
commit
50ca205e3b
5 changed files with 127 additions and 10 deletions
|
@ -548,9 +548,24 @@ impl<'a> Help<'a> {
|
|||
|
||||
let mut ord_m = VecMap::new();
|
||||
for sc in parser.subcommands.iter().filter(|s| !s.p.is_set(AppSettings::Hidden)) {
|
||||
let sc = if let Some(ref aliases) = sc.p.meta.aliases {
|
||||
let mut a = App::new(format!("{}|{}", &*sc.p.meta.name, aliases.iter()
|
||||
.filter(|&&(_, vis)| vis)
|
||||
.map(|&(n, _)| n)
|
||||
.collect::<Vec<_>>()
|
||||
.join("|")));
|
||||
a = if let Some(about) = sc.p.meta.about {
|
||||
a.about(about)
|
||||
} else {
|
||||
a
|
||||
};
|
||||
a
|
||||
} else {
|
||||
sc.clone()
|
||||
};
|
||||
let btm = ord_m.entry(sc.p.meta.disp_ord).or_insert(BTreeMap::new());
|
||||
btm.insert(sc.p.meta.name.clone(), sc);
|
||||
longest = cmp::max(longest, sc.p.meta.name.len());
|
||||
btm.insert(sc.p.meta.name.clone(), sc.clone());
|
||||
}
|
||||
|
||||
let mut first = true;
|
||||
|
@ -561,7 +576,7 @@ impl<'a> Help<'a> {
|
|||
} else {
|
||||
first = false;
|
||||
}
|
||||
try!(self.write_arg(sc, longest));
|
||||
try!(self.write_arg(&sc, longest));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -8,7 +8,7 @@ pub struct AppMeta<'b> {
|
|||
pub about: Option<&'b str>,
|
||||
pub more_help: Option<&'b str>,
|
||||
pub pre_help: Option<&'b str>,
|
||||
pub aliases: Option<Vec<&'b str>>,
|
||||
pub aliases: Option<Vec<(&'b str, bool)>>, // (name, visible)
|
||||
pub usage_str: Option<&'b str>,
|
||||
pub usage: Option<String>,
|
||||
pub help_str: Option<&'b str>,
|
||||
|
|
|
@ -602,9 +602,9 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// [`SubCommand`]: ./struct.SubCommand.html
|
||||
pub fn alias<S: Into<&'b str>>(mut self, name: S) -> Self {
|
||||
if let Some(ref mut als) = self.p.meta.aliases {
|
||||
als.push(name.into());
|
||||
als.push((name.into(), false));
|
||||
} else {
|
||||
self.p.meta.aliases = Some(vec![name.into()]);
|
||||
self.p.meta.aliases = Some(vec![(name.into(), false)]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -632,10 +632,60 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
pub fn aliases(mut self, names: &[&'b str]) -> Self {
|
||||
if let Some(ref mut als) = self.p.meta.aliases {
|
||||
for n in names {
|
||||
als.push(n);
|
||||
als.push((n, false));
|
||||
}
|
||||
} else {
|
||||
self.p.meta.aliases = Some(names.iter().map(|n| *n).collect::<Vec<_>>());
|
||||
self.p.meta.aliases = Some(names.iter().map(|n| (*n, false)).collect::<Vec<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Allows adding a [`SubCommand`] alias that functions exactly like those defined with
|
||||
/// [`App::alias`], except that they are visible inside the help message.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// let m = App::new("myprog")
|
||||
/// .subcommand(SubCommand::with_name("test")
|
||||
/// .visible_alias("do-stuff"))
|
||||
/// .get_matches_from(vec!["myprog", "do-stuff"]);
|
||||
/// assert_eq!(m.subcommand_name(), Some("test"));
|
||||
/// ```
|
||||
/// [`SubCommand`]: ./struct.SubCommand.html
|
||||
/// [`App::alias`]: ./struct.App.html#method.alias
|
||||
pub fn visible_alias<S: Into<&'b str>>(mut self, name: S) -> Self {
|
||||
if let Some(ref mut als) = self.p.meta.aliases {
|
||||
als.push((name.into(), true));
|
||||
} else {
|
||||
self.p.meta.aliases = Some(vec![(name.into(), true)]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Allows adding multiple [`SubCommand`] aliases that functions exactly like those defined
|
||||
/// with [`App::aliases`], except that they are visible inside the help message.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// let m = App::new("myprog")
|
||||
/// .subcommand(SubCommand::with_name("test")
|
||||
/// .visible_aliases(&["do-stuff", "tests"]))
|
||||
/// .get_matches_from(vec!["myprog", "do-stuff"]);
|
||||
/// assert_eq!(m.subcommand_name(), Some("test"));
|
||||
/// ```
|
||||
/// [`SubCommand`]: ./struct.SubCommand.html
|
||||
/// [`App::aliases`]: ./struct.App.html#method.aliases
|
||||
pub fn visible_aliases(mut self, names: &[&'b str]) -> Self {
|
||||
if let Some(ref mut als) = self.p.meta.aliases {
|
||||
for n in names {
|
||||
als.push((n, true));
|
||||
}
|
||||
} else {
|
||||
self.p.meta.aliases = Some(names.iter().map(|n| (*n, true)).collect::<Vec<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
|
|
@ -485,7 +485,7 @@ impl<'a, 'b> Parser<'a, 'b>
|
|||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|&a| a == &*arg_os)));
|
||||
.any(|&(a, _)| a == &*arg_os)));
|
||||
if (!starts_new_arg || self.is_set(AppSettings::AllowLeadingHyphen)) && !pos_sc {
|
||||
// Check to see if parsing a value from an option
|
||||
if let Some(nvo) = needs_val_of {
|
||||
|
@ -530,6 +530,24 @@ impl<'a, 'b> Parser<'a, 'b>
|
|||
if i == cmds.len() - 1 {
|
||||
break;
|
||||
}
|
||||
} else if let Some(c) = sc.subcommands
|
||||
.iter()
|
||||
.filter(|s|
|
||||
if let Some(ref als) = s.p
|
||||
.meta
|
||||
.aliases {
|
||||
als.iter()
|
||||
.any(|&(a, _)| &a == &&*cmd.to_string_lossy())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
)
|
||||
.next()
|
||||
.map(|sc| &sc.p) {
|
||||
sc = c;
|
||||
if i == cmds.len() - 1 {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return Err(
|
||||
Error::unrecognized_subcommand(
|
||||
|
@ -638,7 +656,7 @@ impl<'a, 'b> Parser<'a, 'b>
|
|||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|&a| a == &*pos_sc_name) {
|
||||
.any(|&(a, _)| &a == &&*pos_sc_name) {
|
||||
Some(sc.p.meta.name.clone())
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -3,7 +3,20 @@ extern crate regex;
|
|||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
use clap::{App, Arg, SubCommand};
|
||||
use clap::{App, Arg, SubCommand, ErrorKind};
|
||||
|
||||
static VISIBLE_ALIAS_HELP: &'static str = "clap-test 2.6
|
||||
|
||||
USAGE:
|
||||
clap-test [FLAGS] [SUBCOMMAND]
|
||||
|
||||
FLAGS:
|
||||
-h, --help Prints help information
|
||||
-V, --version Prints version information
|
||||
|
||||
SUBCOMMANDS:
|
||||
help Prints this message or the help of the given subcommand(s)
|
||||
vim|vi Some help";
|
||||
|
||||
#[test]
|
||||
fn subcommand() {
|
||||
|
@ -93,3 +106,24 @@ USAGE:
|
|||
|
||||
For more information try --help", true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alias_help() {
|
||||
let m = App::new("myprog")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.alias("do-stuff"))
|
||||
.get_matches_from_safe(vec!["myprog", "help", "do-stuff"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn visible_aliases_help_output() {
|
||||
let app = App::new("clap-test")
|
||||
.version("2.6")
|
||||
.subcommand(SubCommand::with_name("vim")
|
||||
.about("Some help")
|
||||
.alias("invisible")
|
||||
.visible_alias("vi"));
|
||||
test::check_help(app, VISIBLE_ALIAS_HELP);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue