Move command listing to 'gmx help commands'
authorTeemu Murtola <teemu.murtola@gmail.com>
Sat, 25 Jan 2014 18:07:47 +0000 (20:07 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Thu, 30 Jan 2014 04:25:52 +0000 (05:25 +0100)
Instead of printing the list of commands on 'gmx' or 'gmx help', print
it only when explicitly requested with 'gmx help commands'.  This makes
it easier to see the help about the common command line options that
'gmx' accepts.  The list of available help topics lists the 'commands'
topic, so it should be easy to find.

Related to #685.

Change-Id: I00e9ceae15ebd47d2ac129aae8e6e407f86c388a

src/gromacs/commandline/cmdlinehelpmodule.cpp

index 87f3ca9a076e4d2f0b3c26fdd4e988bbed01bf4f..b6ebcb4206c0af31b33ed8a30933c4002114434b 100644 (file)
@@ -133,12 +133,9 @@ class RootHelpTopic : public CompositeHelpTopic<RootHelpText>
         /*! \brief
          * Creates a root help topic.
          *
-         * \param[in] modules  List of modules for to use for module listings.
-         *
          * Does not throw.
          */
-        explicit RootHelpTopic(const CommandLineModuleMap &modules)
-            : modules_(modules), commonOptions_(NULL)
+        RootHelpTopic() : commonOptions_(NULL)
         {
         }
 
@@ -151,9 +148,6 @@ class RootHelpTopic : public CompositeHelpTopic<RootHelpText>
         virtual void writeHelp(const HelpWriterContext &context) const;
 
     private:
-        void printModuleList(const HelpWriterContext &context) const;
-
-        const CommandLineModuleMap &modules_;
         const Options              *commonOptions_;
 
         GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic);
@@ -176,30 +170,66 @@ void RootHelpTopic::writeHelp(const HelpWriterContext &context) const
         CommandLineHelpWriter(*commonOptions_)
             .writeHelp(cmdlineContext);
     }
-    // TODO: If/when this list becomes long, it may be better to only print
-    // "common" commands here, and have a separate topic (e.g.,
-    // "help commands") that prints the full list.
-    printModuleList(context);
-    context.writeTextBlock(
-            "For additional help on a command, use '[PROGRAM] help <command>'");
+    // TODO: Consider printing a list of "core" commands. Would require someone
+    // to determine such a set...
     writeSubTopicList(context,
-                      "\nAdditional help is available on the following topics:");
+                      "Additional help is available on the following topics:");
     context.writeTextBlock(
-            "To access the help, use '[PROGRAM] help <topic>'.");
+            "To access the help, use '[PROGRAM] help <topic>'.[BR]"
+            "For help on a command, use '[PROGRAM] help <command>'.");
 }
 
-void RootHelpTopic::printModuleList(const HelpWriterContext &context) const
+/********************************************************************
+ * CommandsHelpTopic
+ */
+
+/*! \brief
+ * Help topic for listing the commands.
+ *
+ * \ingroup module_commandline
+ */
+class CommandsHelpTopic : public HelpTopicInterface
+{
+    public:
+        /*! \brief
+         * Creates a command list help topic.
+         *
+         * \param[in]     helpModule Help module to get module information from.
+         *
+         * Does not throw.
+         */
+        explicit CommandsHelpTopic(const CommandLineHelpModuleImpl &helpModule)
+            : helpModule_(helpModule)
+        {
+        }
+
+        virtual const char *name() const { return "commands"; }
+        virtual const char *title() const { return "List of available commands"; }
+        virtual bool hasSubTopics() const { return false; }
+        virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
+        {
+            return NULL;
+        }
+
+        virtual void writeHelp(const HelpWriterContext &context) const;
+
+    private:
+        const CommandLineHelpModuleImpl &helpModule_;
+
+        GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic);
+};
+
+void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const
 {
     if (context.outputFormat() != eHelpOutputFormat_Console)
     {
-        // TODO: Implement once the situation with Redmine issue #969 is more
-        // clear.
         GMX_THROW(NotImplementedError(
                           "Module list is not implemented for this output format"));
     }
     int maxNameLength = 0;
-    CommandLineModuleMap::const_iterator module;
-    for (module = modules_.begin(); module != modules_.end(); ++module)
+    const CommandLineModuleMap           &modules = helpModule_.modules_;
+    CommandLineModuleMap::const_iterator  module;
+    for (module = modules.begin(); module != modules.end(); ++module)
     {
         int nameLength = static_cast<int>(module->first.length());
         if (module->second->shortDescription() != NULL
@@ -208,14 +238,15 @@ void RootHelpTopic::printModuleList(const HelpWriterContext &context) const
             maxNameLength = nameLength;
         }
     }
+    context.writeTextBlock(
+            "Usage: [PROGRAM] [<options>] <command> [<args>][PAR]"
+            "Available commands:");
     File              &file = context.outputFile();
     TextTableFormatter formatter;
     formatter.addColumn(NULL, maxNameLength + 1, false);
     formatter.addColumn(NULL, 72 - maxNameLength, true);
     formatter.setFirstColumnIndent(4);
-    file.writeLine();
-    file.writeLine("Available commands:");
-    for (module = modules_.begin(); module != modules_.end(); ++module)
+    for (module = modules.begin(); module != modules.end(); ++module)
     {
         const char *name        = module->first.c_str();
         const char *description = module->second->shortDescription();
@@ -227,6 +258,8 @@ void RootHelpTopic::printModuleList(const HelpWriterContext &context) const
             file.writeString(formatter.formatRow());
         }
     }
+    context.writeTextBlock(
+            "For help on a command, use '[PROGRAM] help <command>'.");
 }
 
 /********************************************************************
@@ -688,7 +721,7 @@ CommandLineHelpModuleImpl::CommandLineHelpModuleImpl(
         const std::string                &binaryName,
         const CommandLineModuleMap       &modules,
         const CommandLineModuleGroupList &groups)
-    : rootTopic_(new RootHelpTopic(modules)), programInfo_(programInfo),
+    : rootTopic_(new RootHelpTopic), programInfo_(programInfo),
       binaryName_(binaryName), modules_(modules), groups_(groups),
       context_(NULL), moduleOverride_(NULL), bHidden_(false)
 {
@@ -770,6 +803,9 @@ void CommandLineHelpModule::setModuleOverride(
 
 int CommandLineHelpModule::run(int argc, char *argv[])
 {
+    // Add internal topics lazily here.
+    addTopic(HelpTopicPointer(new CommandsHelpTopic(*impl_)));
+
     const char *const exportFormats[] = { "man", "html", "completion" };
     std::string       exportFormat;
     Options           options(NULL, NULL);