mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-07 15:33:51 +00:00
Customize text between option name and description (#497)
* Added an option to change the text between definition and description * Added test and readme * Update Option.hpp Fixed shadowing issue * style: fix formatting Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
parent
b21f2e1bbe
commit
11141525ac
@ -351,6 +351,7 @@ Before parsing, you can set the following options:
|
||||
- `->always_capture_default()`: Always run `capture_default_str()` when creating new options. Only useful on an App's `option_defaults`.
|
||||
- `default_str(string)`: Set the default string directly. This string will also be used as a default value if no arguments are passed and the value is requested.
|
||||
- `default_val(value)`: 🆕 Generate the default string from a value and validate that the value is also valid. For options that assign directly to a value type the value in that type is also updated. Value must be convertible to a string(one of known types or have a stream operator).
|
||||
- `->option_text(string)`: Sets the text between the option name and description.
|
||||
|
||||
|
||||
These options return the `Option` pointer, so you can chain them together, and even skip storing the pointer entirely. The `each` function takes any function that has the signature `void(const std::string&)`; it should throw a `ValidationError` when validation fails. The help message will have the name of the parent option prepended. Since `each`, `check` and `transform` use the same underlying mechanism, you can chain as many as you want, and they will be executed in order. Operations added through `transform` are executed first in reverse order of addition, and `check` and `each` are run following the transform functions in order of addition. If you just want to see the unconverted values, use `.results()` to get the `std::vector<std::string>` of results.
|
||||
|
@ -236,30 +236,34 @@ inline std::string Formatter::make_option_name(const Option *opt, bool is_positi
|
||||
inline std::string Formatter::make_option_opts(const Option *opt) const {
|
||||
std::stringstream out;
|
||||
|
||||
if(opt->get_type_size() != 0) {
|
||||
if(!opt->get_type_name().empty())
|
||||
out << " " << get_label(opt->get_type_name());
|
||||
if(!opt->get_default_str().empty())
|
||||
out << "=" << opt->get_default_str();
|
||||
if(opt->get_expected_max() == detail::expected_max_vector_size)
|
||||
out << " ...";
|
||||
else if(opt->get_expected_min() > 1)
|
||||
out << " x " << opt->get_expected();
|
||||
if(!opt->get_option_text().empty()) {
|
||||
out << " " << opt->get_option_text();
|
||||
} else {
|
||||
if(opt->get_type_size() != 0) {
|
||||
if(!opt->get_type_name().empty())
|
||||
out << " " << get_label(opt->get_type_name());
|
||||
if(!opt->get_default_str().empty())
|
||||
out << "=" << opt->get_default_str();
|
||||
if(opt->get_expected_max() == detail::expected_max_vector_size)
|
||||
out << " ...";
|
||||
else if(opt->get_expected_min() > 1)
|
||||
out << " x " << opt->get_expected();
|
||||
|
||||
if(opt->get_required())
|
||||
out << " " << get_label("REQUIRED");
|
||||
}
|
||||
if(!opt->get_envname().empty())
|
||||
out << " (" << get_label("Env") << ":" << opt->get_envname() << ")";
|
||||
if(!opt->get_needs().empty()) {
|
||||
out << " " << get_label("Needs") << ":";
|
||||
for(const Option *op : opt->get_needs())
|
||||
out << " " << op->get_name();
|
||||
}
|
||||
if(!opt->get_excludes().empty()) {
|
||||
out << " " << get_label("Excludes") << ":";
|
||||
for(const Option *op : opt->get_excludes())
|
||||
out << " " << op->get_name();
|
||||
if(opt->get_required())
|
||||
out << " " << get_label("REQUIRED");
|
||||
}
|
||||
if(!opt->get_envname().empty())
|
||||
out << " (" << get_label("Env") << ":" << opt->get_envname() << ")";
|
||||
if(!opt->get_needs().empty()) {
|
||||
out << " " << get_label("Needs") << ":";
|
||||
for(const Option *op : opt->get_needs())
|
||||
out << " " << op->get_name();
|
||||
}
|
||||
if(!opt->get_excludes().empty()) {
|
||||
out << " " << get_label("Excludes") << ":";
|
||||
for(const Option *op : opt->get_excludes())
|
||||
out << " " << op->get_name();
|
||||
}
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
@ -264,6 +264,9 @@ class Option : public OptionBase<Option> {
|
||||
/// A human readable default value, either manually set, captured, or captured by default
|
||||
std::string default_str_{};
|
||||
|
||||
/// If given, replace the text that describes the option type and usage in the help text
|
||||
std::string option_text_{};
|
||||
|
||||
/// A human readable type value, set when App creates this
|
||||
///
|
||||
/// This is a lambda function so "types" can be dynamic, such as when a set prints its contents.
|
||||
@ -736,6 +739,13 @@ class Option : public OptionBase<Option> {
|
||||
return this;
|
||||
}
|
||||
|
||||
Option *option_text(std::string text) {
|
||||
option_text_ = std::move(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
const std::string &get_option_text() const { return option_text_; }
|
||||
|
||||
///@}
|
||||
/// @name Help tools
|
||||
///@{
|
||||
|
@ -89,6 +89,25 @@ TEST(Formatter, OptCustomizeSimple) {
|
||||
" --opt INT (MUST HAVE) Something\n\n");
|
||||
}
|
||||
|
||||
TEST(Formatter, OptCustomizeOptionText) {
|
||||
CLI::App app{"My prog"};
|
||||
|
||||
app.get_formatter()->column_width(25);
|
||||
|
||||
int v{0};
|
||||
app.add_option("--opt", v, "Something")->option_text("(ARG)");
|
||||
|
||||
std::string help = app.help();
|
||||
|
||||
EXPECT_THAT(help, HasSubstr("(ARG)"));
|
||||
EXPECT_EQ(help,
|
||||
"My prog\n"
|
||||
"Usage: [OPTIONS]\n\n"
|
||||
"Options:\n"
|
||||
" -h,--help Print this help message and exit\n"
|
||||
" --opt (ARG) Something\n\n");
|
||||
}
|
||||
|
||||
TEST(Formatter, FalseFlagExample) {
|
||||
CLI::App app{"My prog"};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user