Skip to content

Commit 1284f2d

Browse files
committed
add an alias section to the help for subcommands
1 parent 28b35af commit 1284f2d

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

include/CLI/App.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,21 @@ class App {
18211821
}
18221822

18231823
/// Get a display name for an app
1824-
std::string get_display_name() const { return (!name_.empty()) ? name_ : "[Option Group: " + get_group() + "]"; }
1824+
std::string get_display_name(bool with_aliases = false) const {
1825+
if(name_.empty()) {
1826+
return std::string("[Option Group: ") + get_group() + "]";
1827+
}
1828+
if(aliases_.empty() || !with_aliases || aliases_.empty()) {
1829+
return name_;
1830+
}
1831+
std::string dispname = name_;
1832+
for(const auto &lalias : aliases_) {
1833+
dispname.push_back(',');
1834+
dispname.push_back(' ');
1835+
dispname.append(lalias);
1836+
}
1837+
return dispname;
1838+
}
18251839

18261840
/// Check the name, case insensitive and underscore insensitive if set
18271841
bool check_name(std::string name_to_check) const {

include/CLI/Formatter.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,15 +205,18 @@ inline std::string Formatter::make_subcommands(const App *app, AppFormatMode mod
205205

206206
inline std::string Formatter::make_subcommand(const App *sub) const {
207207
std::stringstream out;
208-
detail::format_help(out, sub->get_name(), sub->get_description(), column_width_);
208+
detail::format_help(out, sub->get_display_name(true), sub->get_description(), column_width_);
209209
return out.str();
210210
}
211211

212212
inline std::string Formatter::make_expanded(const App *sub) const {
213213
std::stringstream out;
214-
out << sub->get_display_name() << "\n";
214+
out << sub->get_display_name(true) << "\n";
215215

216216
out << make_description(sub);
217+
if(sub->get_name().empty() && !sub->get_aliases().empty()) {
218+
detail::format_aliases(out, sub->get_aliases(), column_width_ + 2);
219+
}
217220
out << make_positionals(sub);
218221
out << make_groups(sub, AppFormatMode::Sub);
219222
out << make_subcommands(sub, AppFormatMode::Sub);

include/CLI/StringTools.hpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ inline std::string trim_copy(const std::string &str, const std::string &filter)
159159
return trim(s, filter);
160160
}
161161
/// Print a two part "help" string
162-
inline std::ostream &format_help(std::ostream &out, std::string name, std::string description, std::size_t wid) {
162+
inline std::ostream &format_help(std::ostream &out, std::string name, const std::string &description, std::size_t wid) {
163163
name = " " + name;
164164
out << std::setw(static_cast<int>(wid)) << std::left << name;
165165
if(!description.empty()) {
@@ -176,6 +176,24 @@ inline std::ostream &format_help(std::ostream &out, std::string name, std::strin
176176
return out;
177177
}
178178

179+
/// Print subcommand aliases
180+
inline std::ostream &format_aliases(std::ostream &out, const std::vector<std::string> &aliases, std::size_t wid) {
181+
if(!aliases.empty()) {
182+
out << std::setw(static_cast<int>(wid)) << " aliases: ";
183+
bool front = true;
184+
for(const auto &alias : aliases) {
185+
if(!front) {
186+
out << ", ";
187+
} else {
188+
front = false;
189+
}
190+
out << alias;
191+
}
192+
out << "\n";
193+
}
194+
return out;
195+
}
196+
179197
/// Verify the first character of an option
180198
template <typename T> bool valid_first_char(T c) {
181199
return std::isalnum(c, std::locale()) || c == '_' || c == '?' || c == '@';

tests/HelpTest.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,36 @@ TEST(THelp, Subcom) {
467467
EXPECT_THAT(help, HasSubstr("Usage: ./myprogram sub2"));
468468
}
469469

470+
TEST(THelp, Subcom_alias) {
471+
CLI::App app{"My prog"};
472+
473+
auto sub1 = app.add_subcommand("sub1", "Subcommand1 description test");
474+
sub1->alias("sub_alias1");
475+
sub1->alias("sub_alias2");
476+
477+
app.add_subcommand("sub2", "Subcommand2 description test");
478+
479+
std::string help = app.help();
480+
EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] [SUBCOMMAND]"));
481+
EXPECT_THAT(help, HasSubstr("sub_alias1"));
482+
EXPECT_THAT(help, HasSubstr("sub_alias2"));
483+
}
484+
485+
TEST(THelp, Subcom_alias_group) {
486+
CLI::App app{"My prog"};
487+
488+
auto sub1 = app.add_subcommand("", "Subcommand1 description test");
489+
sub1->alias("sub_alias1");
490+
sub1->alias("sub_alias2");
491+
492+
app.add_subcommand("sub2", "Subcommand2 description test");
493+
494+
std::string help = app.help();
495+
EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] [SUBCOMMAND]"));
496+
EXPECT_THAT(help, HasSubstr("sub_alias1"));
497+
EXPECT_THAT(help, HasSubstr("sub_alias2"));
498+
}
499+
470500
TEST(THelp, MasterName) {
471501
CLI::App app{"My prog", "MyRealName"};
472502

0 commit comments

Comments
 (0)