diff options
| -rw-r--r-- | args.hxx | 44 | ||||
| -rw-r--r-- | test.cxx | 72 | 
2 files changed, 110 insertions, 6 deletions
| @@ -571,6 +571,26 @@ namespace args          /** Use short flags in program lines when possible           */          bool proglinePreferShortFlags = false; + +        /** Program line prefix +         */ +        std::string usageString; + +        /** String shown in help before flags descriptions +         */ +        std::string optionsString = "OPTIONS:"; + +        /** Display value name after all the long and short flags +         */ +        bool useValueNameOnce = false; + +        /** Show value name +         */ +        bool showValueName = true; + +        /** Add newline before flag description +         */ +        bool addNewlineBeforeDescription = false;      };      /** Base class for all match types @@ -832,9 +852,11 @@ namespace args              virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams ¶ms, const unsigned indentLevel) const override              {                  std::tuple<std::string, std::string, unsigned> description; -                const std::string postfix = NumberOfArguments() == 0 ? std::string() : Name(); +                const std::string postfix = !params.showValueName || NumberOfArguments() == 0 ? std::string() : Name();                  std::string flags; -                for (const auto &flag : matcher.GetFlagStrings()) +                const auto flagStrings = matcher.GetFlagStrings(); +                const bool useValueNameOnce = flagStrings.size() == 1 ? false : params.useValueNameOnce; +                for (const auto &flag : flagStrings)                  {                      if (!flags.empty())                      { @@ -843,12 +865,18 @@ namespace args                      flags += flag.isShort ? params.shortPrefix : params.longPrefix;                      flags += flag.str(); -                    if (!postfix.empty()) +                    if (!postfix.empty() && !useValueNameOnce)                      {                          flags += flag.isShort ? params.shortSeparator : params.longSeparator;                          flags += "[" + postfix + "]";                      }                  } + +                if (!postfix.empty() && useValueNameOnce) +                { +                    flags += " [" + postfix + "]"; +                } +                  std::get<0>(description) = std::move(flags);                  std::get<1>(description) = help;                  std::get<2>(description) = indentLevel; @@ -2236,7 +2264,7 @@ namespace args                  const bool hasarguments = command.HasPositional();                  std::ostringstream prognameline; -                prognameline << Prog(); +                prognameline << helpParams.usageString << Prog();                  for (const std::string &posname: command.GetProgramLine(helpParams))                  { @@ -2268,7 +2296,11 @@ namespace args                  bool lastDescriptionIsNewline = false; -                help_ << std::string(helpParams.progindent, ' ') << "OPTIONS:\n\n"; +                if (!helpParams.optionsString.empty()) +                { +                    help_ << std::string(helpParams.progindent, ' ') << helpParams.optionsString << "\n\n"; +                } +                  for (const auto &desc: command.GetDescription(helpParams, 0))                  {                      lastDescriptionIsNewline = std::get<0>(desc).empty() && std::get<1>(desc).empty(); @@ -2289,7 +2321,7 @@ namespace args                      auto infoit = std::begin(info);                      // groupindent is on both sides of this inequality, and therefore can be removed -                    if ((helpParams.flagindent + flagssize + helpParams.gutter) > helpParams.helpindent || infoit == std::end(info)) +                    if ((helpParams.flagindent + flagssize + helpParams.gutter) > helpParams.helpindent || infoit == std::end(info) || helpParams.addNewlineBeforeDescription)                      {                          help_ << '\n';                      } else @@ -964,6 +964,78 @@ TEST_CASE("Matcher validation works as expected", "[args]")      REQUIRE_THROWS_AS(args::ValueFlag<int>(parser, "", "", {}), args::UsageError);  } +TEST_CASE("HelpParams work as expected", "[args]") +{ +    args::ArgumentParser p("parser"); +    args::ValueFlag<std::string> f(p, "name", "description", {'f', "foo"}); +    args::ValueFlag<std::string> g(p, "name", "description", {'g'}); +    p.Prog("prog"); + +    REQUIRE(p.Help() == R"(  prog {OPTIONS} + +    parser + +  OPTIONS: + +      -f[name], --foo=[name]            description +      -g[name]                          description + +)"); + +    p.helpParams.usageString = "usage: "; +    p.helpParams.optionsString = "Options"; +    p.helpParams.useValueNameOnce = true; +    REQUIRE(p.Help() == R"(  usage: prog {OPTIONS} + +    parser + +  Options + +      -f, --foo [name]                  description +      -g[name]                          description + +)"); + +    p.helpParams.showValueName = false; +    p.helpParams.optionsString = {}; +    REQUIRE(p.Help() == R"(  usage: prog {OPTIONS} + +    parser + +      -f, --foo                         description +      -g                                description + +)"); + +    p.helpParams.helpindent = 12; +    p.helpParams.optionsString = "Options"; +    REQUIRE(p.Help() == R"(  usage: prog {OPTIONS} + +    parser + +  Options + +      -f, --foo +            description +      -g    description + +)"); + +    p.helpParams.addNewlineBeforeDescription = true; +    REQUIRE(p.Help() == R"(  usage: prog {OPTIONS} + +    parser + +  Options + +      -f, --foo +            description +      -g +            description + +)"); +} +  #undef ARGS_HXX  #define ARGS_TESTNAMESPACE  #define ARGS_NOEXCEPT | 
