aboutsummaryrefslogtreecommitdiff
path: root/src/zen/zen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zen/zen.cpp')
-rw-r--r--src/zen/zen.cpp68
1 files changed, 45 insertions, 23 deletions
diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp
index 984e8589b..02695419e 100644
--- a/src/zen/zen.cpp
+++ b/src/zen/zen.cpp
@@ -21,13 +21,13 @@
#include "cmds/service_cmd.h"
#include "cmds/status_cmd.h"
#include "cmds/top_cmd.h"
-#include "cmds/trace_cmd.h"
#include "cmds/ui_cmd.h"
#include "cmds/up_cmd.h"
#include "cmds/version_cmd.h"
#include "cmds/vfs_cmd.h"
#include "cmds/wipe_cmd.h"
#include "cmds/workspaces_cmd.h"
+#include "trace/trace_cmd.h"
#include <zencore/callstack.h>
#include <zencore/config.h>
@@ -270,20 +270,34 @@ ZenCmdWithSubCommands::PrintHelp()
Options().set_width(TuiConsoleColumns(80));
printf("%s\n", Options().help(Groups).c_str());
- // Append subcommand listing.
+ // Append subcommand listing. When a subcommand has aliases, display them as
+ // "name|alias1|alias2" in the left column so callers discover the alternate spellings.
+ auto FormatSubCmdName = [](ZenSubCmdBase& SubCmd) {
+ std::string Name(SubCmd.SubOptions().program());
+ for (const std::string& Alias : SubCmd.Aliases())
+ {
+ Name.push_back('|');
+ Name.append(Alias);
+ }
+ return Name;
+ };
+
+ std::vector<std::string> FormattedNames;
+ FormattedNames.reserve(m_SubCommands.size());
size_t MaxNameLen = 0;
for (ZenSubCmdBase* SubCmd : m_SubCommands)
{
- MaxNameLen = std::max(MaxNameLen, SubCmd->SubOptions().program().size());
+ FormattedNames.push_back(FormatSubCmdName(*SubCmd));
+ MaxNameLen = std::max(MaxNameLen, FormattedNames.back().size());
}
printf("subcommands:\n");
- for (ZenSubCmdBase* SubCmd : m_SubCommands)
+ for (size_t i = 0; i < m_SubCommands.size(); ++i)
{
printf(" %-*s %s\n",
static_cast<int>(MaxNameLen),
- SubCmd->SubOptions().program().c_str(),
- std::string(SubCmd->Description()).c_str());
+ FormattedNames[i].c_str(),
+ std::string(m_SubCommands[i]->Description()).c_str());
}
printf("\nFor global options run: zen --help\n");
}
@@ -308,16 +322,33 @@ ZenCmdWithSubCommands::PrintSubCommandHelp(cxxopts::Options& SubCmdOptions)
void
ZenCmdWithSubCommands::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
- std::vector<cxxopts::Options*> SubOptionPtrs;
- SubOptionPtrs.reserve(m_SubCommands.size());
- for (ZenSubCmdBase* SubCmd : m_SubCommands)
- {
- SubOptionPtrs.push_back(&SubCmd->SubOptions());
- }
-
+ ZenSubCmdBase* MatchedSubCmd = nullptr;
cxxopts::Options* MatchedSubOption = nullptr;
std::vector<char*> SubCommandArguments;
- int ParentArgc = GetSubCommand(Options(), argc, argv, SubOptionPtrs, MatchedSubOption, SubCommandArguments);
+ int ParentArgc = argc;
+ for (int i = 1; i < argc; ++i)
+ {
+ std::string_view Arg(argv[i]);
+ for (ZenSubCmdBase* SubCmd : m_SubCommands)
+ {
+ const bool NameMatch = SubCmd->SubOptions().program() == Arg;
+ const bool AliasMatch =
+ !NameMatch && std::find(SubCmd->Aliases().begin(), SubCmd->Aliases().end(), Arg) != SubCmd->Aliases().end();
+ if (NameMatch || AliasMatch)
+ {
+ MatchedSubCmd = SubCmd;
+ MatchedSubOption = &SubCmd->SubOptions();
+ break;
+ }
+ }
+ if (MatchedSubCmd != nullptr)
+ {
+ SubCommandArguments.push_back(argv[0]);
+ std::copy(&argv[i + 1], &argv[argc], std::back_inserter(SubCommandArguments));
+ ParentArgc = i + 1;
+ break;
+ }
+ }
// Intercept --help/-h in the parent arg range before calling ParseOptions so
// we can append subcommand information to the output. When a subcommand was
@@ -344,15 +375,6 @@ ZenCmdWithSubCommands::Run(const ZenCliOptions& GlobalOptions, int argc, char**
throw OptionParseException("No subcommand specified", {});
}
- ZenSubCmdBase* MatchedSubCmd = nullptr;
- for (ZenSubCmdBase* SubCmd : m_SubCommands)
- {
- if (&SubCmd->SubOptions() == MatchedSubOption)
- {
- MatchedSubCmd = SubCmd;
- break;
- }
- }
ZEN_ASSERT(MatchedSubCmd != nullptr);
// Intercept --help/-h in the subcommand args so we can show combined help