Change the virsh help out. The new output of "virsh help" and
"virsh --help" will be like:

 Secret (help keyword 'secret'):
    secret-define                  define or modify a secret from an XML file
    secret-dumpxml                 secret attributes in XML
    secret-set-value               set a secret value
    secret-get-value               Output a secret value
    secret-undefine                undefine a secret
    secret-list                    list secrets

 Snapshot (help keyword 'snapshot'):
    snapshot-create                Create a snapshot
    snapshot-current               Get the current snapshot
    snapshot-delete                Delete a domain snapshot
    snapshot-dumpxml               Dump XML for a domain snapshot
    snapshot-list                  List snapshots for a domain
    snapshot-revert                Revert a domain to a snapshot

Also support output help information of specified command group, e.g.

% ./tools/virsh help "Network Filter"
 Network Filter (help keyword filter):
    nwfilter-define                define or update a network filter from an 
XML file
    nwfilter-undefine              undefine a network filter
    nwfilter-dumpxml               network filter information in XML
    nwfilter-list                  list network filters
    nwfilter-edit                  edit XML configuration for a network filter

Each group has a help keyword, e.g.

% ./tools/virsh help filter
 Network Filter (help keyword filter):
    nwfilter-define                define or update a network filter from an 
XML file
    nwfilter-undefine              undefine a network filter
    nwfilter-dumpxml               network filter information in XML
    nwfilter-list                  list network filters
    nwfilter-edit                  edit XML configuration for a network filter

* tools/virsh.c:
  - introduce new struct "vshCmdGrp" and macros to define the groups.
  - split previous array "commands" into small arrays which are orgnized
    by group
  - changed some functions, such as "vshCmdDefSearch"
  - commands of each group are in "alphabetical order" now.
  - the commands are categorized with reference of
    http://wiki.libvirt.org/page/VirshHelpV2 (by Justin)
  - the modifications doesn't affect tests

* TODO:
  - doc

---
 tools/virsh.c |  414 ++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 281 insertions(+), 133 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index ae88cc0..123f2d7 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -131,6 +131,22 @@ typedef enum {
 } vshCmdOptType;

 /*
+ * Command group types
+ */
+#define VSH_CMD_GRP_DOM_MANAGEMENT   "Domain Management"
+#define VSH_CMD_GRP_DOM_MONITORING   "Domain Monitoring"
+#define VSH_CMD_GRP_STORAGE_POOL     "Storage Pool"
+#define VSH_CMD_GRP_STORAGE_VOL      "Storage Volume"
+#define VSH_CMD_GRP_NETWORK          "Networking"
+#define VSH_CMD_GRP_NODEDEV          "Node Device"
+#define VSH_CMD_GRP_IFACE            "Interface"
+#define VSH_CMD_GRP_NWFILTER         "Network Filter"
+#define VSH_CMD_GRP_SECRET           "Secret"
+#define VSH_CMD_GRP_SNAPSHOT         "Snapshot"
+#define VSH_CMD_GRP_HOST_AND_HV      "Host and Hypervisor"
+#define VSH_CMD_GRP_VIRSH            "Virsh Itself"
+
+/*
  * Command Option Flags
  */
 #define VSH_OFLAG_NONE    0     /* without flags */
@@ -207,8 +223,13 @@ typedef struct __vshControl {
     char *historyfile;          /* readline history file name */
 } __vshControl;

+typedef struct vshCmdGrp {
+    const char *name;
+    const char *keyword; /* help keyword */
+    const vshCmdDef *commands;
+} vshCmdGrp;

-static const vshCmdDef commands[];
+static const vshCmdGrp cmdGroups[];

 static void vshError(vshControl *ctl, const char *format, ...)
     ATTRIBUTE_FMT_PRINTF(2, 3);
@@ -224,6 +245,8 @@ static int vshParseArgv(vshControl *ctl, int argc, char 
**argv);
 static const char *vshCmddefGetInfo(const vshCmdDef *cmd, const char *info);
 static const vshCmdDef *vshCmddefSearch(const char *cmdname);
 static int vshCmddefHelp(vshControl *ctl, const char *name);
+static const vshCmdGrp *vshCmdGrpSearch(const char *grpname);
+static int vshCmdGrpHelp(vshControl *ctl, const char *name);

 static vshCmdOpt *vshCommandOpt(const vshCmd *cmd, const char *name);
 static int vshCommandOptInt(const vshCmd *cmd, const char *name, int *found);
@@ -551,19 +574,39 @@ static const vshCmdOptDef opts_help[] = {

 static int
 cmdHelp(vshControl *ctl, const vshCmd *cmd)
-{
-    const char *cmdname = vshCommandOptString(cmd, "command", NULL);
+ {
+    const vshCmdDef *c;
+    const vshCmdGrp *g;
+    const char *name = vshCommandOptString(cmd, "command", NULL);

-    if (!cmdname) {
+    if (!name) {
+        const vshCmdGrp *grp;
         const vshCmdDef *def;

-        vshPrint(ctl, "%s", _("Commands:\n\n"));
-        for (def = commands; def->name; def++)
-            vshPrint(ctl, "    %-15s %s\n", def->name,
-                     _(vshCmddefGetInfo(def, "help")));
-        return TRUE;
+        vshPrint(ctl, "%s", _("Grouped commands:\n\n"));
+
+        for (grp = cmdGroups; grp->name; grp++) {
+            vshPrint(ctl, _(" %s (help keyword '%s'):\n"), grp->name,
+                     grp->keyword);
+
+            for (def = grp->commands; def->name; def++)
+                vshPrint(ctl, "    %-30s %s\n", def->name,
+                         _(vshCmddefGetInfo(def, "help")));
+
+            vshPrint(ctl, "\n");
+        }
+
+         return TRUE;
+     }
+
+    if ((c = vshCmddefSearch(name))) {
+        return vshCmddefHelp(ctl, name);
+    } else if ((g = vshCmdGrpSearch(name))) {
+        return vshCmdGrpHelp(ctl, name);
+    } else {
+        vshError(ctl, _("command or command group '%s' doesn't exist"), name);
+        return FALSE;
     }
-    return vshCmddefHelp(ctl, cmdname);
 }

 /*
@@ -9878,60 +9921,117 @@ cleanup:
     return ret;
 }

-
-/*
- * Commands
- */
-static const vshCmdDef commands[] = {
-    {"help", cmdHelp, opts_help, info_help},
+static const vshCmdDef domManagementCmds[] = {
     {"attach-device", cmdAttachDevice, opts_attach_device, info_attach_device},
     {"attach-disk", cmdAttachDisk, opts_attach_disk, info_attach_disk},
     {"attach-interface", cmdAttachInterface, opts_attach_interface, 
info_attach_interface},
     {"autostart", cmdAutostart, opts_autostart, info_autostart},
-    {"capabilities", cmdCapabilities, NULL, info_capabilities},
-#ifndef WIN32
-    {"cd", cmdCd, opts_cd, info_cd},
-#endif
-    {"connect", cmdConnect, opts_connect, info_connect},
 #ifndef WIN32
     {"console", cmdConsole, opts_console, info_console},
 #endif
     {"cpu-baseline", cmdCPUBaseline, opts_cpu_baseline, info_cpu_baseline},
     {"cpu-compare", cmdCPUCompare, opts_cpu_compare, info_cpu_compare},
     {"create", cmdCreate, opts_create, info_create},
-    {"start", cmdStart, opts_start, info_start},
+    {"define", cmdDefine, opts_define, info_define},
     {"destroy", cmdDestroy, opts_destroy, info_destroy},
     {"detach-device", cmdDetachDevice, opts_detach_device, info_detach_device},
     {"detach-disk", cmdDetachDisk, opts_detach_disk, info_detach_disk},
     {"detach-interface", cmdDetachInterface, opts_detach_interface, 
info_detach_interface},
-    {"define", cmdDefine, opts_define, info_define},
     {"domid", cmdDomid, opts_domid, info_domid},
-    {"domuuid", cmdDomuuid, opts_domuuid, info_domuuid},
-    {"dominfo", cmdDominfo, opts_dominfo, info_dominfo},
-    {"domjobinfo", cmdDomjobinfo, opts_domjobinfo, info_domjobinfo},
     {"domjobabort", cmdDomjobabort, opts_domjobabort, info_domjobabort},
+    {"domjobinfo", cmdDomjobinfo, opts_domjobinfo, info_domjobinfo},
     {"domname", cmdDomname, opts_domname, info_domname},
-    {"domstate", cmdDomstate, opts_domstate, info_domstate},
-    {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat},
-    {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat},
-    {"dommemstat", cmdDomMemStat, opts_dommemstat, info_dommemstat},
-    {"domblkinfo", cmdDomblkinfo, opts_domblkinfo, info_domblkinfo},
+    {"domuuid", cmdDomuuid, opts_domuuid, info_domuuid},
     {"domxml-from-native", cmdDomXMLFromNative, opts_domxmlfromnative, 
info_domxmlfromnative},
     {"domxml-to-native", cmdDomXMLToNative, opts_domxmltonative, 
info_domxmltonative},
+    {"dump", cmdDump, opts_dump, info_dump},
     {"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
     {"echo", cmdEcho, opts_echo, info_echo},
     {"edit", cmdEdit, opts_edit, info_edit},
-    {"find-storage-pool-sources", cmdPoolDiscoverSources,
-     opts_find_storage_pool_sources, info_find_storage_pool_sources},
     {"find-storage-pool-sources-as", cmdPoolDiscoverSourcesAs,
      opts_find_storage_pool_sources_as, info_find_storage_pool_sources_as},
+    {"find-storage-pool-sources", cmdPoolDiscoverSources,
+     opts_find_storage_pool_sources, info_find_storage_pool_sources},
     {"freecell", cmdFreecell, opts_freecell, info_freecell},
     {"hostname", cmdHostname, NULL, info_hostname},
-    {"list", cmdList, opts_list, info_list},
+    {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave},
+    {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, 
info_managedsaveremove},
     {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus},
+    {"memtune", cmdMemtune, opts_memtune, info_memtune},
     {"migrate", cmdMigrate, opts_migrate, info_migrate},
     {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, 
opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime},
+    {"reboot", cmdReboot, opts_reboot, info_reboot},
+    {"restore", cmdRestore, opts_restore, info_restore},
+    {"resume", cmdResume, opts_resume, info_resume},
+    {"save", cmdSave, opts_save, info_save},
+    {"schedinfo", cmdSchedinfo, opts_schedinfo, info_schedinfo},
+    {"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem},
+    {"setmem", cmdSetmem, opts_setmem, info_setmem},
+    {"setvcpus", cmdSetvcpus, opts_setvcpus, info_setvcpus},
+    {"shutdown", cmdShutdown, opts_shutdown, info_shutdown},
+    {"start", cmdStart, opts_start, info_start},
+    {"suspend", cmdSuspend, opts_suspend, info_suspend},
+    {"ttyconsole", cmdTTYConsole, opts_ttyconsole, info_ttyconsole},
+    {"undefine", cmdUndefine, opts_undefine, info_undefine},
+    {"update-device", cmdUpdateDevice, opts_update_device, info_update_device},
+    {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount},
+    {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
+    {"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
+    {"version", cmdVersion, NULL, info_version},
+    {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay},
+    {NULL, NULL, NULL, NULL}
+};
+
+static const vshCmdDef domMonitoringCmds[] = {
+    {"domblkinfo", cmdDomblkinfo, opts_domblkinfo, info_domblkinfo},
+    {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat},
+    {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat},
+    {"dominfo", cmdDominfo, opts_dominfo, info_dominfo},
+    {"dommemstat", cmdDomMemStat, opts_dommemstat, info_dommemstat},
+    {"domstate", cmdDomstate, opts_domstate, info_domstate},
+    {"list", cmdList, opts_list, info_list},
+    {NULL, NULL, NULL, NULL}
+};
+
+static const vshCmdDef storagePoolCmds[] = {
+    {"pool-autostart", cmdPoolAutostart, opts_pool_autostart, 
info_pool_autostart},
+    {"pool-build", cmdPoolBuild, opts_pool_build, info_pool_build},
+    {"pool-create-as", cmdPoolCreateAs, opts_pool_X_as, info_pool_create_as},
+    {"pool-create", cmdPoolCreate, opts_pool_create, info_pool_create},
+    {"pool-define-as", cmdPoolDefineAs, opts_pool_X_as, info_pool_define_as},
+    {"pool-define", cmdPoolDefine, opts_pool_define, info_pool_define},
+    {"pool-delete", cmdPoolDelete, opts_pool_delete, info_pool_delete},
+    {"pool-destroy", cmdPoolDestroy, opts_pool_destroy, info_pool_destroy},
+    {"pool-dumpxml", cmdPoolDumpXML, opts_pool_dumpxml, info_pool_dumpxml},
+    {"pool-edit", cmdPoolEdit, opts_pool_edit, info_pool_edit},
+    {"pool-info", cmdPoolInfo, opts_pool_info, info_pool_info},
+    {"pool-list", cmdPoolList, opts_pool_list, info_pool_list},
+    {"pool-name", cmdPoolName, opts_pool_name, info_pool_name},
+    {"pool-refresh", cmdPoolRefresh, opts_pool_refresh, info_pool_refresh},
+    {"pool-start", cmdPoolStart, opts_pool_start, info_pool_start},
+    {"pool-undefine", cmdPoolUndefine, opts_pool_undefine, info_pool_undefine},
+    {"pool-uuid", cmdPoolUuid, opts_pool_uuid, info_pool_uuid},
+    {NULL, NULL, NULL, NULL}
+};
+
+static const vshCmdDef storageVolCmds[] = {
+    {"vol-clone", cmdVolClone, opts_vol_clone, info_vol_clone},
+    {"vol-create-as", cmdVolCreateAs, opts_vol_create_as, info_vol_create_as},
+    {"vol-create", cmdVolCreate, opts_vol_create, info_vol_create},
+    {"vol-create-from", cmdVolCreateFrom, opts_vol_create_from, 
info_vol_create_from},
+    {"vol-delete", cmdVolDelete, opts_vol_delete, info_vol_delete},
+    {"vol-dumpxml", cmdVolDumpXML, opts_vol_dumpxml, info_vol_dumpxml},
+    {"vol-info", cmdVolInfo, opts_vol_info, info_vol_info},
+    {"vol-key", cmdVolKey, opts_vol_key, info_vol_key},
+    {"vol-list", cmdVolList, opts_vol_list, info_vol_list},
+    {"vol-name", cmdVolName, opts_vol_name, info_vol_name},
+    {"vol-path", cmdVolPath, opts_vol_path, info_vol_path},
+    {"vol-pool", cmdVolPool, opts_vol_pool, info_vol_pool},
+    {"vol-wipe", cmdVolWipe, opts_vol_wipe, info_vol_wipe},
+    {NULL, NULL, NULL, NULL}
+};

+static const vshCmdDef networkCmds[] = {
     {"net-autostart", cmdNetworkAutostart, opts_network_autostart, 
info_network_autostart},
     {"net-create", cmdNetworkCreate, opts_network_create, info_network_create},
     {"net-define", cmdNetworkDefine, opts_network_define, info_network_define},
@@ -9944,116 +10044,104 @@ static const vshCmdDef commands[] = {
     {"net-start", cmdNetworkStart, opts_network_start, info_network_start},
     {"net-undefine", cmdNetworkUndefine, opts_network_undefine, 
info_network_undefine},
     {"net-uuid", cmdNetworkUuid, opts_network_uuid, info_network_uuid},
+    {NULL, NULL, NULL, NULL}
+};

-    {"iface-list", cmdInterfaceList, opts_interface_list, info_interface_list},
-    {"iface-name", cmdInterfaceName, opts_interface_name, info_interface_name},
-    {"iface-mac", cmdInterfaceMAC, opts_interface_mac, info_interface_mac},
-    {"iface-dumpxml", cmdInterfaceDumpXML, opts_interface_dumpxml, 
info_interface_dumpxml},
-    {"iface-define", cmdInterfaceDefine, opts_interface_define, 
info_interface_define},
-    {"iface-undefine", cmdInterfaceUndefine, opts_interface_undefine, 
info_interface_undefine},
-    {"iface-edit", cmdInterfaceEdit, opts_interface_edit, info_interface_edit},
-    {"iface-start", cmdInterfaceStart, opts_interface_start, 
info_interface_start},
-    {"iface-destroy", cmdInterfaceDestroy, opts_interface_destroy, 
info_interface_destroy},
-
-    {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave},
-    {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, 
info_managedsaveremove},
-
-    {"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo},
-
-    {"nodedev-list", cmdNodeListDevices, opts_node_list_devices, 
info_node_list_devices},
-    {"nodedev-dumpxml", cmdNodeDeviceDumpXML, opts_node_device_dumpxml, 
info_node_device_dumpxml},
+static const vshCmdDef nodedevCmds[] = {
+    {"nodedev-create", cmdNodeDeviceCreate, opts_node_device_create, 
info_node_device_create},
+    {"nodedev-destroy", cmdNodeDeviceDestroy, opts_node_device_destroy, 
info_node_device_destroy},
     {"nodedev-dettach", cmdNodeDeviceDettach, opts_node_device_dettach, 
info_node_device_dettach},
+    {"nodedev-dumpxml", cmdNodeDeviceDumpXML, opts_node_device_dumpxml, 
info_node_device_dumpxml},
+    {"nodedev-list", cmdNodeListDevices, opts_node_list_devices, 
info_node_list_devices},
     {"nodedev-reattach", cmdNodeDeviceReAttach, opts_node_device_reattach, 
info_node_device_reattach},
     {"nodedev-reset", cmdNodeDeviceReset, opts_node_device_reset, 
info_node_device_reset},
-    {"nodedev-create", cmdNodeDeviceCreate, opts_node_device_create, 
info_node_device_create},
-    {"nodedev-destroy", cmdNodeDeviceDestroy, opts_node_device_destroy, 
info_node_device_destroy},
+    {"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo},
+    {NULL, NULL, NULL, NULL}
+};
+
+static const vshCmdDef ifaceCmds[] = {
+    {"iface-define", cmdInterfaceDefine, opts_interface_define, 
info_interface_define},
+    {"iface-destroy", cmdInterfaceDestroy, opts_interface_destroy, 
info_interface_destroy},
+    {"iface-dumpxml", cmdInterfaceDumpXML, opts_interface_dumpxml, 
info_interface_dumpxml},
+    {"iface-edit", cmdInterfaceEdit, opts_interface_edit, info_interface_edit},
+    {"iface-list", cmdInterfaceList, opts_interface_list, info_interface_list},
+    {"iface-mac", cmdInterfaceMAC, opts_interface_mac, info_interface_mac},
+    {"iface-name", cmdInterfaceName, opts_interface_name, info_interface_name},
+    {"iface-start", cmdInterfaceStart, opts_interface_start, 
info_interface_start},
+    {"iface-undefine", cmdInterfaceUndefine, opts_interface_undefine, 
info_interface_undefine},
+    {NULL, NULL, NULL, NULL}
+};

+static const vshCmdDef nwfilterCmds[] = {
     {"nwfilter-define", cmdNWFilterDefine, opts_nwfilter_define, 
info_nwfilter_define},
-    {"nwfilter-undefine", cmdNWFilterUndefine, opts_nwfilter_undefine, 
info_nwfilter_undefine},
     {"nwfilter-dumpxml", cmdNWFilterDumpXML, opts_nwfilter_dumpxml, 
info_nwfilter_dumpxml},
-    {"nwfilter-list", cmdNWFilterList, opts_nwfilter_list, info_nwfilter_list},
     {"nwfilter-edit", cmdNWFilterEdit, opts_nwfilter_edit, info_nwfilter_edit},
+    {"nwfilter-list", cmdNWFilterList, opts_nwfilter_list, info_nwfilter_list},
+    {"nwfilter-undefine", cmdNWFilterUndefine, opts_nwfilter_undefine, 
info_nwfilter_undefine},
+    {NULL, NULL, NULL, NULL}
+};

-    {"pool-autostart", cmdPoolAutostart, opts_pool_autostart, 
info_pool_autostart},
-    {"pool-build", cmdPoolBuild, opts_pool_build, info_pool_build},
-    {"pool-create", cmdPoolCreate, opts_pool_create, info_pool_create},
-    {"pool-create-as", cmdPoolCreateAs, opts_pool_X_as, info_pool_create_as},
-    {"pool-define", cmdPoolDefine, opts_pool_define, info_pool_define},
-    {"pool-define-as", cmdPoolDefineAs, opts_pool_X_as, info_pool_define_as},
-    {"pool-destroy", cmdPoolDestroy, opts_pool_destroy, info_pool_destroy},
-    {"pool-delete", cmdPoolDelete, opts_pool_delete, info_pool_delete},
-    {"pool-dumpxml", cmdPoolDumpXML, opts_pool_dumpxml, info_pool_dumpxml},
-    {"pool-edit", cmdPoolEdit, opts_pool_edit, info_pool_edit},
-    {"pool-info", cmdPoolInfo, opts_pool_info, info_pool_info},
-    {"pool-list", cmdPoolList, opts_pool_list, info_pool_list},
-    {"pool-name", cmdPoolName, opts_pool_name, info_pool_name},
-    {"pool-refresh", cmdPoolRefresh, opts_pool_refresh, info_pool_refresh},
-    {"pool-start", cmdPoolStart, opts_pool_start, info_pool_start},
-    {"pool-undefine", cmdPoolUndefine, opts_pool_undefine, info_pool_undefine},
-    {"pool-uuid", cmdPoolUuid, opts_pool_uuid, info_pool_uuid},
-
+static const vshCmdDef secretCmds[] = {
     {"secret-define", cmdSecretDefine, opts_secret_define, info_secret_define},
     {"secret-dumpxml", cmdSecretDumpXML, opts_secret_dumpxml, 
info_secret_dumpxml},
-    {"secret-set-value", cmdSecretSetValue, opts_secret_set_value, 
info_secret_set_value},
     {"secret-get-value", cmdSecretGetValue, opts_secret_get_value, 
info_secret_get_value},
-    {"secret-undefine", cmdSecretUndefine, opts_secret_undefine, 
info_secret_undefine},
     {"secret-list", cmdSecretList, NULL, info_secret_list},
+    {"secret-set-value", cmdSecretSetValue, opts_secret_set_value, 
info_secret_set_value},
+    {"secret-undefine", cmdSecretUndefine, opts_secret_undefine, 
info_secret_undefine},
+    {NULL, NULL, NULL, NULL}
+};

-
+static const vshCmdDef virshCmds[] = {
+#ifndef WIN32
+    {"cd", cmdCd, opts_cd, info_cd},
+#endif
+    {"echo", cmdEcho, opts_echo, info_echo},
+    {"exit", cmdQuit, NULL, info_quit},
+    {"help", cmdHelp, opts_help, info_help},
 #ifndef WIN32
     {"pwd", cmdPwd, NULL, info_pwd},
 #endif
     {"quit", cmdQuit, NULL, info_quit},
-    {"exit", cmdQuit, NULL, info_quit},
-    {"reboot", cmdReboot, opts_reboot, info_reboot},
-    {"restore", cmdRestore, opts_restore, info_restore},
-    {"resume", cmdResume, opts_resume, info_resume},
-    {"save", cmdSave, opts_save, info_save},
-    {"schedinfo", cmdSchedinfo, opts_schedinfo, info_schedinfo},
-    {"dump", cmdDump, opts_dump, info_dump},
-    {"shutdown", cmdShutdown, opts_shutdown, info_shutdown},
-    {"setmem", cmdSetmem, opts_setmem, info_setmem},
-    {"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem},
-    {"memtune", cmdMemtune, opts_memtune, info_memtune},
-    {"setvcpus", cmdSetvcpus, opts_setvcpus, info_setvcpus},
-    {"suspend", cmdSuspend, opts_suspend, info_suspend},
-    {"ttyconsole", cmdTTYConsole, opts_ttyconsole, info_ttyconsole},
-    {"undefine", cmdUndefine, opts_undefine, info_undefine},
-    {"update-device", cmdUpdateDevice, opts_update_device, info_update_device},
-    {"uri", cmdURI, NULL, info_uri},
-
-    {"vol-create", cmdVolCreate, opts_vol_create, info_vol_create},
-    {"vol-create-from", cmdVolCreateFrom, opts_vol_create_from, 
info_vol_create_from},
-    {"vol-create-as", cmdVolCreateAs, opts_vol_create_as, info_vol_create_as},
-    {"vol-clone", cmdVolClone, opts_vol_clone, info_vol_clone},
-    {"vol-delete", cmdVolDelete, opts_vol_delete, info_vol_delete},
-    {"vol-wipe", cmdVolWipe, opts_vol_wipe, info_vol_wipe},
-    {"vol-dumpxml", cmdVolDumpXML, opts_vol_dumpxml, info_vol_dumpxml},
-    {"vol-info", cmdVolInfo, opts_vol_info, info_vol_info},
-    {"vol-list", cmdVolList, opts_vol_list, info_vol_list},
-    {"vol-pool", cmdVolPool, opts_vol_pool, info_vol_pool},
-    {"vol-path", cmdVolPath, opts_vol_path, info_vol_path},
-    {"vol-name", cmdVolName, opts_vol_name, info_vol_name},
-    {"vol-key", cmdVolKey, opts_vol_key, info_vol_key},
-
-    {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount},
-    {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
-    {"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
-    {"version", cmdVersion, NULL, info_version},
-    {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay},
+    {NULL, NULL, NULL, NULL}
+};

+static const vshCmdDef snapshotCmds[] = {
     {"snapshot-create", cmdSnapshotCreate, opts_snapshot_create, 
info_snapshot_create},
     {"snapshot-current", cmdSnapshotCurrent, opts_snapshot_current, 
info_snapshot_current},
     {"snapshot-delete", cmdSnapshotDelete, opts_snapshot_delete, 
info_snapshot_delete},
     {"snapshot-dumpxml", cmdSnapshotDumpXML, opts_snapshot_dumpxml, 
info_snapshot_dumpxml},
     {"snapshot-list", cmdSnapshotList, opts_snapshot_list, info_snapshot_list},
     {"snapshot-revert", cmdDomainSnapshotRevert, opts_snapshot_revert, 
info_snapshot_revert},
+    {NULL, NULL, NULL, NULL}
+};

+static const vshCmdDef hostAndHypervisorCmds[] = {
+    {"capabilities", cmdCapabilities, NULL, info_capabilities},
+    {"connect", cmdConnect, opts_connect, info_connect},
+    {"freecell", cmdFreecell, opts_freecell, info_freecell},
+    {"hostname", cmdHostname, NULL, info_hostname},
     {"qemu-monitor-command", cmdQemuMonitorCommand, opts_qemu_monitor_command, 
info_qemu_monitor_command},
-
+    {"uri", cmdURI, NULL, info_uri},
     {NULL, NULL, NULL, NULL}
 };

+static const vshCmdGrp cmdGroups[] = {
+    {VSH_CMD_GRP_DOM_MANAGEMENT, "domain", domManagementCmds},
+    {VSH_CMD_GRP_DOM_MONITORING, "monitor", domMonitoringCmds},
+    {VSH_CMD_GRP_STORAGE_POOL, "pool", storagePoolCmds},
+    {VSH_CMD_GRP_STORAGE_VOL, "volume", storageVolCmds},
+    {VSH_CMD_GRP_NETWORK, "network", networkCmds},
+    {VSH_CMD_GRP_NODEDEV, "nodedev", nodedevCmds},
+    {VSH_CMD_GRP_IFACE, "interface", ifaceCmds},
+    {VSH_CMD_GRP_NWFILTER, "filter", nwfilterCmds},
+    {VSH_CMD_GRP_SECRET, "secret", secretCmds},
+    {VSH_CMD_GRP_SNAPSHOT, "snapshot", snapshotCmds},
+    {VSH_CMD_GRP_HOST_AND_HV, "host", hostAndHypervisorCmds},
+    {VSH_CMD_GRP_VIRSH, "virsh", virshCmds},
+    {NULL, NULL, NULL}
+};
+
+
 /* ---------------
  * Utils for work with command definition
  * ---------------
@@ -10135,14 +10223,54 @@ vshCommandCheckOpts(vshControl *ctl, const vshCmd 
*cmd)
 static const vshCmdDef *
 vshCmddefSearch(const char *cmdname)
 {
+    const vshCmdGrp *g;
     const vshCmdDef *c;

-    for (c = commands; c->name; c++)
-        if (STREQ(c->name, cmdname))
-            return c;
+    for (g = cmdGroups; g->name; g++) {
+        for (c = g->commands; c->name; c++) {
+            if(STREQ(c->name, cmdname))
+                return c;
+        }
+    }
+
     return NULL;
 }

+static const vshCmdGrp *
+vshCmdGrpSearch(const char *grpname)
+{
+    const vshCmdGrp *g;
+
+    for (g = cmdGroups; g->name; g++) {
+        if(STREQ(g->name, grpname) || STREQ(g->keyword, grpname))
+            return g;
+    }
+
+    return NULL;
+}
+
+static int
+vshCmdGrpHelp(vshControl *ctl, const char *grpname)
+{
+    const vshCmdGrp *grp = vshCmdGrpSearch(grpname);
+    const vshCmdDef *cmd = NULL;
+
+    if (!grp) {
+        vshError(ctl, _("command group '%s' doesn't exist"), grpname);
+        return FALSE;
+    } else {
+        vshPrint(ctl, _(" %s (help keyword '%s'):\n"), grp->name,
+                 grp->keyword);
+
+        for (cmd = grp->commands; cmd->name; cmd++) {
+            vshPrint(ctl, "    %-30s %s\n", cmd->name,
+                     _(vshCmddefGetInfo(cmd, "help")));
+        }
+    }
+
+    return TRUE;
+}
+
 static int
 vshCmddefHelp(vshControl *ctl, const char *cmdname)
 {
@@ -11323,25 +11451,36 @@ vshCloseLogFile(vshControl *ctl)
 static char *
 vshReadlineCommandGenerator(const char *text, int state)
 {
-    static int list_index, len;
+    static int grp_list_index, cmd_list_index, len;
     const char *name;
+    const vshCmdGrp *grp;
+    const vshCmdDef *cmds;

-    /* If this is a new word to complete, initialize now.  This
-     * includes saving the length of TEXT for efficiency, and
-     * initializing the index variable to 0.
-     */
     if (!state) {
-        list_index = 0;
+        grp_list_index = 0;
+        cmd_list_index = 0;
         len = strlen(text);
     }

+    grp = cmdGroups;
+
     /* Return the next name which partially matches from the
      * command list.
      */
-    while ((name = commands[list_index].name)) {
-        list_index++;
-        if (STREQLEN(name, text, len))
-            return vshStrdup(NULL, name);
+    while (grp[grp_list_index].name) {
+        cmds = grp[grp_list_index].commands;
+
+        if (cmds[cmd_list_index].name) {
+            while ((name = cmds[cmd_list_index].name)) {
+                cmd_list_index++;
+
+                if (STREQLEN(name, text, len))
+                    return vshStrdup(NULL, name);
+            }
+        } else {
+            cmd_list_index = 0;
+            grp_list_index++;
+        }
     }

     /* If no names matched, then return NULL. */
@@ -11540,7 +11679,9 @@ vshDeinit(vshControl *ctl)
 static void
 vshUsage(void)
 {
+    const vshCmdGrp *grp;
     const vshCmdDef *cmd;
+
     fprintf(stdout, _("\n%s [options]... [<command_string>]"
                       "\n%s [options]... <command> [args...]\n\n"
                       "  options:\n"
@@ -11551,14 +11692,21 @@ vshUsage(void)
                       "    -q | --quiet            quiet mode\n"
                       "    -t | --timing           print timing information\n"
                       "    -l | --log <file>       output logging to file\n"
-                      "    -v | --version[=short]  program version\n\n"
-                      "    -V | --version=long     version and full 
options\n\n"
-                      "  commands (non interactive mode):\n"), progname, 
progname);
+                      "    -v | --version          program version\n\n"
+                      "  commands (non interactive mode):\n\n"), progname, 
progname);

-    for (cmd = commands; cmd->name; cmd++)
-        fprintf(stdout,
-                "    %-15s %s\n", cmd->name, _(vshCmddefGetInfo(cmd, "help")));
+    for (grp = cmdGroups; grp->name; grp++) {
+        fprintf(stdout, _(" %s (help keyword '%s')\n"), grp->name, 
grp->keyword);

+        for (cmd = grp->commands; cmd->name; cmd++)
+            fprintf(stdout,
+                    "    %-30s %s\n", cmd->name, _(vshCmddefGetInfo(cmd, 
"help")));
+
+        fprintf(stdout, "\n");
+    }
+
+    fprintf(stdout, "%s",
+            _("\n  (specify help <group> for details about the commands in the 
group)\n"));
     fprintf(stdout, "%s",
             _("\n  (specify help <command> for details about the 
command)\n\n"));
     return;
--
1.7.3.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to