mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 06:42:33 +00:00
Added helper methods to generator
This commit is contained in:
parent
33f47acc67
commit
e6f77a8713
9 changed files with 293 additions and 173 deletions
11
clap_generate/examples/bash_completion.rs
Normal file
11
clap_generate/examples/bash_completion.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use clap::App;
|
||||
use clap_generate::{generate, generators::Bash};
|
||||
use std::io;
|
||||
|
||||
fn main() {
|
||||
let mut app = App::new("myapp")
|
||||
.subcommand(App::new("test").subcommand(App::new("config")))
|
||||
.subcommand(App::new("hello"));
|
||||
|
||||
generate::<Bash, _>(&mut app, "myapp", &mut io::stdout());
|
||||
}
|
|
@ -5,7 +5,6 @@ use std::io::Write;
|
|||
|
||||
// Internal
|
||||
use clap::*;
|
||||
|
||||
pub use shells::*;
|
||||
|
||||
/// Generator trait which can be used to write generators
|
||||
|
@ -55,39 +54,12 @@ pub trait Generator {
|
|||
/// ```
|
||||
fn generate(app: &App, buf: &mut dyn Write);
|
||||
|
||||
/// Gets all subcommands including child subcommands in the form of 'name' where the name
|
||||
/// is a single word (i.e. "install") of the path to said subcommand (i.e.
|
||||
/// "rustup toolchain install")
|
||||
/// Gets all subcommands including child subcommands in the form of `("name", "bin_name")`.
|
||||
///
|
||||
/// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
|
||||
/// aliasing.
|
||||
fn all_subcommand_names(app: &App) -> Vec<String> {
|
||||
debugln!("all_subcommand_names;");
|
||||
|
||||
let mut subcmds: Vec<_> = Self::subcommands_of(app)
|
||||
.iter()
|
||||
.map(|&(ref n, _)| n.clone())
|
||||
.collect();
|
||||
|
||||
for sc_v in subcommands!(app).map(|s| Self::all_subcommand_names(&s)) {
|
||||
subcmds.extend(sc_v);
|
||||
}
|
||||
|
||||
subcmds.sort();
|
||||
subcmds.dedup();
|
||||
subcmds
|
||||
}
|
||||
|
||||
/// Gets all subcommands including child subcommands in the form of ('name', 'bin_name') where the name
|
||||
/// is a single word (i.e. "install") of the path and full bin_name of said subcommand (i.e.
|
||||
/// "rustup toolchain install")
|
||||
///
|
||||
/// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
|
||||
/// aliasing.
|
||||
/// Subcommand `rustup toolchain install` would be converted to
|
||||
/// `("install", "rustup toolchain install")`.
|
||||
fn all_subcommands(app: &App) -> Vec<(String, String)> {
|
||||
debugln!("all_subcommands;");
|
||||
|
||||
let mut subcmds: Vec<_> = Self::subcommands_of(app);
|
||||
let mut subcmds: Vec<_> = Self::subcommands(app);
|
||||
|
||||
for sc_v in subcommands!(app).map(|s| Self::all_subcommands(&s)) {
|
||||
subcmds.extend(sc_v);
|
||||
|
@ -96,120 +68,256 @@ pub trait Generator {
|
|||
subcmds
|
||||
}
|
||||
|
||||
/// Gets all subcommands exlcuding child subcommands in the form of (name, bin_name) where the name
|
||||
/// is a single word (i.e. "install") and the bin_name is a space deliniated list of the path to said
|
||||
/// subcommand (i.e. "rustup toolchain install")
|
||||
/// Finds the subcommand [`clap::App`][clap] from the given [`clap::App`][clap] with the given path.
|
||||
///
|
||||
/// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
|
||||
/// aliasing.
|
||||
fn subcommands_of(p: &App) -> Vec<(String, String)> {
|
||||
debugln!(
|
||||
"subcommands_of: name={}, bin_name={}",
|
||||
p.name,
|
||||
p.bin_name.as_ref().unwrap()
|
||||
);
|
||||
debugln!(
|
||||
"subcommands_of: Has subcommands...{:?}",
|
||||
p.has_subcommands()
|
||||
);
|
||||
/// **NOTE:** `path` should not contain the root `bin_name`.
|
||||
///
|
||||
/// [clap]: ../clap/struct.App.html
|
||||
fn find_subcommand_with_path<'b>(p: &'b App<'b>, path: Vec<&str>) -> &'b App<'b> {
|
||||
let mut app = p;
|
||||
|
||||
for sc in path {
|
||||
app = find_subcmd!(app, sc).unwrap();
|
||||
}
|
||||
|
||||
app
|
||||
}
|
||||
|
||||
/// Gets subcommands of [`clap::App`](../clap/struct.App.html) in the form of `("name", "bin_name")`.
|
||||
///
|
||||
/// Subcommand `rustup toolchain install` would be converted to
|
||||
/// `("install", "rustup toolchain install")`.
|
||||
fn subcommands(p: &App) -> Vec<(String, String)> {
|
||||
debugln!("subcommands: name={}", p.name);
|
||||
debugln!("subcommands: Has subcommands...{:?}", p.has_subcommands());
|
||||
|
||||
let mut subcmds = vec![];
|
||||
|
||||
if !p.has_subcommands() {
|
||||
let mut ret = vec![];
|
||||
|
||||
debugln!("subcommands_of: Looking for aliases...");
|
||||
|
||||
if let Some(ref aliases) = p.aliases {
|
||||
for &(n, _) in aliases {
|
||||
debugln!("subcommands_of:iter:iter: Found alias...{}", n);
|
||||
|
||||
let mut als_bin_name: Vec<_> =
|
||||
p.bin_name.as_ref().unwrap().split(' ').collect();
|
||||
|
||||
als_bin_name.push(n);
|
||||
|
||||
let old = als_bin_name.len() - 2;
|
||||
|
||||
als_bin_name.swap_remove(old);
|
||||
ret.push((n.to_owned(), als_bin_name.join(" ")));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return subcmds;
|
||||
}
|
||||
|
||||
for sc in subcommands!(p) {
|
||||
for sc in &p.subcommands {
|
||||
let sc_bin_name = sc.get_bin_name().unwrap();
|
||||
|
||||
debugln!(
|
||||
"subcommands_of:iter: name={}, bin_name={}",
|
||||
"subcommands:iter: name={}, bin_name={}",
|
||||
sc.name,
|
||||
sc.bin_name.as_ref().unwrap()
|
||||
sc_bin_name
|
||||
);
|
||||
debugln!("subcommands_of:iter: Looking for aliases...");
|
||||
|
||||
if let Some(ref aliases) = sc.aliases {
|
||||
for &(n, _) in aliases {
|
||||
debugln!("subcommands_of:iter:iter: Found alias...{}", n);
|
||||
|
||||
let mut als_bin_name: Vec<_> =
|
||||
p.bin_name.as_ref().unwrap().split(' ').collect();
|
||||
|
||||
als_bin_name.push(n);
|
||||
|
||||
let old = als_bin_name.len() - 2;
|
||||
|
||||
als_bin_name.swap_remove(old);
|
||||
subcmds.push((n.to_owned(), als_bin_name.join(" ")));
|
||||
}
|
||||
}
|
||||
|
||||
subcmds.push((sc.name.clone(), sc.get_bin_name().unwrap().to_string()));
|
||||
subcmds.push((sc.name.clone(), sc_bin_name.to_string()));
|
||||
}
|
||||
|
||||
subcmds
|
||||
}
|
||||
|
||||
/// TODO
|
||||
fn get_all_subcommand_paths(p: &App, first: bool) -> Vec<String> {
|
||||
debugln!("get_all_subcommand_paths;");
|
||||
/// Gets all the short options and flags of a [`clap::App`](../clap/struct.App.html).
|
||||
/// Includes `h` and `V` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html).
|
||||
fn shorts<'b>(p: &'b App<'b>) -> Vec<char> {
|
||||
debugln!("shorts: name={}", p.name);
|
||||
|
||||
let mut subcmds = vec![];
|
||||
|
||||
if !p.has_subcommands() {
|
||||
if !first {
|
||||
let name = &*p.name;
|
||||
let path = p.get_bin_name().unwrap().to_string().replace(" ", "__");
|
||||
let mut ret = vec![path.clone()];
|
||||
|
||||
if let Some(ref aliases) = p.aliases {
|
||||
for &(n, _) in aliases {
|
||||
ret.push(path.replace(name, n));
|
||||
}
|
||||
let mut shorts: Vec<char> = p
|
||||
.args
|
||||
.args
|
||||
.iter()
|
||||
.filter_map(|a| {
|
||||
if a.index.is_none() && a.short.is_some() {
|
||||
Some(a.short.unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return vec![];
|
||||
if shorts.iter().find(|x| **x == 'h').is_none() {
|
||||
shorts.push('h');
|
||||
}
|
||||
|
||||
for sc in subcommands!(p) {
|
||||
let name = &*sc.name;
|
||||
let path = sc.get_bin_name().unwrap().to_string().replace(" ", "__");
|
||||
if !p.is_set(AppSettings::DisableVersion) && shorts.iter().find(|x| **x == 'V').is_none() {
|
||||
shorts.push('V');
|
||||
}
|
||||
|
||||
subcmds.push(path.clone());
|
||||
shorts
|
||||
}
|
||||
|
||||
if let Some(ref aliases) = sc.aliases {
|
||||
for &(n, _) in aliases {
|
||||
subcmds.push(path.replace(name, n));
|
||||
/// Gets all the long options and flags of a [`clap::App`](../clap/struct.App.html).
|
||||
/// Includes `help` and `version` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html).
|
||||
fn longs<'b>(p: &'b App<'b>) -> Vec<String> {
|
||||
debugln!("longs: name={}", p.name);
|
||||
|
||||
let mut longs: Vec<String> = p
|
||||
.args
|
||||
.args
|
||||
.iter()
|
||||
.filter_map(|a| {
|
||||
if a.index.is_none() && a.long.is_some() {
|
||||
Some(a.long.unwrap().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
if longs.iter().find(|x| **x == "help").is_none() {
|
||||
longs.push(String::from("help"));
|
||||
}
|
||||
|
||||
for sc_v in subcommands!(p).map(|s| Self::get_all_subcommand_paths(&s, false)) {
|
||||
subcmds.extend(sc_v);
|
||||
if !p.is_set(AppSettings::DisableVersion)
|
||||
&& longs.iter().find(|x| **x == "version").is_none()
|
||||
{
|
||||
longs.push(String::from("version"));
|
||||
}
|
||||
|
||||
subcmds
|
||||
longs
|
||||
}
|
||||
|
||||
/// Gets all the flags of a [`clap::App`](../clap/struct.App.html).
|
||||
/// Includes `help` and `version` depending on the [`clap::AppSettings`](../clap/enum.AppSettings.html).
|
||||
fn flags<'b>(p: &'b App<'b>) -> Vec<Arg> {
|
||||
debugln!("flags: name={}", p.name);
|
||||
|
||||
let mut flags: Vec<_> = flags!(p).cloned().collect();
|
||||
|
||||
if flags.iter().find(|x| x.name == "help").is_none() {
|
||||
flags.push(
|
||||
Arg::with_name("help")
|
||||
.short('h')
|
||||
.long("help")
|
||||
.help("Prints help information"),
|
||||
);
|
||||
}
|
||||
|
||||
if !p.is_set(AppSettings::DisableVersion)
|
||||
&& flags.iter().find(|x| x.name == "version").is_none()
|
||||
{
|
||||
flags.push(
|
||||
Arg::with_name("version")
|
||||
.short('V')
|
||||
.long("version")
|
||||
.help("Prints version information"),
|
||||
);
|
||||
}
|
||||
|
||||
flags
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Generator for Foo {
|
||||
fn generate(_: &App, _: &mut dyn Write) {}
|
||||
|
||||
fn file_name(name: &str) -> String {
|
||||
name.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn common() -> App<'static> {
|
||||
let mut app = App::new("myapp")
|
||||
.subcommand(
|
||||
App::new("test")
|
||||
.subcommand(App::new("config"))
|
||||
.arg(Arg::with_name("file").short('f').long("file")),
|
||||
)
|
||||
.subcommand(App::new("hello"))
|
||||
.bin_name("my-app");
|
||||
|
||||
app._build();
|
||||
app._build_bin_names();
|
||||
app
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subcommands() {
|
||||
let app = common();
|
||||
|
||||
assert_eq!(
|
||||
Foo::subcommands(&app),
|
||||
vec![
|
||||
("test".to_string(), "my-app test".to_string()),
|
||||
("hello".to_string(), "my-app hello".to_string()),
|
||||
("help".to_string(), "my-app help".to_string()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_subcommands() {
|
||||
let app = common();
|
||||
|
||||
assert_eq!(
|
||||
Foo::all_subcommands(&app),
|
||||
vec![
|
||||
("test".to_string(), "my-app test".to_string()),
|
||||
("hello".to_string(), "my-app hello".to_string()),
|
||||
("help".to_string(), "my-app help".to_string()),
|
||||
("config".to_string(), "my-app test config".to_string()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_subcommand_with_path() {
|
||||
let app = common();
|
||||
let sc_app = Foo::find_subcommand_with_path(&app, "test config".split(" ").collect());
|
||||
|
||||
assert_eq!(sc_app.name, "config");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flags() {
|
||||
let app = common();
|
||||
let flags = Foo::flags(&app);
|
||||
|
||||
assert_eq!(flags.len(), 2);
|
||||
assert_eq!(flags[0].long, Some("help"));
|
||||
assert_eq!(flags[1].long, Some("version"));
|
||||
|
||||
let sc_flags = Foo::flags(Foo::find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_flags.len(), 3);
|
||||
assert_eq!(sc_flags[0].long, Some("file"));
|
||||
assert_eq!(sc_flags[1].long, Some("help"));
|
||||
assert_eq!(sc_flags[2].long, Some("version"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shorts() {
|
||||
let app = common();
|
||||
let shorts = Foo::shorts(&app);
|
||||
|
||||
assert_eq!(shorts.len(), 2);
|
||||
assert_eq!(shorts[0], 'h');
|
||||
assert_eq!(shorts[1], 'V');
|
||||
|
||||
let sc_shorts = Foo::shorts(Foo::find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_shorts.len(), 3);
|
||||
assert_eq!(sc_shorts[0], 'f');
|
||||
assert_eq!(sc_shorts[1], 'h');
|
||||
assert_eq!(sc_shorts[2], 'V');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_longs() {
|
||||
let app = common();
|
||||
let longs = Foo::longs(&app);
|
||||
|
||||
assert_eq!(longs.len(), 2);
|
||||
assert_eq!(longs[0], "help");
|
||||
assert_eq!(longs[1], "version");
|
||||
|
||||
let sc_longs = Foo::longs(Foo::find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_longs.len(), 3);
|
||||
assert_eq!(sc_longs[0], "file");
|
||||
assert_eq!(sc_longs[1], "help");
|
||||
assert_eq!(sc_longs[2], "version");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,13 @@ fn all_subcommands(app: &App) -> String {
|
|||
debugln!("Bash::all_subcommands;");
|
||||
|
||||
let mut subcmds = String::new();
|
||||
let scs = Bash::all_subcommand_names(app);
|
||||
let mut scs = Bash::all_subcommands(app)
|
||||
.iter()
|
||||
.map(|x| x.0.clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
scs.sort();
|
||||
scs.dedup();
|
||||
|
||||
for sc in &scs {
|
||||
subcmds = format!(
|
||||
|
@ -97,10 +103,12 @@ fn subcommand_details(app: &App) -> String {
|
|||
debugln!("Bash::subcommand_details;");
|
||||
|
||||
let mut subcmd_dets = String::new();
|
||||
let mut scs = Bash::get_all_subcommand_paths(app, true);
|
||||
let mut scs = Bash::all_subcommands(app)
|
||||
.iter()
|
||||
.map(|x| x.1.replace(" ", "__"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
scs.sort();
|
||||
scs.dedup();
|
||||
|
||||
for sc in &scs {
|
||||
subcmd_dets = format!(
|
||||
|
@ -123,7 +131,7 @@ fn subcommand_details(app: &App) -> String {
|
|||
subcmd_dets,
|
||||
subcmd = sc.replace("-", "__"),
|
||||
sc_opts = all_options_for_path(app, &*sc),
|
||||
level = sc.split("__").map(|_| 1).fold(0, |acc, n| acc + n),
|
||||
level = sc.split("__").map(|_| 1).sum::<u64>(),
|
||||
opts_details = option_details_for_path(app, &*sc)
|
||||
);
|
||||
}
|
||||
|
@ -134,13 +142,7 @@ fn subcommand_details(app: &App) -> String {
|
|||
fn option_details_for_path(app: &App, path: &str) -> String {
|
||||
debugln!("Bash::option_details_for_path: path={}", path);
|
||||
|
||||
let mut p = app;
|
||||
|
||||
for sc in path.split("__").skip(1) {
|
||||
debugln!("Bash::option_details_for_path:iter: sc={}", sc);
|
||||
p = &find_subcmd!(p, sc).unwrap();
|
||||
}
|
||||
|
||||
let p = Bash::find_subcommand_with_path(app, path.split("__").skip(1).collect());
|
||||
let mut opts = String::new();
|
||||
|
||||
for o in opts!(p) {
|
||||
|
@ -187,25 +189,19 @@ fn vals_for(o: &Arg) -> String {
|
|||
fn all_options_for_path(app: &App, path: &str) -> String {
|
||||
debugln!("Bash::all_options_for_path: path={}", path);
|
||||
|
||||
let mut p = app;
|
||||
|
||||
for sc in path.split("__").skip(1) {
|
||||
debugln!("Bash::all_options_for_path:iter: sc={}", sc);
|
||||
p = &find_subcmd!(p, sc).unwrap();
|
||||
}
|
||||
let p = Bash::find_subcommand_with_path(app, path.split("__").skip(1).collect());
|
||||
let scs: Vec<_> = Bash::subcommands(p).iter().map(|x| x.0.clone()).collect();
|
||||
|
||||
let opts = format!(
|
||||
"{shorts} {longs} {pos} {subcmds}",
|
||||
shorts = shorts!(p).fold(String::new(), |acc, s| format!("{} -{}", acc, s)),
|
||||
// Handles aliases too
|
||||
longs = longs!(p).fold(String::new(), |acc, l| format!(
|
||||
"{} --{}",
|
||||
acc,
|
||||
l.to_str().unwrap()
|
||||
)),
|
||||
shorts = Bash::shorts(p)
|
||||
.iter()
|
||||
.fold(String::new(), |acc, s| format!("{} -{}", acc, s)),
|
||||
longs = Bash::longs(p)
|
||||
.iter()
|
||||
.fold(String::new(), |acc, l| format!("{} --{}", acc, l)),
|
||||
pos = positionals!(p).fold(String::new(), |acc, p| format!("{} {}", acc, p)),
|
||||
// Handles aliases too
|
||||
subcmds = sc_names!(p).fold(String::new(), |acc, s| format!("{} {}", acc, s))
|
||||
subcmds = scs.join(" "),
|
||||
);
|
||||
|
||||
opts
|
||||
|
|
|
@ -93,7 +93,7 @@ fn generate_inner<'b>(
|
|||
}
|
||||
}
|
||||
|
||||
for flag in flags!(p) {
|
||||
for flag in Elvish::flags(p) {
|
||||
if let Some(data) = flag.short {
|
||||
let tooltip = get_tooltip(flag.help, data);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ impl Generator for Fish {
|
|||
let command = app.get_bin_name().unwrap();
|
||||
let mut buffer = String::new();
|
||||
|
||||
gen_fish_inner(command, app, command, &mut buffer);
|
||||
gen_fish_inner(command, app, &mut buffer);
|
||||
w!(buf, buffer.as_bytes());
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ fn escape_string(string: &str) -> String {
|
|||
string.replace("\\", "\\\\").replace("'", "\\'")
|
||||
}
|
||||
|
||||
fn gen_fish_inner(root_command: &str, app: &App, subcommand: &str, buffer: &mut String) {
|
||||
fn gen_fish_inner(root_command: &str, app: &App, buffer: &mut String) {
|
||||
debugln!("Fish::gen_fish_inner;");
|
||||
// example :
|
||||
//
|
||||
|
@ -43,13 +43,17 @@ fn gen_fish_inner(root_command: &str, app: &App, subcommand: &str, buffer: &mut
|
|||
// -n "__fish_seen_subcommand_from subcmd1" # complete for command "myprog subcmd1"
|
||||
|
||||
let mut basic_template = format!("complete -c {} -n ", root_command);
|
||||
let mut bin_name = app.get_bin_name().unwrap();
|
||||
|
||||
if root_command == subcommand {
|
||||
if root_command == bin_name {
|
||||
basic_template.push_str("\"__fish_use_subcommand\"");
|
||||
} else {
|
||||
basic_template.push_str(format!("\"__fish_seen_subcommand_from {}\"", subcommand).as_str());
|
||||
bin_name = &app.name;
|
||||
basic_template.push_str(format!("\"__fish_seen_subcommand_from {}\"", bin_name).as_str());
|
||||
}
|
||||
|
||||
debugln!("Fish::gen_fish_inner; bin_name={}", bin_name);
|
||||
|
||||
for option in opts!(app) {
|
||||
let mut template = basic_template.clone();
|
||||
|
||||
|
@ -73,7 +77,7 @@ fn gen_fish_inner(root_command: &str, app: &App, subcommand: &str, buffer: &mut
|
|||
buffer.push_str("\n");
|
||||
}
|
||||
|
||||
for flag in flags!(app) {
|
||||
for flag in Fish::flags(app) {
|
||||
let mut template = basic_template.clone();
|
||||
|
||||
if let Some(data) = flag.short {
|
||||
|
@ -92,7 +96,7 @@ fn gen_fish_inner(root_command: &str, app: &App, subcommand: &str, buffer: &mut
|
|||
buffer.push_str("\n");
|
||||
}
|
||||
|
||||
for subcommand in subcommands!(app) {
|
||||
for subcommand in &app.subcommands {
|
||||
let mut template = basic_template.clone();
|
||||
|
||||
template.push_str(" -f");
|
||||
|
@ -107,7 +111,7 @@ fn gen_fish_inner(root_command: &str, app: &App, subcommand: &str, buffer: &mut
|
|||
}
|
||||
|
||||
// generate options of subcommands
|
||||
for subapp in &app.subcommands {
|
||||
gen_fish_inner(root_command, subapp, &subapp.name, buffer);
|
||||
for subcommand in &app.subcommands {
|
||||
gen_fish_inner(root_command, subcommand, buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ fn generate_inner<'b>(
|
|||
}
|
||||
}
|
||||
|
||||
for flag in flags!(p) {
|
||||
for flag in PowerShell::flags(p) {
|
||||
if let Some(data) = flag.short {
|
||||
let tooltip = get_tooltip(flag.help, data);
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ fn get_subcommands_of(p: &App) -> String {
|
|||
return String::new();
|
||||
}
|
||||
|
||||
let sc_names = Zsh::subcommands_of(p);
|
||||
let sc_names = Zsh::subcommands(p);
|
||||
let mut subcmds = vec![];
|
||||
|
||||
for &(ref name, ref bin_name) in &sc_names {
|
||||
|
@ -262,7 +262,7 @@ fn parser_of<'b>(p: &'b App<'b>, mut sc: &str) -> &'b App<'b> {
|
|||
return p;
|
||||
}
|
||||
|
||||
sc = sc.split(" ").last().unwrap();
|
||||
sc = sc.split(' ').last().unwrap();
|
||||
find_subcmd!(p, sc).expect(INTERNAL_ERROR_MSG)
|
||||
}
|
||||
|
||||
|
@ -429,7 +429,7 @@ fn write_flags_of(p: &App) -> String {
|
|||
|
||||
let mut ret = vec![];
|
||||
|
||||
for f in flags!(p) {
|
||||
for f in Zsh::flags(p) {
|
||||
debugln!("Zsh::write_flags_of:iter: f={}", f.name);
|
||||
|
||||
let help = f.help.map_or(String::new(), escape_help);
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
unused_allocation,
|
||||
trivial_numeric_casts
|
||||
)]
|
||||
#![allow(clippy::needless_doctest_main)]
|
||||
|
||||
const INTERNAL_ERROR_MSG: &'static str = "Fatal internal error. Please consider filing a bug \
|
||||
report at https://github.com/clap-rs/clap/issues";
|
||||
const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \
|
||||
report at https://github.com/clap-rs/clap/issues";
|
||||
|
||||
#[macro_use]
|
||||
#[allow(missing_docs)]
|
||||
|
@ -106,9 +107,9 @@ pub use generators::Generator;
|
|||
/// };
|
||||
///
|
||||
/// let mut app = build_cli();
|
||||
/// generate_to<Bash>(&mut app, // We need to specify what generator to use
|
||||
/// "myapp", // We need to specify the bin name manually
|
||||
/// outdir); // We need to specify where to write to
|
||||
/// generate_to::<Bash, _>(&mut app, // We need to specify what generator to use
|
||||
/// "myapp", // We need to specify the bin name manually
|
||||
/// outdir); // We need to specify where to write to
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
@ -153,13 +154,13 @@ where
|
|||
///
|
||||
/// mod cli;
|
||||
/// use std::io;
|
||||
/// use clap_generate::{generate_to, generators::Bash};
|
||||
/// use clap_generate::{generate, generators::Bash};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let matches = cli::build_cli().get_matches();
|
||||
///
|
||||
/// if matches.is_present("generate-bash-completions") {
|
||||
/// generate<Bash>(&mut cli::build_cli(), "myapp", &mut io::stdout());
|
||||
/// generate::<Bash, _>(&mut cli::build_cli(), "myapp", &mut io::stdout());
|
||||
/// }
|
||||
///
|
||||
/// // normal logic continues...
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
use std::fmt;
|
||||
use clap::{App, Arg};
|
||||
use clap_generate::{generate, generators::*};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct PrettyString<'a>(pub &'a str);
|
||||
|
||||
impl<'a> fmt::Debug for PrettyString<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(self.0)
|
||||
}
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! assert_eq {
|
||||
($left:expr, $right:expr) => {
|
||||
pretty_assertions::assert_eq!(PrettyString($left), PrettyString($right));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static BASH: &'static str = r#"_myapp() {
|
||||
|
@ -45,7 +45,7 @@ static BASH: &'static str = r#"_myapp() {
|
|||
|
||||
case "${cmd}" in
|
||||
myapp)
|
||||
opts=" -h -V --help --version <file> test help"
|
||||
opts=" -h -V --help --version <file> test help"
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
|
@ -572,7 +572,7 @@ static BASH_SPECIAL_CMDS: &'static str = r#"_my_app() {
|
|||
|
||||
case "${cmd}" in
|
||||
my_app)
|
||||
opts=" -h -V --help --version <file> test some_cmd some-cmd-with-hypens help"
|
||||
opts=" -h -V --help --version <file> test some_cmd some-cmd-with-hypens help"
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
|
@ -740,7 +740,7 @@ fn build_app_special_commands() -> App<'static> {
|
|||
.help("the other case to test"),
|
||||
),
|
||||
)
|
||||
.subcommand(App::new("some-cmd-with-hypens"))
|
||||
.subcommand(App::new("some-cmd-with-hypens").alias("hyphen"))
|
||||
}
|
||||
|
||||
fn build_app_special_help() -> App<'static> {
|
||||
|
|
Loading…
Reference in a new issue