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

fix(help): Use a more neutral palette #4117

Merged
merged 1 commit into from Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -82,6 +82,7 @@ MSRV is now 1.60.0
- *(assert)* Ensure subcommand names are not duplicated
- *(help)* Use `Command::display_name` in the help title rather than `Command::bin_name`
- *(help)* Show when a flag is `ArgAction::Count` by adding an `...`
- *(help)* Use a more neutral palette for coloring
- *(version)* Use `Command::display_name` rather than `Command::bin_name`
- *(parser)* Assert on unknown args when using external subcommands (#3703)
- *(parser)* Always fill in `""` argument for external subcommands (#3263)
Expand Down
27 changes: 13 additions & 14 deletions src/builder/arg.rs
Expand Up @@ -3979,11 +3979,11 @@ impl Arg {
let mut styled = StyledStr::new();
// Write the name such --long or -l
if let Some(l) = self.get_long() {
styled.none("--");
styled.none(l);
styled.literal("--");
styled.literal(l);
} else if let Some(s) = self.get_short() {
styled.none("-");
styled.none(s);
styled.literal("-");
styled.literal(s);
}
styled.extend(self.stylize_arg_suffix().into_iter());
styled
Expand All @@ -3995,29 +3995,28 @@ impl Arg {
let mut need_closing_bracket = false;
if self.is_takes_value_set() && !self.is_positional() {
let is_optional_val = self.get_min_vals() == 0;
let sep = if self.is_require_equals_set() {
if self.is_require_equals_set() {
if is_optional_val {
need_closing_bracket = true;
"[="
styled.placeholder("[=");
} else {
"="
styled.literal("=");
}
} else if is_optional_val {
need_closing_bracket = true;
" ["
styled.placeholder(" [");
} else {
" "
};
styled.good(sep);
styled.placeholder(" ");
}
}
if self.is_takes_value_set() || self.is_positional() {
let arg_val = self.render_arg_val();
styled.good(arg_val);
styled.placeholder(arg_val);
} else if matches!(*self.get_action(), ArgAction::Count) {
styled.good("...");
styled.placeholder("...");
}
if need_closing_bracket {
styled.none("]");
styled.placeholder("]");
}

styled
Expand Down
25 changes: 25 additions & 0 deletions src/builder/styled_str.rs
Expand Up @@ -13,6 +13,18 @@ impl StyledStr {
Self { pieces: Vec::new() }
}

pub(crate) fn header(&mut self, msg: impl Into<String>) {
self.stylize_(Some(Style::Header), msg.into());
}

pub(crate) fn literal(&mut self, msg: impl Into<String>) {
self.stylize_(Some(Style::Literal), msg.into());
}

pub(crate) fn placeholder(&mut self, msg: impl Into<String>) {
self.stylize_(Some(Style::Placeholder), msg.into());
}

pub(crate) fn good(&mut self, msg: impl Into<String>) {
self.stylize_(Some(Style::Good), msg.into());
}
Expand Down Expand Up @@ -137,6 +149,16 @@ impl StyledStr {
for (style, content) in &self.pieces {
let mut color = termcolor::ColorSpec::new();
match style {
Some(Style::Header) => {
color.set_bold(true);
color.set_underline(true);
}
Some(Style::Literal) => {
color.set_bold(true);
}
Some(Style::Placeholder) => {
color.set_dimmed(true);
}
Some(Style::Good) => {
color.set_fg(Some(termcolor::Color::Green));
}
Expand Down Expand Up @@ -212,6 +234,9 @@ impl std::fmt::Display for StyledStr {

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum Style {
Header,
Literal,
Placeholder,
Good,
Warning,
Error,
Expand Down
32 changes: 16 additions & 16 deletions src/output/help.rs
Expand Up @@ -155,7 +155,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
self.write_about(true, true);
}
"usage-heading" => {
self.warning("USAGE:");
self.header("USAGE:");
}
"usage" => {
self.writer
Expand Down Expand Up @@ -215,7 +215,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
.replace("{n}", "\n"),
self.term_w,
);
self.good(&display_name);
self.none(&display_name);
}

/// Writes binary name of a Parser Object to the wrapped stream.
Expand All @@ -232,7 +232,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
} else {
wrap(&self.cmd.get_name().replace("{n}", "\n"), self.term_w)
};
self.good(&bin_name);
self.none(&bin_name);
}

fn write_version(&mut self) {
Expand Down Expand Up @@ -340,7 +340,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {

let mut first = if !pos.is_empty() {
// Write positional args if any
self.warning("ARGS:\n");
self.header("ARGS:\n");
self.write_args(&pos, "ARGS", positional_sort_key);
false
} else {
Expand All @@ -351,7 +351,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
if !first {
self.none("\n\n");
}
self.warning("OPTIONS:\n");
self.header("OPTIONS:\n");
self.write_args(&non_pos, "OPTIONS", option_sort_key);
first = false;
}
Expand All @@ -373,7 +373,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
if !first {
self.none("\n\n");
}
self.warning(format!("{}:\n", heading));
self.header(format!("{}:\n", heading));
self.write_args(&args, heading, option_sort_key);
first = false
}
Expand All @@ -386,12 +386,12 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
}

let default_help_heading = Str::from("SUBCOMMANDS");
self.warning(
self.header(
self.cmd
.get_subcommand_help_heading()
.unwrap_or(&default_help_heading),
);
self.warning(":\n");
self.header(":\n");

self.write_subcommands(self.cmd);
}
Expand Down Expand Up @@ -465,7 +465,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
debug!("Help::short");

if let Some(s) = arg.get_short() {
self.good(format!("-{}", s));
self.literal(format!("-{}", s));
} else if arg.get_long().is_some() {
self.none(TAB)
}
Expand All @@ -478,7 +478,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
if arg.short.is_some() {
self.none(", ");
}
self.good(format!("--{}", long));
self.literal(format!("--{}", long));
}
}

Expand Down Expand Up @@ -622,7 +622,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
self.none("\n");
self.spaces(spaces);
self.none("- ");
self.good(pv.get_name());
self.literal(pv.get_name());
if let Some(help) = pv.get_help() {
debug!("Help::help: Possible Value help");

Expand Down Expand Up @@ -775,12 +775,12 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
self.writer.extend(msg.iter());
}

fn good<T: Into<String>>(&mut self, msg: T) {
self.writer.good(msg);
fn header<T: Into<String>>(&mut self, msg: T) {
self.writer.header(msg);
}

fn warning<T: Into<String>>(&mut self, msg: T) {
self.writer.warning(msg);
fn literal<T: Into<String>>(&mut self, msg: T) {
self.writer.literal(msg);
}

fn none<T: Into<String>>(&mut self, msg: T) {
Expand Down Expand Up @@ -915,7 +915,7 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
/// Writes subcommand to the wrapped stream.
fn subcmd(&mut self, sc_str: &str, next_line_help: bool, longest: usize) {
self.none(TAB);
self.good(sc_str);
self.literal(sc_str);
if !next_line_help {
let width = display_width(sc_str);
self.spaces(width.max(longest + 4) - width);
Expand Down
55 changes: 28 additions & 27 deletions src/output/usage.rs
Expand Up @@ -32,7 +32,7 @@ impl<'cmd> Usage<'cmd> {
pub(crate) fn create_usage_with_title(&self, used: &[Id]) -> StyledStr {
debug!("Usage::create_usage_with_title");
let mut styled = StyledStr::new();
styled.none("USAGE:\n ");
styled.header("USAGE:\n ");
styled.extend(self.create_usage_no_title(used).into_iter());
styled
}
Expand All @@ -58,10 +58,10 @@ impl<'cmd> Usage<'cmd> {
.get_usage_name()
.or_else(|| self.cmd.get_bin_name())
.unwrap_or_else(|| self.cmd.get_name());
styled.none(name);
styled.literal(name);

if self.needs_options_tag() {
styled.none(" [OPTIONS]");
styled.placeholder(" [OPTIONS]");
}

let allow_missing_positional = self.cmd.is_allow_missing_positional_set();
Expand All @@ -80,15 +80,15 @@ impl<'cmd> Usage<'cmd> {
&& !(self.cmd.has_visible_subcommands() || self.cmd.is_allow_external_subcommands_set())
&& !has_last
{
styled.none(" [--]");
styled.placeholder(" [--]");
}
let not_req_or_hidden =
|p: &Arg| (!p.is_required_set() || p.is_last_set()) && !p.is_hide_set();
if self.cmd.get_positionals().any(not_req_or_hidden) {
if let Some(args_tag) = self.get_args_tag(incl_reqs) {
styled.none(&*args_tag);
styled.placeholder(&*args_tag);
} else {
styled.none(" [ARGS]");
styled.placeholder(" [ARGS]");
}
if has_last && incl_reqs {
let pos = self
Expand All @@ -102,17 +102,18 @@ impl<'cmd> Usage<'cmd> {
);
let req = pos.is_required_set();
if req && self.cmd.get_positionals().any(|p| !p.is_required_set()) {
styled.none(" -- <");
styled.literal(" -- ");
styled.placeholder("<");
} else if req {
styled.none(" [--] <");
styled.placeholder(" [--] <");
} else {
styled.none(" [-- <");
styled.placeholder(" [-- <");
}
styled.none(&*pos.name_no_brackets());
styled.none('>');
styled.none(pos.multiple_str());
styled.placeholder(&*pos.name_no_brackets());
styled.placeholder('>');
styled.placeholder(pos.multiple_str());
if !req {
styled.none(']');
styled.placeholder(']');
}
}
}
Expand All @@ -136,19 +137,19 @@ impl<'cmd> Usage<'cmd> {
if !self.cmd.is_args_conflicts_with_subcommands_set() {
styled.extend(self.create_help_usage(false).into_iter());
} else {
styled.none(name);
styled.literal(name);
}
styled.none(" <");
styled.none(placeholder);
styled.none(">");
styled.placeholder(" <");
styled.placeholder(placeholder);
styled.placeholder(">");
} else if self.cmd.is_subcommand_required_set() {
styled.none(" <");
styled.none(placeholder);
styled.none(">");
styled.placeholder(" <");
styled.placeholder(placeholder);
styled.placeholder(">");
} else {
styled.none(" [");
styled.none(placeholder);
styled.none("]");
styled.placeholder(" [");
styled.placeholder(placeholder);
styled.placeholder("]");
}
}
styled.trim();
Expand All @@ -162,7 +163,7 @@ impl<'cmd> Usage<'cmd> {
debug!("Usage::create_smart_usage");
let mut styled = StyledStr::new();

styled.none(
styled.literal(
self.cmd
.get_usage_name()
.or_else(|| self.cmd.get_bin_name())
Expand All @@ -172,13 +173,13 @@ impl<'cmd> Usage<'cmd> {
self.write_required_usage_from(used, None, true, &mut styled);

if self.cmd.is_subcommand_required_set() {
styled.none(" <");
styled.none(
styled.placeholder(" <");
styled.placeholder(
self.cmd
.get_subcommand_value_name()
.unwrap_or(DEFAULT_SUB_VALUE_NAME),
);
styled.none(">");
styled.placeholder(">");
}
styled
}
Expand Down