mirror of
https://github.com/clap-rs/clap
synced 2025-03-04 07:17:26 +00:00
feat: Open the door for user styling in the future
This added about 10 KiB to the `.text` which I cannot explain why
This commit is contained in:
parent
2e2b63fa5c
commit
c6155f62d5
18 changed files with 215 additions and 111 deletions
|
@ -1,5 +1,6 @@
|
|||
use std::io::Write;
|
||||
|
||||
use clap::builder::StyledStr;
|
||||
use clap::*;
|
||||
|
||||
use crate::generator::{utils, Generator};
|
||||
|
@ -59,9 +60,9 @@ fn escape_string(string: &str) -> String {
|
|||
string.replace('\'', "''")
|
||||
}
|
||||
|
||||
fn get_tooltip<T: ToString>(help: Option<&str>, data: T) -> String {
|
||||
fn get_tooltip<T: ToString>(help: Option<&StyledStr>, data: T) -> String {
|
||||
match help {
|
||||
Some(help) => escape_string(help),
|
||||
Some(help) => escape_string(&help.to_string()),
|
||||
_ => data.to_string(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ fn gen_fish_inner(
|
|||
}
|
||||
|
||||
if let Some(data) = option.get_help() {
|
||||
template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
|
||||
template.push_str(format!(" -d '{}'", escape_string(&data.to_string())).as_str());
|
||||
}
|
||||
|
||||
template.push_str(value_completion(option).as_str());
|
||||
|
@ -118,7 +118,7 @@ fn gen_fish_inner(
|
|||
}
|
||||
|
||||
if let Some(data) = flag.get_help() {
|
||||
template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
|
||||
template.push_str(format!(" -d '{}'", escape_string(&data.to_string())).as_str());
|
||||
}
|
||||
|
||||
buffer.push_str(template.as_str());
|
||||
|
@ -132,7 +132,7 @@ fn gen_fish_inner(
|
|||
template.push_str(format!(" -a \"{}\"", &subcommand.get_name()).as_str());
|
||||
|
||||
if let Some(data) = subcommand.get_about() {
|
||||
template.push_str(format!(" -d '{}'", escape_string(data)).as_str())
|
||||
template.push_str(format!(" -d '{}'", escape_string(&data.to_string())).as_str())
|
||||
}
|
||||
|
||||
buffer.push_str(template.as_str());
|
||||
|
@ -164,7 +164,7 @@ fn value_completion(option: &Arg) -> String {
|
|||
Some(format!(
|
||||
"{}\t{}",
|
||||
escape_string(value.get_name()).as_str(),
|
||||
escape_string(value.get_help().unwrap_or_default()).as_str()
|
||||
escape_string(&value.get_help().unwrap_or_default().to_string())
|
||||
))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::io::Write;
|
||||
|
||||
use clap::builder::StyledStr;
|
||||
use clap::*;
|
||||
|
||||
use crate::generator::{utils, Generator};
|
||||
|
@ -64,9 +65,9 @@ fn escape_string(string: &str) -> String {
|
|||
string.replace('\'', "''")
|
||||
}
|
||||
|
||||
fn get_tooltip<T: ToString>(help: Option<&str>, data: T) -> String {
|
||||
fn get_tooltip<T: ToString>(help: Option<&StyledStr>, data: T) -> String {
|
||||
match help {
|
||||
Some(help) => escape_string(help),
|
||||
Some(help) => escape_string(&help.to_string()),
|
||||
_ => data.to_string(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ fn subcommands_of(p: &Command) -> String {
|
|||
let text = format!(
|
||||
"'{name}:{help}' \\",
|
||||
name = name,
|
||||
help = escape_help(subcommand.get_about().unwrap_or_default())
|
||||
help = escape_help(&subcommand.get_about().unwrap_or_default().to_string())
|
||||
);
|
||||
|
||||
if !text.is_empty() {
|
||||
|
@ -372,7 +372,8 @@ fn value_completion(arg: &Arg) -> Option<String> {
|
|||
Some(format!(
|
||||
r#"{name}\:"{tooltip}""#,
|
||||
name = escape_value(value.get_name()),
|
||||
tooltip = value.get_help().map(escape_help).unwrap_or_default()
|
||||
tooltip =
|
||||
escape_help(&value.get_help().unwrap_or_default().to_string()),
|
||||
))
|
||||
}
|
||||
})
|
||||
|
@ -445,7 +446,7 @@ fn write_opts_of(p: &Command, p_global: Option<&Command>) -> String {
|
|||
for o in p.get_opts() {
|
||||
debug!("write_opts_of:iter: o={}", o.get_id());
|
||||
|
||||
let help = o.get_help().map(escape_help).unwrap_or_default();
|
||||
let help = escape_help(&o.get_help().unwrap_or_default().to_string());
|
||||
let conflicts = arg_conflicts(p, o, p_global);
|
||||
|
||||
let multiple = "*";
|
||||
|
@ -541,7 +542,7 @@ fn write_flags_of(p: &Command, p_global: Option<&Command>) -> String {
|
|||
for f in utils::flags(p) {
|
||||
debug!("write_flags_of:iter: f={}", f.get_id());
|
||||
|
||||
let help = f.get_help().map(escape_help).unwrap_or_default();
|
||||
let help = escape_help(&f.get_help().unwrap_or_default().to_string());
|
||||
let conflicts = arg_conflicts(p, &f, p_global);
|
||||
|
||||
let multiple = "*";
|
||||
|
@ -634,7 +635,8 @@ fn write_positionals_of(p: &Command) -> String {
|
|||
name = arg.get_id(),
|
||||
help = arg
|
||||
.get_help()
|
||||
.map_or("".to_owned(), |v| " -- ".to_owned() + v)
|
||||
.map(|s| s.to_string())
|
||||
.map_or("".to_owned(), |v| " -- ".to_owned() + &v)
|
||||
.replace('[', "\\[")
|
||||
.replace(']', "\\]")
|
||||
.replace('\'', "'\\''")
|
||||
|
|
|
@ -28,7 +28,7 @@ impl Generator for Fig {
|
|||
write!(
|
||||
&mut buffer,
|
||||
" description: \"{}\",\n",
|
||||
escape_string(cmd.get_about().unwrap_or_default())
|
||||
escape_string(&cmd.get_about().unwrap_or_default().to_string())
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -101,7 +101,7 @@ fn gen_fig_inner(
|
|||
buffer,
|
||||
"{:indent$}description: \"{}\",\n",
|
||||
"",
|
||||
escape_string(data),
|
||||
escape_string(&data.to_string()),
|
||||
indent = indent + 4
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -205,7 +205,7 @@ fn gen_options(cmd: &Command, indent: usize) -> String {
|
|||
&mut buffer,
|
||||
"{:indent$}description: \"{}\",\n",
|
||||
"",
|
||||
escape_string(data),
|
||||
escape_string(&data.to_string()),
|
||||
indent = indent + 4
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -314,7 +314,7 @@ fn gen_options(cmd: &Command, indent: usize) -> String {
|
|||
&mut buffer,
|
||||
"{:indent$}description: \"{}\",\n",
|
||||
"",
|
||||
escape_string(data).as_str(),
|
||||
escape_string(&data.to_string()).as_str(),
|
||||
indent = indent + 4
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -426,7 +426,7 @@ fn gen_args(arg: &Arg, indent: usize) -> String {
|
|||
&mut buffer,
|
||||
"{:indent$}description: \"{}\",\n",
|
||||
"",
|
||||
escape_string(help),
|
||||
escape_string(&help.to_string()),
|
||||
indent = indent + 6
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -17,7 +17,7 @@ pub(crate) fn about(roff: &mut Roff, cmd: &clap::Command) {
|
|||
|
||||
pub(crate) fn description(roff: &mut Roff, cmd: &clap::Command) {
|
||||
if let Some(about) = cmd.get_long_about().or_else(|| cmd.get_about()) {
|
||||
for line in about.lines() {
|
||||
for line in about.to_string().lines() {
|
||||
if line.trim().is_empty() {
|
||||
roff.control("PP", []);
|
||||
} else {
|
||||
|
@ -110,7 +110,7 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) {
|
|||
let mut arg_help_written = false;
|
||||
if let Some(help) = opt.get_long_help().or_else(|| opt.get_help()) {
|
||||
arg_help_written = true;
|
||||
body.push(roman(help));
|
||||
body.push(roman(help.to_string()));
|
||||
}
|
||||
|
||||
roff.control("TP", []);
|
||||
|
@ -224,7 +224,7 @@ pub(crate) fn subcommands(roff: &mut Roff, cmd: &clap::Command, section: &str) {
|
|||
roff.text([roman(&name)]);
|
||||
|
||||
if let Some(about) = sub.get_about().or_else(|| sub.get_long_about()) {
|
||||
for line in about.lines() {
|
||||
for line in about.to_string().lines() {
|
||||
roff.text([roman(line)]);
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ pub(crate) fn version(cmd: &clap::Command) -> String {
|
|||
|
||||
pub(crate) fn after_help(roff: &mut Roff, cmd: &clap::Command) {
|
||||
if let Some(about) = cmd.get_after_long_help().or_else(|| cmd.get_after_help()) {
|
||||
for line in about.lines() {
|
||||
for line in about.to_string().lines() {
|
||||
roff.text([roman(line)]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::builder::IntoResettable;
|
|||
use crate::builder::OsStr;
|
||||
use crate::builder::PossibleValue;
|
||||
use crate::builder::Str;
|
||||
use crate::builder::StyledStr;
|
||||
use crate::builder::ValueRange;
|
||||
use crate::ArgAction;
|
||||
use crate::Id;
|
||||
|
@ -54,8 +55,8 @@ use crate::INTERNAL_ERROR_MSG;
|
|||
#[derive(Default, Clone)]
|
||||
pub struct Arg {
|
||||
pub(crate) id: Id,
|
||||
pub(crate) help: Option<Str>,
|
||||
pub(crate) long_help: Option<Str>,
|
||||
pub(crate) help: Option<StyledStr>,
|
||||
pub(crate) long_help: Option<StyledStr>,
|
||||
pub(crate) action: Option<ArgAction>,
|
||||
pub(crate) value_parser: Option<super::ValueParser>,
|
||||
pub(crate) blacklist: Vec<Id>,
|
||||
|
@ -1900,7 +1901,7 @@ impl Arg {
|
|||
/// [`Arg::long_help`]: Arg::long_help()
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn help(mut self, h: impl IntoResettable<Str>) -> Self {
|
||||
pub fn help(mut self, h: impl IntoResettable<StyledStr>) -> Self {
|
||||
self.help = h.into_resettable().into_option();
|
||||
self
|
||||
}
|
||||
|
@ -1962,7 +1963,7 @@ impl Arg {
|
|||
/// [`Arg::help`]: Arg::help()
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn long_help(mut self, h: impl IntoResettable<Str>) -> Self {
|
||||
pub fn long_help(mut self, h: impl IntoResettable<StyledStr>) -> Self {
|
||||
self.long_help = h.into_resettable().into_option();
|
||||
self
|
||||
}
|
||||
|
@ -3539,8 +3540,8 @@ impl Arg {
|
|||
|
||||
/// Get the help specified for this argument, if any
|
||||
#[inline]
|
||||
pub fn get_help(&self) -> Option<&str> {
|
||||
self.help.as_deref()
|
||||
pub fn get_help(&self) -> Option<&StyledStr> {
|
||||
self.help.as_ref()
|
||||
}
|
||||
|
||||
/// Get the long help specified for this argument, if any
|
||||
|
@ -3550,12 +3551,12 @@ impl Arg {
|
|||
/// ```rust
|
||||
/// # use clap::Arg;
|
||||
/// let arg = Arg::new("foo").long_help("long help");
|
||||
/// assert_eq!(Some("long help"), arg.get_long_help());
|
||||
/// assert_eq!(Some("long help".to_owned()), arg.get_long_help().map(|s| s.to_string()));
|
||||
/// ```
|
||||
///
|
||||
#[inline]
|
||||
pub fn get_long_help(&self) -> Option<&str> {
|
||||
self.long_help.as_deref()
|
||||
pub fn get_long_help(&self) -> Option<&StyledStr> {
|
||||
self.long_help.as_ref()
|
||||
}
|
||||
|
||||
/// Get the help heading specified for this argument, if any
|
||||
|
|
|
@ -75,22 +75,22 @@ pub struct Command {
|
|||
author: Option<Str>,
|
||||
version: Option<Str>,
|
||||
long_version: Option<Str>,
|
||||
about: Option<Str>,
|
||||
long_about: Option<Str>,
|
||||
before_help: Option<Str>,
|
||||
before_long_help: Option<Str>,
|
||||
after_help: Option<Str>,
|
||||
after_long_help: Option<Str>,
|
||||
about: Option<StyledStr>,
|
||||
long_about: Option<StyledStr>,
|
||||
before_help: Option<StyledStr>,
|
||||
before_long_help: Option<StyledStr>,
|
||||
after_help: Option<StyledStr>,
|
||||
after_long_help: Option<StyledStr>,
|
||||
aliases: Vec<(Str, bool)>, // (name, visible)
|
||||
short_flag_aliases: Vec<(char, bool)>, // (name, visible)
|
||||
long_flag_aliases: Vec<(Str, bool)>, // (name, visible)
|
||||
usage_str: Option<Str>,
|
||||
usage_str: Option<StyledStr>,
|
||||
usage_name: Option<String>,
|
||||
help_str: Option<Str>,
|
||||
help_str: Option<StyledStr>,
|
||||
disp_ord: Option<usize>,
|
||||
term_w: Option<usize>,
|
||||
max_w: Option<usize>,
|
||||
template: Option<Str>,
|
||||
template: Option<StyledStr>,
|
||||
settings: AppFlags,
|
||||
g_settings: AppFlags,
|
||||
args: MKeyMap,
|
||||
|
@ -1442,7 +1442,7 @@ impl Command {
|
|||
/// # ;
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn about(mut self, about: impl IntoResettable<Str>) -> Self {
|
||||
pub fn about(mut self, about: impl IntoResettable<StyledStr>) -> Self {
|
||||
self.about = about.into_resettable().into_option();
|
||||
self
|
||||
}
|
||||
|
@ -1467,7 +1467,7 @@ impl Command {
|
|||
/// ```
|
||||
/// [`Command::about`]: Command::about()
|
||||
#[must_use]
|
||||
pub fn long_about(mut self, long_about: impl IntoResettable<Str>) -> Self {
|
||||
pub fn long_about(mut self, long_about: impl IntoResettable<StyledStr>) -> Self {
|
||||
self.long_about = long_about.into_resettable().into_option();
|
||||
self
|
||||
}
|
||||
|
@ -1489,7 +1489,7 @@ impl Command {
|
|||
/// ```
|
||||
///
|
||||
#[must_use]
|
||||
pub fn after_help(mut self, help: impl Into<Str>) -> Self {
|
||||
pub fn after_help(mut self, help: impl Into<StyledStr>) -> Self {
|
||||
self.after_help = Some(help.into());
|
||||
self
|
||||
}
|
||||
|
@ -1511,7 +1511,7 @@ impl Command {
|
|||
/// # ;
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn after_long_help(mut self, help: impl Into<Str>) -> Self {
|
||||
pub fn after_long_help(mut self, help: impl Into<StyledStr>) -> Self {
|
||||
self.after_long_help = Some(help.into());
|
||||
self
|
||||
}
|
||||
|
@ -1531,7 +1531,7 @@ impl Command {
|
|||
/// # ;
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn before_help(mut self, help: impl Into<Str>) -> Self {
|
||||
pub fn before_help(mut self, help: impl Into<StyledStr>) -> Self {
|
||||
self.before_help = Some(help.into());
|
||||
self
|
||||
}
|
||||
|
@ -1551,7 +1551,7 @@ impl Command {
|
|||
/// # ;
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn before_long_help(mut self, help: impl Into<Str>) -> Self {
|
||||
pub fn before_long_help(mut self, help: impl Into<StyledStr>) -> Self {
|
||||
self.before_long_help = Some(help.into());
|
||||
self
|
||||
}
|
||||
|
@ -1645,7 +1645,7 @@ impl Command {
|
|||
///
|
||||
/// [`ArgMatches::usage`]: ArgMatches::usage()
|
||||
#[must_use]
|
||||
pub fn override_usage(mut self, usage: impl Into<Str>) -> Self {
|
||||
pub fn override_usage(mut self, usage: impl Into<StyledStr>) -> Self {
|
||||
self.usage_str = Some(usage.into());
|
||||
self
|
||||
}
|
||||
|
@ -1682,7 +1682,7 @@ impl Command {
|
|||
/// # ;
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn override_help(mut self, help: impl Into<Str>) -> Self {
|
||||
pub fn override_help(mut self, help: impl Into<StyledStr>) -> Self {
|
||||
self.help_str = Some(help.into());
|
||||
self
|
||||
}
|
||||
|
@ -1732,7 +1732,7 @@ impl Command {
|
|||
/// [`Command::before_help`]: Command::before_help()
|
||||
/// [`Command::before_long_help`]: Command::before_long_help()
|
||||
#[must_use]
|
||||
pub fn help_template(mut self, s: impl Into<Str>) -> Self {
|
||||
pub fn help_template(mut self, s: impl Into<StyledStr>) -> Self {
|
||||
self.template = Some(s.into());
|
||||
self
|
||||
}
|
||||
|
@ -3242,16 +3242,16 @@ impl Command {
|
|||
///
|
||||
/// [`Command::about`]: Command::about()
|
||||
#[inline]
|
||||
pub fn get_about(&self) -> Option<&str> {
|
||||
self.about.as_deref()
|
||||
pub fn get_about(&self) -> Option<&StyledStr> {
|
||||
self.about.as_ref()
|
||||
}
|
||||
|
||||
/// Get the help message specified via [`Command::long_about`].
|
||||
///
|
||||
/// [`Command::long_about`]: Command::long_about()
|
||||
#[inline]
|
||||
pub fn get_long_about(&self) -> Option<&str> {
|
||||
self.long_about.as_deref()
|
||||
pub fn get_long_about(&self) -> Option<&StyledStr> {
|
||||
self.long_about.as_ref()
|
||||
}
|
||||
|
||||
/// Get the custom section heading specified via [`Command::next_help_heading`].
|
||||
|
@ -3364,26 +3364,26 @@ impl Command {
|
|||
|
||||
/// Returns the help heading for listing subcommands.
|
||||
#[inline]
|
||||
pub fn get_before_help(&self) -> Option<&str> {
|
||||
self.before_help.as_deref()
|
||||
pub fn get_before_help(&self) -> Option<&StyledStr> {
|
||||
self.before_help.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the help heading for listing subcommands.
|
||||
#[inline]
|
||||
pub fn get_before_long_help(&self) -> Option<&str> {
|
||||
self.before_long_help.as_deref()
|
||||
pub fn get_before_long_help(&self) -> Option<&StyledStr> {
|
||||
self.before_long_help.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the help heading for listing subcommands.
|
||||
#[inline]
|
||||
pub fn get_after_help(&self) -> Option<&str> {
|
||||
self.after_help.as_deref()
|
||||
pub fn get_after_help(&self) -> Option<&StyledStr> {
|
||||
self.after_help.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the help heading for listing subcommands.
|
||||
#[inline]
|
||||
pub fn get_after_long_help(&self) -> Option<&str> {
|
||||
self.after_long_help.as_deref()
|
||||
pub fn get_after_long_help(&self) -> Option<&StyledStr> {
|
||||
self.after_long_help.as_ref()
|
||||
}
|
||||
|
||||
/// Find subcommand such that its name or one of aliases equals `name`.
|
||||
|
@ -3667,16 +3667,16 @@ impl Command {
|
|||
|
||||
// Internally used only
|
||||
impl Command {
|
||||
pub(crate) fn get_override_usage(&self) -> Option<&str> {
|
||||
self.usage_str.as_deref()
|
||||
pub(crate) fn get_override_usage(&self) -> Option<&StyledStr> {
|
||||
self.usage_str.as_ref()
|
||||
}
|
||||
|
||||
pub(crate) fn get_override_help(&self) -> Option<&str> {
|
||||
self.help_str.as_deref()
|
||||
pub(crate) fn get_override_help(&self) -> Option<&StyledStr> {
|
||||
self.help_str.as_ref()
|
||||
}
|
||||
|
||||
pub(crate) fn get_help_template(&self) -> Option<&str> {
|
||||
self.template.as_deref()
|
||||
pub(crate) fn get_help_template(&self) -> Option<&StyledStr> {
|
||||
self.template.as_ref()
|
||||
}
|
||||
|
||||
pub(crate) fn get_term_width(&self) -> Option<usize> {
|
||||
|
|
|
@ -339,13 +339,13 @@ pub(crate) fn assert_app(cmd: &Command) {
|
|||
|
||||
if let Some(help_template) = cmd.get_help_template() {
|
||||
assert!(
|
||||
!help_template.contains("{flags}"),
|
||||
!help_template.to_string().contains("{flags}"),
|
||||
"Command {}: {}",
|
||||
cmd.get_name(),
|
||||
"`{flags}` template variable was removed in clap3, they are now included in `{options}`",
|
||||
);
|
||||
assert!(
|
||||
!help_template.contains("{unified}"),
|
||||
!help_template.to_string().contains("{unified}"),
|
||||
"Command {}: {}",
|
||||
cmd.get_name(),
|
||||
"`{unified}` template variable was removed in clap3, use `{options}` instead"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::{borrow::Cow, iter};
|
||||
|
||||
use crate::builder::Str;
|
||||
use crate::builder::StyledStr;
|
||||
use crate::util::eq_ignore_case;
|
||||
|
||||
/// A possible value of an argument.
|
||||
|
@ -30,7 +31,7 @@ use crate::util::eq_ignore_case;
|
|||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub struct PossibleValue {
|
||||
name: Str,
|
||||
help: Option<Str>,
|
||||
help: Option<StyledStr>,
|
||||
aliases: Vec<Str>, // (name, visible)
|
||||
hide: bool,
|
||||
}
|
||||
|
@ -75,7 +76,7 @@ impl PossibleValue {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn help(mut self, help: impl Into<Str>) -> Self {
|
||||
pub fn help(mut self, help: impl Into<StyledStr>) -> Self {
|
||||
self.help = Some(help.into());
|
||||
self
|
||||
}
|
||||
|
@ -144,16 +145,16 @@ impl PossibleValue {
|
|||
|
||||
/// Get the help specified for this argument, if any
|
||||
#[inline]
|
||||
pub fn get_help(&self) -> Option<&str> {
|
||||
self.help.as_deref()
|
||||
pub fn get_help(&self) -> Option<&StyledStr> {
|
||||
self.help.as_ref()
|
||||
}
|
||||
|
||||
/// Get the help specified for this argument, if any and the argument
|
||||
/// value is not hidden
|
||||
#[inline]
|
||||
pub(crate) fn get_visible_help(&self) -> Option<&str> {
|
||||
pub(crate) fn get_visible_help(&self) -> Option<&StyledStr> {
|
||||
if !self.hide {
|
||||
self.help.as_deref()
|
||||
self.get_help()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
use crate::builder::OsStr;
|
||||
use crate::builder::Str;
|
||||
use crate::builder::StyledStr;
|
||||
|
||||
/// Clearable builder value
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -43,6 +44,15 @@ pub trait IntoResettable<T> {
|
|||
fn into_resettable(self) -> Resettable<T>;
|
||||
}
|
||||
|
||||
impl IntoResettable<StyledStr> for Option<&'static str> {
|
||||
fn into_resettable(self) -> Resettable<StyledStr> {
|
||||
match self {
|
||||
Some(s) => Resettable::Value(s.into()),
|
||||
None => Resettable::Reset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResettable<OsStr> for Option<&'static str> {
|
||||
fn into_resettable(self) -> Resettable<OsStr> {
|
||||
match self {
|
||||
|
@ -67,6 +77,12 @@ impl<T> IntoResettable<T> for Resettable<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<I: Into<StyledStr>> IntoResettable<StyledStr> for I {
|
||||
fn into_resettable(self) -> Resettable<StyledStr> {
|
||||
Resettable::Value(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Into<OsStr>> IntoResettable<OsStr> for I {
|
||||
fn into_resettable(self) -> Resettable<OsStr> {
|
||||
Resettable::Value(self.into())
|
||||
|
|
|
@ -32,7 +32,41 @@ impl StyledStr {
|
|||
}
|
||||
|
||||
fn stylize(&mut self, style: Option<Style>, msg: String) {
|
||||
self.pieces.push((style, msg));
|
||||
if !msg.is_empty() {
|
||||
self.pieces.push((style, msg));
|
||||
}
|
||||
}
|
||||
|
||||
/// HACK: Until call sites are updated to handle formatted text, extract the unformatted
|
||||
#[track_caller]
|
||||
pub(crate) fn unwrap_none(&self) -> &str {
|
||||
match self.pieces.len() {
|
||||
0 => "",
|
||||
1 => {
|
||||
if self.pieces[0].0 != None {
|
||||
panic!("{}", crate::INTERNAL_ERROR_MSG)
|
||||
}
|
||||
self.pieces[0].1.as_str()
|
||||
}
|
||||
_ => panic!("{}", crate::INTERNAL_ERROR_MSG),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
self.pieces.is_empty()
|
||||
}
|
||||
|
||||
pub(crate) fn iter(&self) -> impl Iterator<Item = (Option<Style>, &str)> {
|
||||
self.pieces.iter().map(|(s, c)| (*s, c.as_str()))
|
||||
}
|
||||
|
||||
pub(crate) fn extend(
|
||||
&mut self,
|
||||
other: impl IntoIterator<Item = (impl Into<Option<Style>>, impl Into<String>)>,
|
||||
) {
|
||||
for (style, content) in other {
|
||||
self.stylize(style.into(), content.into());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "color")]
|
||||
|
@ -68,6 +102,13 @@ impl StyledStr {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for &'_ StyledStr {
|
||||
fn default() -> Self {
|
||||
static DEFAULT: StyledStr = StyledStr::new();
|
||||
&DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::string::String> for StyledStr {
|
||||
fn from(name: std::string::String) -> Self {
|
||||
let mut styled = StyledStr::new();
|
||||
|
|
|
@ -80,9 +80,9 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
debug!("Help::write_help");
|
||||
|
||||
if let Some(h) = self.cmd.get_override_help() {
|
||||
self.none(h);
|
||||
self.extend(h);
|
||||
} else if let Some(tmpl) = self.cmd.get_help_template() {
|
||||
self.write_templated_help(tmpl);
|
||||
self.write_templated_help(tmpl.unwrap_none());
|
||||
} else {
|
||||
let pos = self
|
||||
.cmd
|
||||
|
@ -107,6 +107,10 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
|
||||
// Methods to write Arg help.
|
||||
impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
||||
fn extend(&mut self, msg: &StyledStr) {
|
||||
self.writer.extend(msg.iter());
|
||||
}
|
||||
|
||||
fn good<T: Into<String>>(&mut self, msg: T) {
|
||||
self.writer.good(msg);
|
||||
}
|
||||
|
@ -353,7 +357,10 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
self.cmd.get_before_help()
|
||||
};
|
||||
if let Some(output) = before_help {
|
||||
self.none(text_wrapper(&output.replace("{n}", "\n"), self.term_w));
|
||||
self.none(text_wrapper(
|
||||
&output.unwrap_none().replace("{n}", "\n"),
|
||||
self.term_w,
|
||||
));
|
||||
self.none("\n\n");
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +376,10 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
};
|
||||
if let Some(output) = after_help {
|
||||
self.none("\n\n");
|
||||
self.none(text_wrapper(&output.replace("{n}", "\n"), self.term_w));
|
||||
self.none(text_wrapper(
|
||||
&output.unwrap_none().replace("{n}", "\n"),
|
||||
self.term_w,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,13 +387,13 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
fn help(
|
||||
&mut self,
|
||||
arg: Option<&Arg>,
|
||||
about: &str,
|
||||
about: &StyledStr,
|
||||
spec_vals: &str,
|
||||
next_line_help: bool,
|
||||
longest: usize,
|
||||
) {
|
||||
debug!("Help::help");
|
||||
let mut help = String::from(about) + spec_vals;
|
||||
let mut help = String::from(about.unwrap_none()) + spec_vals;
|
||||
debug!("Help::help: Next Line...{:?}", next_line_help);
|
||||
|
||||
let spaces = if next_line_help {
|
||||
|
@ -451,7 +461,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
.expect("Only called with possible value");
|
||||
let help_longest = possible_vals
|
||||
.iter()
|
||||
.filter_map(|f| f.get_visible_help().map(display_width))
|
||||
.filter_map(|f| f.get_visible_help().map(|h| display_width(h.unwrap_none())))
|
||||
.max()
|
||||
.expect("Only called with possible value with help");
|
||||
// should new line
|
||||
|
@ -490,7 +500,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
usize::MAX
|
||||
};
|
||||
|
||||
let help = text_wrapper(help, avail_chars);
|
||||
let help = text_wrapper(help.unwrap_none(), avail_chars);
|
||||
let mut help = help.lines();
|
||||
|
||||
self.none(help.next().unwrap_or_default());
|
||||
|
@ -522,7 +532,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
} else {
|
||||
// force_next_line
|
||||
let h = arg.get_help().unwrap_or_default();
|
||||
let h_w = display_width(h) + display_width(spec_vals);
|
||||
let h_w = display_width(h.unwrap_none()) + display_width(spec_vals);
|
||||
let taken = longest + 12;
|
||||
self.term_w >= taken
|
||||
&& (taken as f32 / self.term_w as f32) > 0.40
|
||||
|
@ -649,7 +659,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
if before_new_line {
|
||||
self.none("\n");
|
||||
}
|
||||
self.none(text_wrapper(output, self.term_w));
|
||||
self.none(text_wrapper(output.unwrap_none(), self.term_w));
|
||||
if after_new_line {
|
||||
self.none("\n");
|
||||
}
|
||||
|
@ -739,7 +749,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
|
|||
} else {
|
||||
// force_next_line
|
||||
let h = cmd.get_about().unwrap_or_default();
|
||||
let h_w = display_width(h) + display_width(spec_vals);
|
||||
let h_w = display_width(h.unwrap_none()) + display_width(spec_vals);
|
||||
let taken = longest + 12;
|
||||
self.term_w >= taken
|
||||
&& (taken as f32 / self.term_w as f32) > 0.40
|
||||
|
|
|
@ -40,7 +40,7 @@ impl<'cmd> Usage<'cmd> {
|
|||
pub(crate) fn create_usage_no_title(&self, used: &[Id]) -> String {
|
||||
debug!("Usage::create_usage_no_title");
|
||||
if let Some(u) = self.cmd.get_override_usage() {
|
||||
u.to_owned()
|
||||
u.to_string()
|
||||
} else if used.is_empty() {
|
||||
self.create_help_usage(true)
|
||||
} else {
|
||||
|
|
|
@ -450,7 +450,11 @@ fn mut_subcommand_with_alias_resolve() {
|
|||
let mut cmd =
|
||||
Command::new("foo").subcommand(Command::new("bar").alias("baz").about("test subcmd"));
|
||||
assert_eq!(
|
||||
cmd.find_subcommand("baz").unwrap().get_about().unwrap(),
|
||||
cmd.find_subcommand("baz")
|
||||
.unwrap()
|
||||
.get_about()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
"test subcmd"
|
||||
);
|
||||
|
||||
|
@ -459,7 +463,11 @@ fn mut_subcommand_with_alias_resolve() {
|
|||
|
||||
cmd = cmd.mut_subcommand(&*true_name, |subcmd| subcmd.about("modified about"));
|
||||
assert_eq!(
|
||||
cmd.find_subcommand("baz").unwrap().get_about().unwrap(),
|
||||
cmd.find_subcommand("baz")
|
||||
.unwrap()
|
||||
.get_about()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
"modified about"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -233,7 +233,10 @@ fn doc_comment_about_handles_both_abouts() {
|
|||
}
|
||||
|
||||
let cmd = Opts::command();
|
||||
assert_eq!(cmd.get_about(), Some("Opts doc comment summary"));
|
||||
assert_eq!(
|
||||
cmd.get_about().map(|s| s.to_string()),
|
||||
Some("Opts doc comment summary".to_owned())
|
||||
);
|
||||
// clap will fallback to `about` on `None`. The main care about is not providing a `Sub` doc
|
||||
// comment.
|
||||
assert_eq!(cmd.get_long_about(), None);
|
||||
|
|
|
@ -94,7 +94,11 @@ fn inferred_help() {
|
|||
let mut cmd = Opt::command();
|
||||
cmd.build();
|
||||
let arg = cmd.get_arguments().find(|a| a.get_id() == "help").unwrap();
|
||||
assert_eq!(arg.get_help(), Some("Foo"), "Incorrect help");
|
||||
assert_eq!(
|
||||
arg.get_help().map(|s| s.to_string()),
|
||||
Some("Foo".to_owned()),
|
||||
"Incorrect help"
|
||||
);
|
||||
assert!(matches!(arg.get_action(), clap::ArgAction::Help));
|
||||
}
|
||||
|
||||
|
@ -114,7 +118,11 @@ fn inferred_version() {
|
|||
.get_arguments()
|
||||
.find(|a| a.get_id() == "version")
|
||||
.unwrap();
|
||||
assert_eq!(arg.get_help(), Some("Foo"), "Incorrect help");
|
||||
assert_eq!(
|
||||
arg.get_help().map(|s| s.to_string()),
|
||||
Some("Foo".to_owned()),
|
||||
"Incorrect help"
|
||||
);
|
||||
assert!(matches!(arg.get_action(), clap::ArgAction::Version));
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -'b');
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -54,7 +54,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -b ...);
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -62,7 +62,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Count));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -b "How to use it");
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -70,7 +70,10 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), Some("How to use it"));
|
||||
assert_eq!(
|
||||
arg.get_help().map(|s| s.to_string()),
|
||||
Some("How to use it".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -82,7 +85,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -'b' --hello);
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -91,7 +94,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -b --hello ...);
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -100,7 +103,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Count));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -b --hello "How to use it");
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -109,7 +112,10 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), Some("How to use it"));
|
||||
assert_eq!(
|
||||
arg.get_help().map(|s| s.to_string()),
|
||||
Some("How to use it".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -186,7 +192,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Set));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -'b' <NUM>);
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -194,7 +200,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Set));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -b <NUM> ...);
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -202,7 +208,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Append));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: -b <NUM> "How to use it");
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -210,7 +216,10 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Set));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), Some("How to use it"));
|
||||
assert_eq!(
|
||||
arg.get_help().map(|s| s.to_string()),
|
||||
Some("How to use it".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -221,7 +230,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Set));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!([NUM]);
|
||||
assert_eq!(arg.get_id(), "NUM");
|
||||
|
@ -229,7 +238,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Set));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(!arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(<NUM>);
|
||||
assert_eq!(arg.get_id(), "NUM");
|
||||
|
@ -237,7 +246,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Set));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(foo: <NUM>);
|
||||
assert_eq!(arg.get_id(), "foo");
|
||||
|
@ -245,7 +254,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Set));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(<NUM> ...);
|
||||
assert_eq!(arg.get_id(), "NUM");
|
||||
|
@ -253,7 +262,7 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Append));
|
||||
assert_eq!(arg.get_num_args(), Some((1..).into()));
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), None);
|
||||
assert_eq!(arg.get_help().map(|s| s.to_string()), None);
|
||||
|
||||
let arg = clap::arg!(<NUM> "How to use it");
|
||||
assert_eq!(arg.get_id(), "NUM");
|
||||
|
@ -261,7 +270,10 @@ mod arg {
|
|||
assert!(matches!(arg.get_action(), clap::ArgAction::Set));
|
||||
assert_eq!(arg.get_num_args(), None);
|
||||
assert!(arg.is_required_set());
|
||||
assert_eq!(arg.get_help(), Some("How to use it"));
|
||||
assert_eq!(
|
||||
arg.get_help().map(|s| s.to_string()),
|
||||
Some("How to use it".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Reference in a new issue