Ookii.CommandLine for C++  2.0.0
usage_writer.h
Go to the documentation of this file.
1 #ifndef OOKII_USAGE_WRITER_H_
4 #define OOKII_USAGE_WRITER_H_
5 
6 #pragma once
7 
8 #include "string_helper.h"
9 #include "line_wrapping_stream.h"
10 #include "scope_helper.h"
11 
12 namespace ookii
13 {
14  template<typename CharType, typename Traits, typename Alloc>
15  class basic_command_line_parser;
16 
17  template<typename CharType, typename Traits, typename Alloc>
18  class basic_command_manager;
19 
20  template<typename CharType, typename Traits, typename Alloc>
21  class command_info;
22 
23 
25  enum class usage_help_request
26  {
28  full,
34  none
35  };
36 
39  {
44  descripion,
46  all,
48  none,
49  };
50 
53  {
70  };
71 
97  template<typename CharType, typename Traits = std::char_traits<CharType>, typename Alloc = std::allocator<CharType>>
99  {
101 
102  std::optional<line_wrapping_stream_type> _owned_output;
103  std::optional<line_wrapping_stream_type> _owned_error;
104 
105  public:
107  struct defaults
108  {
110  static constexpr auto name_separator = literal_cast<CharType>(", ");
112  static constexpr size_t application_description_indent = 0;
114  static constexpr size_t syntax_indent = 3;
116  static constexpr size_t argument_description_indent = 8;
118  static constexpr size_t command_description_indent = 8;
119  };
120 
122  using string_type = std::basic_string<CharType, Traits, Alloc>;
124  using string_view_type = std::basic_string_view<CharType, Traits>;
126  using stream_type = std::basic_ostream<CharType, Traits>;
135 
144  basic_usage_writer(std::optional<bool> use_color = {})
145  : _owned_output{line_wrapping_stream_type::for_cout()},
146  _owned_error{line_wrapping_stream_type::for_cerr()},
147  output{*_owned_output},
148  error{*_owned_error},
149  _use_color{use_color}
150  {
151  }
152 
161  : output{output},
162  error{output},
163  _use_color{use_color}
164  {
165  }
166 
175  : output{output},
176  error{error},
177  _use_color{use_color}
178  {
179  }
180 
181  virtual ~basic_usage_writer()
182  {
183  }
184 
187 
190 
197 
204 
211 
217 
223 
233 
238 
243 
248 
258 
263 
268 
273 
278 
285 
290 
307 
323 
339 
352 
363 
369  {
370  _parser = &parser;
371  write_usage_internal(parser.locale(), request);
372  }
373 
377  virtual void write_command_list_usage(const command_manager_type &manager)
378  {
379  _command_manager = &manager;
380  write_usage_internal(manager.locale());
381  }
382 
385  {
386  auto support = enable_error_color();
387  if (support)
388  {
389  error << error_color;
390  }
391 
392  error << message;
393  if (support)
394  {
395  error << color_reset;
396  }
397 
398  error << std::endl << std::endl;
399  }
400 
401  protected:
415  {
416  if (request == usage_help_request::none)
417  {
419  return;
420  }
421 
422  if (request == usage_help_request::full && include_application_description && !parser().description().empty())
423  {
424  write_application_description(parser().description());
425  }
426 
428  if (request == usage_help_request::full)
429  {
431  }
432  else
433  {
434  output << reset_indent << set_indent(0);
436  }
437  }
438 
446  {
448  output << description << std::endl << std::endl;
449  }
450 
455  {
457  write_usage_syntax_prefix(parser().command_name());
458  for (const auto &arg : parser().arguments())
459  {
460  output << ' ';
461  if (use_abbreviated_syntax && !arg.position())
462  {
464  break;
465  }
466 
467  if (arg.is_required())
468  {
470  }
471  else
472  {
474  }
475  }
476 
477  output << std::endl;
479  {
480  output << std::endl;
481  }
482  }
483 
497  virtual void write_usage_syntax_prefix(string_view_type command_name)
498  {
500  output << "Usage:";
502  output << " " << command_name;
503  }
504 
513  {
514  output << "[arguments]";
515  }
516 
526  {
527  output << c_optionalStart;
529  output << c_optionalEnd;
530  }
531 
539  virtual void write_argument_syntax(const argument_type &arg)
540  {
541  string_view_type name;
542  CharType short_name;
544  {
545  short_name = arg.short_name();
546  name = string_view_type(&short_name, 1);
547  }
548  else
549  {
550  name = arg.name();
551  }
552 
553  const auto &prefix = parser().mode() != parsing_mode::long_short || (arg.has_short_name() && (use_short_names_for_syntax || !arg.has_long_name()))
554  ? parser().prefixes()[0]
555  : parser().long_prefix();
556 
557  std::optional<CharType> separator = parser().allow_white_space_separator() && use_white_space_value_separator
558  ? std::nullopt
559  : std::optional<CharType>(parser().argument_value_separator());
560 
561  if (arg.position())
562  {
563  write_positional_argument_name(name, prefix, separator);
564  }
565  else
566  {
567  write_argument_name(name, prefix);
568  }
569 
570  if (!arg.is_switch())
571  {
572  // Otherwise, the separator was included in the argument name.
573  if (!arg.position() || !separator)
574  {
575  if (separator)
576  {
577  output << *separator;
578  }
579  else
580  {
581  output << ' ';
582  }
583  }
584 
586  }
587 
588  if (arg.is_multi_value())
589  {
591  }
592  }
593 
604  {
605  output << prefix << name;
606  }
607 
620  virtual void write_positional_argument_name(string_view_type name, string_view_type prefix, std::optional<CharType> separator)
621  {
622  output << c_optionalStart;
623  write_argument_name(name, prefix);
624  if (separator)
625  {
626  output << *separator;
627  }
628 
629  output << c_optionalEnd;
630  }
631 
641  {
642  output << '<' << value_description << '>';
643  }
644 
650  virtual void write_multi_value_suffix()
651  {
652  output << "...";
653  }
654 
662  virtual void write_argument_descriptions()
663  {
664  auto indent = argument_description_indent;
665  if (parser().mode() == parsing_mode::long_short)
666  {
667  // For long/short mode, increase the indentation by the size of the short argument.
668  indent += parser().prefixes()[0].length() + name_separator.length() + 1;
669  }
670 
671  output << set_indent(indent);
672  bool first = true;
673  for_each_argument_in_description_order([this, &first](const auto &arg)
674  {
675  if (first)
676  {
677  write_argument_description_list_header();
678  first = false;
679  }
680 
681  write_argument_description(arg);
682 
683  return true;
684  });
685  }
686 
694  virtual void write_argument_description_list_header()
695  {
696  // Intentionally blank.
697  }
698 
709  virtual void write_argument_description(const argument_type &arg)
710  {
711  write_argument_description_header(arg);
712  write_argument_description_body(arg);
713 
714  if (blank_line_after_description)
715  {
716  output << std::endl;
717  }
718  }
719 
733  virtual void write_argument_description_header(const argument_type &arg)
734  {
735  output << reset_indent;
736  write_spacing(argument_description_indent / 2);
737  const auto &short_prefix = parser().prefixes()[0];
738  const auto &prefix = parser().long_prefix().length() == 0
739  ? short_prefix
740  : parser().long_prefix();
741 
742  set_color(argument_description_color);
743  if (parser().mode() == parsing_mode::long_short)
744  {
745  if (arg.has_short_name())
746  {
747  auto short_name = arg.short_name();
748  write_argument_name_for_description(string_view_type{&short_name, 1}, short_prefix);
749  if (arg.has_long_name())
750  {
751  output << name_separator;
752  }
753  }
754  else
755  {
756  write_spacing(short_prefix.length() + name_separator.length() + 1);
757  }
758 
759  if (arg.has_long_name())
760  {
761  write_argument_name_for_description(arg.name(), prefix);
762  }
763  }
764  else
765  {
766  write_argument_name_for_description(arg.name(), prefix);
767  }
768 
769  output << ' ';
770  if (arg.is_switch())
771  {
772  write_switch_value_description(arg.value_description());
773  }
774  else
775  {
776  write_value_description_for_description(arg.value_description());
777  }
778 
779  if (include_aliases_in_description)
780  {
781  write_aliases(arg.aliases(), arg.short_aliases(), prefix, short_prefix);
782  }
783 
784  set_color(color_reset);
785  output << std::endl;
786  }
787 
799  virtual void write_argument_description_body(const argument_type &arg)
800  {
801  if (!arg.description().empty())
802  {
803  write_argument_description(arg.description());
804  }
805 
806  if (include_default_value_in_description && arg.has_default_value())
807  {
808  write_default_value(arg);
809  }
810 
811  output << std::endl;
812  }
813 
823  virtual void write_argument_name_for_description(string_view_type name, string_view_type prefix)
824  {
825  output << prefix << name;
826  }
827 
838  virtual void write_value_description_for_description(string_view_type value_description)
839  {
840  output << '<' << value_description << '>';
841  }
842 
854  virtual void write_switch_value_description(string_view_type value_description)
855  {
856  output << c_optionalStart;
857  write_value_description_for_description(value_description);
858  output << c_optionalEnd;
859  }
860 
875  virtual void write_aliases(const std::vector<string_type> &aliases, const std::vector<CharType> &short_aliases,
876  string_view_type prefix, string_view_type short_prefix)
877  {
878  bool first = true;
879  for (const auto &alias : short_aliases)
880  {
881  if (first)
882  {
883  output << " (";
884  first = false;
885  }
886  else
887  {
888  output << name_separator;
889  }
890 
891  write_alias(string_view_type{&alias, 1}, short_prefix);
892  }
893 
894  for (const auto &alias : aliases)
895  {
896  if (first)
897  {
898  output << " (";
899  first = false;
900  }
901  else
902  {
903  output << name_separator;
904  }
905 
906  write_alias(alias, prefix);
907  }
908 
909  if (!first)
910  {
911  output << ")";
912  }
913  }
914 
923  virtual void write_alias(string_view_type alias, string_view_type prefix)
924  {
925  write_argument_name_for_description(alias, prefix);
926  }
927 
936  virtual void write_argument_description(string_view_type description)
937  {
938  output << description;
939  }
940 
951  virtual void write_default_value(const argument_type &arg)
952  {
953  output << " Default value: ";
954  arg.write_default_value(output);
955  output << '.';
956  }
957 
968  virtual void write_more_info_message()
969  {
970  auto arg = parser().get_help_argument();
971  if (arg != nullptr)
972  {
973  output << "Run '" << parser().command_name() << " " << arg->name_with_prefix(parser()) << "' for more information."
974  << std::endl;
975  }
976  }
977 
988  virtual void write_command_list_usage_core()
989  {
990  if (!command_manager().description().empty())
991  {
992  write_application_description(command_manager().description());
993  }
994 
995  output << reset_indent << set_indent(syntax_indent);
996  write_command_list_usage_syntax();
997  output << reset_indent << set_indent(0);
998  write_available_commands_header();
999  write_command_descriptions();
1000  output << reset_indent << set_indent(0);
1001  write_command_list_usage_footer();
1002  }
1003 
1011  virtual void write_command_list_usage_syntax()
1012  {
1013  write_usage_syntax_prefix(command_manager().application_name());
1014  output << " <command> [arguments]" << std::endl;
1015  if (blank_line_after_syntax)
1016  {
1017  output << std::endl;
1018  }
1019  }
1020 
1028  virtual void write_available_commands_header()
1029  {
1030  output << "The following commands are available:" << std::endl << std::endl;
1031  }
1032 
1039  virtual void write_command_descriptions()
1040  {
1041  output << set_indent(command_description_indent);
1042  for (const auto &command : command_manager().commands())
1043  {
1044  write_command_description(command);
1045  }
1046  }
1047 
1058  virtual void write_command_description(const command_info_type &command)
1059  {
1060  write_command_description_header(command);
1061  write_command_description_body(command);
1062 
1063  if (blank_line_after_command_description)
1064  {
1065  output << std::endl;
1066  }
1067  }
1068 
1080  virtual void write_command_description_header(const command_info_type &command)
1081  {
1082  output << reset_indent;
1083  write_spacing(command_description_indent / 2);
1084  set_color(command_description_color);
1085  write_command_name(command.name());
1086  set_color(color_reset);
1087  output << std::endl;
1088  }
1089 
1099  virtual void write_command_description_body(const command_info_type &command)
1100  {
1101  if (!command.description().empty())
1102  {
1103  write_command_description(command.description());
1104  output << std::endl;
1105  }
1106  }
1107 
1116  virtual void write_command_name(string_view_type name)
1117  {
1118  output << name;
1119  }
1120 
1129  virtual void write_command_description(string_view_type description)
1130  {
1131  output << description;
1132  }
1133 
1138  virtual void write_command_list_usage_footer()
1139  {
1140  if (!command_manager().common_help_argument().empty())
1141  {
1142  // If there wasn't already a blank line after the last command, add one now.
1144  {
1145  output << std::endl;
1146  }
1147 
1148  output << "Run '" << command_manager().application_name() << " <command> " <<
1149  command_manager().common_help_argument() << "' for more information about a command." << std::endl;
1150  }
1151  }
1152 
1155  virtual void write_spacing(size_t count)
1156  {
1157  for (size_t i = 0; i < count; ++i)
1158  {
1159  output << ' ';
1160  }
1161  }
1162 
1167  const parser_type &parser() const
1168  {
1169  return *_parser;
1170  }
1171 
1177  {
1178  return *_command_manager;
1179  }
1180 
1185  bool use_color() const
1186  {
1187  return _use_color && *_use_color;
1188  }
1189 
1192  void set_color(const char *color)
1193  {
1194  if (use_color())
1195  {
1196  output << color;
1197  }
1198  }
1199 
1204  template<typename Func>
1206  {
1207  if (argument_description_list_filter == description_list_filter_mode::none)
1208  {
1209  return;
1210  }
1211 
1212  if (argument_description_list_order == description_list_sort_mode::usage_order)
1213  {
1214  for (const auto &arg : parser().arguments())
1215  {
1216  if (check_filter(arg))
1217  {
1218  f(arg);
1219  }
1220  }
1221 
1222  return;
1223  }
1224 
1225  std::vector<const argument_type *> arguments;
1226  arguments.reserve(parser().argument_count());
1227  auto source = parser().arguments();
1228  std::transform(source.begin(), source.end(), std::back_inserter(arguments), [](const auto &arg) { return &arg; });
1229  std::sort(arguments.begin(), arguments.end(), get_sort_function());
1230  for (const auto &arg : arguments)
1231  {
1232  if (check_filter(*arg))
1233  {
1234  f(*arg);
1235  }
1236  }
1237  }
1238 
1239  private:
1240 
1241  bool check_filter(const argument_type &arg) const
1242  {
1243  switch (argument_description_list_filter)
1244  {
1246  return has_information(arg);
1247 
1249  return !arg.description().empty();
1250 
1252  return true;
1253 
1254  default:
1255  return false;
1256  }
1257  }
1258 
1259  bool has_information(const argument_type &arg) const
1260  {
1261  if (!arg.description().empty())
1262  {
1263  return true;
1264  }
1265 
1266  if (use_abbreviated_syntax && arg.position())
1267  {
1268  return true;
1269  }
1270 
1271  if (parser().mode() == parsing_mode::long_short && use_short_names_for_syntax)
1272  {
1273  if (arg.has_long_name())
1274  {
1275  return true;
1276  }
1277  }
1278  else if (arg.has_short_name())
1279  {
1280  return true;
1281  }
1282 
1283  if (include_aliases_in_description && (!arg.aliases().empty() || !arg.short_aliases().empty()))
1284  {
1285  return true;
1286  }
1287 
1288  if (include_default_value_in_description && arg.has_default_value())
1289  {
1290  return true;
1291  }
1292 
1293  return false;
1294  }
1295 
1296  std::function<bool(const argument_type *, const argument_type *)> get_sort_function() const
1297  {
1298  auto comparer = parser().argument_comparer();
1299  switch (argument_description_list_order)
1300  {
1302  return [comparer](const argument_type *left, const argument_type *right)
1303  {
1304  return comparer(left->name(), right->name());
1305  };
1306 
1308  return [comparer](const argument_type *left, const argument_type *right)
1309  {
1310  return comparer(right->name(), left->name());
1311  };
1312 
1314  return [comparer](const argument_type *left, const argument_type *right)
1315  {
1316  return comparer(left->short_or_long_name(), right->short_or_long_name());
1317  };
1318 
1320  return [comparer](const argument_type *left, const argument_type *right)
1321  {
1322  return comparer(right->short_or_long_name(), left->short_or_long_name());
1323  };
1324 
1325  default:
1326  throw std::logic_error("Invalid sort mode.");
1327  }
1328  }
1329 
1330  void write_usage_internal(const std::locale &loc, usage_help_request request = usage_help_request::full)
1331  {
1332  auto old_output_loc = output.imbue(loc);
1333  std::optional<std::locale> old_error_loc;
1334  details::scope_exit revert{[this, &old_output_loc, &old_error_loc]()
1335  {
1336  _parser = nullptr;
1337  if (old_error_loc)
1338  {
1339  error.imbue(*old_error_loc);
1340  }
1341 
1342  output.imbue(old_output_loc);
1343  }
1344  };
1345 
1346  if (std::addressof(output) != std::addressof(error))
1347  {
1348  old_error_loc = error.imbue(loc);
1349  }
1350 
1351  auto color = enable_color();
1352  output << set_indent(0) << reset_indent;
1353  if (_parser != nullptr)
1354  {
1355  write_parser_usage_core(request);
1356  }
1357  else
1358  {
1359  write_command_list_usage_core();
1360  }
1361  }
1362 
1363  vt::virtual_terminal_support enable_color()
1364  {
1365  if (!_use_color)
1366  {
1368  _use_color = support.is_supported();
1369  return support;
1370  }
1371 
1372  return {};
1373  }
1374 
1375  vt::virtual_terminal_support enable_error_color()
1376  {
1377  if (!_use_color)
1378  {
1380  }
1381 
1382  return {};
1383  }
1384 
1385  const parser_type *_parser{};
1386  const command_manager_type *_command_manager{};
1387  std::optional<bool> _use_color;
1388 
1389  static constexpr char c_optionalStart = '[';
1390  static constexpr char c_optionalEnd = ']';
1391  };
1392 
1397 
1398 }
1399 
1400 #endif
Parses command line arguments into strongly-typed values.
Definition: command_line_parser.h:106
parsing_mode mode() const noexcept
Gets the parsing mode used by this parser.
Definition: command_line_parser.h:243
const std::vector< string_type > & prefixes() const noexcept
Gets a list of all the argument name prefixes accepted by the parser.
Definition: command_line_parser.h:293
const std::locale & locale() const noexcept
Gets the locale used to parse argument values and to format strings.
Definition: command_line_parser.h:311
const string_type & long_prefix() const noexcept
Gets the long argument prefix.
Definition: command_line_parser.h:303
bool allow_white_space_separator() const noexcept
Indicates whether argument names and values can be separated by white space.
Definition: command_line_parser.h:267
Manages registration, creation and invocation of subcommands for an application.
Definition: subcommand.h:313
basic_command_manager & common_help_argument(string_type name_with_prefix)
Sets the name of a help argument, including prefix, that is used by all subcommands.
Definition: subcommand.h:391
const string_type & application_name() const noexcept
Gets the name of the application containing the command.
Definition: subcommand.h:513
const std::locale & locale() const noexcept
Gets the locale used to parse argument values and to format strings.
Definition: subcommand.h:519
Output stream that wraps lines on white-space characters at the specified line length,...
Definition: line_wrapping_stream.h:749
static basic_line_wrapping_ostream for_cout(short default_width=80)
Creates a basic_line_wrapping_ostream that writes to the standard output stream, using the console wi...
Definition: line_wrapping_stream.h:815
static basic_line_wrapping_ostream for_cerr(short default_width=80)
Creates a basic_line_wrapping_ostream that writes to the standard error stream, using the console wid...
Definition: line_wrapping_stream.h:825
Creates usage help for the basic_command_line_parser and basic_command_manager classes.
Definition: usage_writer.h:99
basic_usage_writer(stream_type &output, stream_type &error, bool use_color=false)
Initializes a new instance of the basic_usage_writer class with the specified output and error stream...
Definition: usage_writer.h:174
bool use_abbreviated_syntax
Indicates whether to list only positional arguments in the usage syntax.
Definition: usage_writer.h:257
const char * error_color
The color applied by the write_error() method.
Definition: usage_writer.h:351
stream_type & output
The stream used to write usage help to.
Definition: usage_writer.h:186
virtual void write_positional_argument_name(string_view_type name, string_view_type prefix, std::optional< CharType > separator)
Writes the name of a positional argument.
Definition: usage_writer.h:620
virtual void write_usage_syntax_prefix(string_view_type command_name)
Writes the prefix for the usage syntax, including the executable name and, for subcommands,...
Definition: usage_writer.h:497
bool blank_line_after_syntax
Indicates whether to add a blank line after the usage syntax.
Definition: usage_writer.h:262
basic_usage_writer(std::optional< bool > use_color={})
Initializes a new instance of the basic_usage_writer class.
Definition: usage_writer.h:144
bool include_aliases_in_description
Indicates whether to include the aliases of arguments in the description.
Definition: usage_writer.h:247
stream_type & error
The stream used to write errors to.
Definition: usage_writer.h:189
virtual void write_parser_usage(const parser_type &parser, usage_help_request request=usage_help_request::full)
Creates usage help for the specified parser.
Definition: usage_writer.h:368
virtual void write_value_description(string_view_type value_description)
Writes the value description of an argument.
Definition: usage_writer.h:640
std::basic_ostream< CharType, Traits > stream_type
The concrete stream type used.
Definition: usage_writer.h:126
virtual void write_argument_descriptions()
Writes the list of argument descriptions.
Definition: usage_writer.h:662
virtual void write_command_list_usage(const command_manager_type &manager)
Creates usage help for the specified command manager.
Definition: usage_writer.h:377
virtual void write_spacing(size_t count)
Writes the specified amount of spaces.
Definition: usage_writer.h:1155
size_t argument_description_indent
The level of indentation to use when writing argument descriptions.
Definition: usage_writer.h:210
void for_each_argument_in_description_order(Func f) const
Iterates over the arguments in the order set by the argument_description_list_order field,...
Definition: usage_writer.h:1205
bool include_application_description
Indicates whether to include the application description in the usage help.
Definition: usage_writer.h:237
virtual void write_parser_usage_syntax()
Writes the usage syntax for the application or subcommand.
Definition: usage_writer.h:454
virtual void write_abbreviated_remaining_arguments()
Writes the string used to indicate there are more arguments if the usage syntax was abbreviated.
Definition: usage_writer.h:512
description_list_filter_mode argument_description_list_filter
A value that indicates which arguments should be included in the list of argument descriptions.
Definition: usage_writer.h:216
const command_manager_type & command_manager() const
Gets the basic_command_manager that usage is being written for.
Definition: usage_writer.h:1176
bool blank_line_after_description
Indicates whether to add a blank line after each argument's description.
Definition: usage_writer.h:272
std::basic_string_view< CharType, Traits > string_view_type
The concrete string_view type used.
Definition: usage_writer.h:124
virtual void write_more_info_message()
Writes a message telling to user how to get more detailed help.
Definition: usage_writer.h:968
void write_error(string_view_type message)
Writes an error message to the error stream, using color if enabled.
Definition: usage_writer.h:384
description_list_sort_mode argument_description_list_order
A value that indicates the order of the arguments in the list of argument descriptions.
Definition: usage_writer.h:222
const char * usage_prefix_color
The color applied by the base implementation of the write_usage_syntax_prefix method.
Definition: usage_writer.h:306
virtual void write_argument_syntax(const argument_type &arg)
Writes the string used to indicate there are more arguments if the usage syntax was abbreviated.
Definition: usage_writer.h:539
string_type name_separator
The separator to use between names of arguments and commands.
Definition: usage_writer.h:277
bool use_white_space_value_separator
Indicates whether to use white space as the argument name separator in the usage syntax.
Definition: usage_writer.h:232
virtual void write_multi_value_suffix()
Writes a suffix that indicates an argument is a multi-value argument.
Definition: usage_writer.h:650
bool use_short_names_for_syntax
When using parsing_mode::long_short, use short names in the usage syntax.
Definition: usage_writer.h:267
virtual void write_optional_argument_syntax(const argument_type &arg)
Writes the string used to indicate there are more arguments if the usage syntax was abbreviated.
Definition: usage_writer.h:525
std::basic_string< CharType, Traits, Alloc > string_type
The concrete string type used.
Definition: usage_writer.h:122
const char * color_reset
The sequence used to reset color applied a usage help element.
Definition: usage_writer.h:362
virtual void write_argument_name(string_view_type name, string_view_type prefix)
Writes the name of an argument.
Definition: usage_writer.h:603
bool use_color() const
Gets a value that indicates whether color virtual terminal sequences can be used in the output.
Definition: usage_writer.h:1185
int command_description_indent
The level of indentation to use when writing the command descriptions.
Definition: usage_writer.h:284
bool include_default_value_in_description
Indicates whether to include the default value of arguments in the description.
Definition: usage_writer.h:242
virtual void write_parser_usage_core(usage_help_request request)
Creates the usage help for a basic_command_line_parser instance.
Definition: usage_writer.h:414
const char * command_description_color
The color applied by the base implementation of the write_command_description_header() method.
Definition: usage_writer.h:338
size_t syntax_indent
The level of indentation to use when writing the usage syntax.
Definition: usage_writer.h:203
const parser_type & parser() const
Gets the basic_command_line_parser that usage is being written for.
Definition: usage_writer.h:1167
virtual void write_application_description(string_view_type description)
Writes the application description, or command description in case of a subcommand.
Definition: usage_writer.h:445
size_t application_description_indent
The level of indentation to use when writing the application description.
Definition: usage_writer.h:196
bool blank_line_after_command_description
Indicates whether to add a blank line after each command's description.
Definition: usage_writer.h:289
const char * argument_description_color
The color applied by the base implementation of the write_argument_description_header() method.
Definition: usage_writer.h:322
void set_color(const char *color)
Writes the specified color virtual terminal sequence, if color is enabled.
Definition: usage_writer.h:1192
basic_usage_writer(stream_type &output, bool use_color=false)
Initializes a new instance of the basic_usage_writer class with the specified stream.
Definition: usage_writer.h:160
Provides information about a subcommand.
Definition: subcommand.h:143
Abstract base class for regular and multi-value arguments.
Definition: command_line_argument.h:108
bool has_long_name() const noexcept
Gets a value that indicates whether the argument has a long name.
Definition: command_line_argument.h:160
CharType short_name() const noexcept
Gets the short name of the argument, or a NULL character if it doesn't have one.
Definition: command_line_argument.h:144
virtual bool is_multi_value() const noexcept
Gets a value that indicates whether the argument can be provided more than once, collecting all the s...
Definition: command_line_argument.h:305
virtual bool is_switch() const noexcept=0
Gets a value that indicates whether the argument is a switch, which means it can be supplied without ...
const string_type & value_description() const noexcept
Gets the value description for the argument.
Definition: command_line_argument.h:227
std::optional< size_t > position() const noexcept
Gets the position of the argument.
Definition: command_line_argument.h:254
const string_type & name() const noexcept
Gets the name of the argument.
Definition: command_line_argument.h:133
bool has_short_name() const noexcept
Gets a value that indicates whether the argument has a short name.
Definition: command_line_argument.h:152
static virtual_terminal_support enable_color(standard_stream stream)
Enables color support using virtual terminal sequences for the console attached to the specified stre...
Definition: vt_helper.h:337
Provides an output stream buffer, and associated stream, that allow for white-space wrapping text at ...
constexpr const char * default_format
Resets the text format to the settings before modification.
Definition: vt_helper.h:106
constexpr const char * foreground_cyan
Sets the foreground color to cyan.
Definition: vt_helper.h:145
constexpr const char * foreground_red
Sets the foreground color to red.
Definition: vt_helper.h:130
constexpr const char * foreground_green
Sets the foreground color to green.
Definition: vt_helper.h:133
Namespace containing the core Ookii.CommandLine.Cpp types.
Definition: command_line_argument.h:16
@ output
The standard output stream.
@ error
The standard error stream.
description_list_filter_mode
Indicates which arguments should be included in the description list when printing usage.
Definition: usage_writer.h:39
@ none
Omit the description list entirely.
@ all
Include all arguments.
@ information
Include arguments that have any information that is not included in the syntax, such as aliases,...
@ descripion
Include only arguments that have a description.
usage_help_request
Indicates if and how usage is shown if an error occurred parsing the command line.
Definition: usage_writer.h:26
@ none
No usage help is shown. Instead, the basic_usage_writer::write_more_info_message() message is shown.
@ syntax_only
Only the usage syntax is shown; the argument descriptions are not. In addition, the basic_usage_write...
@ full
Full usage help is shown, including the argument descriptions.
basic_command< char > command
Typedef for basic_command using char as the character type.
Definition: subcommand.h:94
std::basic_ostream< CharType, Traits > & reset_indent(std::basic_ostream< CharType, Traits > &stream)
IO manipulator that lets the next line start at the beginning of the line, without indenting it.
Definition: line_wrapping_stream.h:680
@ long_short
Use POSIX-like rules where arguments have separate long and short names.
details::set_indent_helper set_indent(size_t indent)
IO manipulator that changes the number of spaces that each line is indented with for a line wrapping ...
Definition: line_wrapping_stream.h:658
description_list_sort_mode
Indicates how the arguments in the description list should be sorted.
Definition: usage_writer.h:53
@ alphabetical_short_name
The descriptions are listed in alphabetical order by the short argument name. If the argument has no ...
@ alphabetical_descending
The same as alphabetical, but in reverse order.
@ alphabetical_short_name_descending
The same as alphabetical_short_name, but in reverse order.
@ usage_order
The descriptions are listed in the same order as the usage syntax: first the positional arguments,...
@ alphabetical
The descriptions are listed in alphabetical order by argument name. If the parsing mode is parsing_mo...
@ error
There was an error converting the value to the element type of the argument.
Provides RAII types.
Provides helper types and functions for working with strings.
Provides default values for the fields of basic_usage_writer.
Definition: usage_writer.h:108
static constexpr size_t argument_description_indent
Default value for basic_usage_writer::argument_description_indent.
Definition: usage_writer.h:116
static constexpr size_t application_description_indent
Default value for basic_usage_writer::application_description_indent.
Definition: usage_writer.h:112
static constexpr auto name_separator
Default value for basic_usage_writer::name_separator.
Definition: usage_writer.h:110
static constexpr size_t syntax_indent
Default value for basic_usage_writer::syntax_indent.
Definition: usage_writer.h:114
static constexpr size_t command_description_indent
Default value for basic_usage_writer::command_description_indent.
Definition: usage_writer.h:118
Template used to specify the default value description for a type.
Definition: value_description.h:30