39 std::stringstream out;
40 std::string commentLead;
41 commentLead.push_back(commentChar);
42 commentLead.push_back(
' ');
44 std::vector<std::string> groups = app->get_groups();
45 bool defaultUsed =
false;
46 groups.insert(groups.begin(), std::string(
"Options"));
47 for (
const auto& group : groups) {
48 if (group ==
"Options" || group.empty()) {
54 if (write_description && group !=
"Options" && !group.empty() &&
55 !app->get_options([group](
const Option* opt) ->
bool {
56 return opt->get_group() == group && opt->get_configurable();
59 out <<
'\n' << commentChar << commentLead << group <<
"\n";
61 for (
const Option* opt : app->get_options({})) {
63 if (opt->get_configurable()) {
64 if (opt->get_group() != group) {
65 if (!(group ==
"Options" && opt->get_group().empty())) {
69 const std::string name = prefix + opt->get_single_name();
71 detail::ini_join(opt->reduced_results(), arraySeparator, arrayStart, arrayEnd, stringQuote, characterQuote);
73 std::string defaultValue{};
75 static_assert(std::string::npos +
static_cast<std::string::size_type>(1) == 0,
76 "std::string::npos + static_cast<std::string::size_type>(1) != 0");
77 if (!value.empty() && opt->get_default_str() == value) {
80 if (!opt->get_default_str().empty()) {
81 defaultValue = detail::convert_arg_for_ini(opt->get_default_str(), stringQuote, characterQuote);
82 }
else if (opt->get_expected_min() == 0) {
83 defaultValue =
"false";
84 }
else if (opt->get_run_callback_for_default()) {
85 defaultValue =
"\"\"";
86 }
else if (opt->get_required()) {
87 defaultValue =
"\"<REQUIRED>\"";
89 defaultValue =
"\"\"";
92 if (write_description && opt->has_description() && (default_also || !value.empty())) {
93 out << commentLead << detail::fix_newlines(commentLead, opt->get_description()) <<
'\n';
96 out << commentChar << name << valueDelimiter << defaultValue <<
"\n";
99 if (!opt->get_fnames().empty()) {
100 value = opt->get_flag_value(name, value);
102 out << name << valueDelimiter << value <<
"\n\n";
109 auto subcommands = app->get_subcommands({});
110 for (
const App* subcom : subcommands) {
111 if (subcom->get_name().empty()) {
112 if (write_description && !subcom->get_group().empty()) {
113 out <<
'\n' << commentLead << subcom->get_group() <<
" Options\n";
115 out << to_config(subcom, default_also, write_description, prefix);
119 for (
const App* subcom : subcommands) {
120 if (!subcom->get_name().empty()) {
121 if (subcom->get_configurable() && app->got_subcommand(subcom)) {
122 if (!prefix.empty() || app->get_parent() ==
nullptr) {
123 out <<
'[' << prefix << subcom->get_name() <<
"]\n";
125 std::string subname = app->get_name() + parentSeparatorChar + subcom->get_name();
126 const auto* p = app->get_parent();
127 while (p->get_parent() !=
nullptr) {
128 subname = p->get_name() + parentSeparatorChar + subname;
131 out <<
'[' << subname <<
"]\n";
133 out << to_config(subcom, default_also, write_description,
"");
135 out << to_config(subcom, default_also, write_description, prefix + subcom->get_name() + parentSeparatorChar);
140 std::string outString;
141 if (write_description && !out.str().empty()) {
143 commentChar + std::string(
"#") + commentLead + detail::fix_newlines(commentChar + commentLead, app->get_description());
146 return outString + out.str();
165 std::string desc = app->get_description();
166 auto min_options = app->get_require_option_min();
167 auto max_options = app->get_require_option_max();
169 if ((max_options == min_options) && (min_options > 0)) {
170 if (min_options == 1) {
171 desc +=
" \n[Exactly 1 of the following options is required]";
173 desc +=
" \n[Exactly " + std::to_string(min_options) +
" options from the following list are required]";
175 }
else if (max_options > 0) {
176 if (min_options > 0) {
177 desc +=
" \n[Between " + std::to_string(min_options) +
" and " + std::to_string(max_options) +
178 " of the follow options are required]";
180 desc +=
" \n[At most " + std::to_string(max_options) +
" of the following options are allowed]";
182 }
else if (min_options > 0) {
183 desc +=
" \n[At least " + std::to_string(min_options) +
" of the following options are required]";
185 return (!desc.empty()) ? desc +
"\n" : std::string{};
189 const std::string usage = app->get_usage();
190 if (!usage.empty()) {
194 std::stringstream out;
196 out << get_label(
"Usage") <<
":" << (name.empty() ?
"" :
" ") << name;
199 const std::vector<
const Option*> non_pos_options = app->get_options([](
const Option* opt) {
200 return opt->nonpositional();
202 if (!non_pos_options.empty()) {
203 out <<
" [" << get_label(
"OPTIONS") <<
"]";
207 std::vector<
const Option*> positionals = app->get_options([](
const Option* opt) {
208 return opt->get_positional();
212 if (!positionals.empty()) {
214 std::vector<std::string> positional_names(positionals.size());
215 std::transform(positionals.begin(), positionals.end(), positional_names.begin(), [
this](
const Option* opt) {
216 return make_option_usage(opt);
219 out <<
" " << detail::join(positional_names,
" ");
223 if (!app->get_subcommands([](
const App* subc) {
224 return !subc->get_disabled() && !subc->get_name().empty();
229 << get_label(app->get_subcommands([](
const CLI::App* subc) {
230 return ((!subc->get_disabled()) && (!subc->get_name().empty()) );
238 const Option* disabledOpt = app->get_option_no_throw(
"--disabled");
239 if (disabledOpt !=
nullptr ? disabledOpt->as<
bool>() :
false) {
240 out <<
" " << get_label(
"DISABLED");
241 }
else if (app->get_required()) {
242 out <<
" " << get_label(
"REQUIRED");
245 out << std::endl << std::endl;
251 std::stringstream out;
253 const std::vector<
const App*> subcommands = app->get_subcommands([](
const App* subc) {
254 return !subc->get_disabled() && !subc->get_name().empty();
258 std::set<std::string> subcmd_groups_seen;
259 for (
const App* com : subcommands) {
260 if (com->get_name().empty()) {
261 if (!com->get_group().empty()) {
262 out << make_expanded(com);
266 std::string group_key = com->get_group();
267 if (!group_key.empty() &&
268 std::find_if(subcmd_groups_seen.begin(), subcmd_groups_seen.end(), [&group_key](
const std::string& a) {
269 return detail::to_lower(a) == detail::to_lower(group_key);
270 }) == subcmd_groups_seen.end()) {
271 subcmd_groups_seen.insert(group_key);
276 for (
const std::string& group : subcmd_groups_seen) {
277 out <<
"\n" << group <<
":\n";
278 const std::vector<
const App*> subcommands_group = app->get_subcommands([&group](
const App* sub_app) {
279 return detail::to_lower(sub_app->get_group()) == detail::to_lower(group) && !sub_app->get_disabled() &&
280 !sub_app->get_name().empty();
282 for (
const App* new_com : subcommands_group) {
283 if (new_com->get_name().empty()) {
286 if (mode != AppFormatMode::All) {
287 out << make_subcommand(new_com);
289 out << new_com->help(new_com->get_name(), AppFormatMode::Sub);
297 std::string tmp = out.str();
298 if (mode == AppFormatMode::All && !tmp.empty()) {
319 std::stringstream out;
321 const Option* disabledOpt = sub->get_option_no_throw(
"--disabled");
322 out << sub->get_display_name(
true) +
" [OPTIONS]" + (!sub->get_subcommands({}).empty() ?
" [SECTIONS]" :
"") +
323 ((disabledOpt !=
nullptr ? disabledOpt->as<
bool>() :
false) ?
""
324 : (sub->get_required() ?
" " + get_label(
"REQUIRED") :
""))
327 out << make_description(sub);
328 if (sub->get_name().empty() && !sub->get_aliases().empty()) {
329 detail::format_aliases(out, sub->get_aliases(), column_width_ + 2);
331 out << make_positionals(sub);
332 out << make_groups(sub, AppFormatMode::Sub);
333 out << make_subcommands(sub, AppFormatMode::Sub);
336 std::string tmp = out.str();
340 return detail::find_and_replace(tmp,
"\n",
"\n ") +
"\n";
344 std::stringstream out;
346 if (!opt->get_option_text().empty()) {
347 out <<
" " << opt->get_option_text();
349 if (opt->get_type_size() != 0) {
350 if (!opt->get_type_name().empty()) {
352 out << ((opt->get_items_expected_max() == 0) ?
"=" :
" ") << get_label(opt->get_type_name());
354 if (!opt->get_default_str().empty()) {
355 out <<
" [" << opt->get_default_str() <<
"]";
357 if (opt->get_expected_max() == detail::expected_max_vector_size) {
359 }
else if (opt->get_expected_min() > 1) {
360 out <<
" x " << opt->get_expected();
362 if (opt->get_required()) {
363 out <<
" " << get_label(
"REQUIRED");
365 if (opt->get_configurable()) {
366 out <<
" " << get_label(
"PERSISTENT");
369 if (!opt->get_envname().empty()) {
370 out <<
" (" << get_label(
"Env") <<
":" << opt->get_envname() <<
") ";
372 if (!opt->get_needs().empty()) {
373 out <<
" " << get_label(
"Needs") <<
":";
374 for (
const Option* op : opt->get_needs()) {
375 out <<
" " << op->get_name();
379 if (!opt->get_excludes().empty()) {
380 out <<
" " << get_label(
"Excludes") <<
":";
381 for (
const Option* op : opt->get_excludes()) {
382 out <<
" " << op->get_name();