Repository: python-cmd2/cmd2
Pull request #508 (2018-08-24 15:20:06)

ACHelpFormatter now inherits from argparse.RawTextHelpFormatter
To make it easier to create well formatted description text, I made ACHelpFormatter inherit from argparse.RawTextHelpFormatter.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7fbc7594..9f201664 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@
 * Enhancements
     * Added ``exit_code`` attribute of ``cmd2.Cmd`` class
         * Enables applications to return a non-zero exit code when exiting from ``cmdloop``
+    * ``ACHelpFormatter`` now inherits from ``argparse.RawTextHelpFormatter`` to make it easier
+    for formatting help/description text
     
 ## 0.9.4 (August 21, 2018)
 * Bug Fixes
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py
index 1479a6bf..0e241cd9 100755
--- a/cmd2/argparse_completer.py
+++ b/cmd2/argparse_completer.py
@@ -695,7 +695,7 @@ class AutoCompleter(object):
 
 
 # noinspection PyCompatibility,PyShadowingBuiltins,PyShadowingBuiltins
-class ACHelpFormatter(argparse.HelpFormatter):
+class ACHelpFormatter(argparse.RawTextHelpFormatter):
     """Custom help formatter to configure ordering of help text"""
 
     def _format_usage(self, usage, actions, groups, prefix) -> str:
@@ -870,9 +870,6 @@ class ACHelpFormatter(argparse.HelpFormatter):
             result = super()._format_args(action, default_metavar)
         return result
 
-    def _split_lines(self, text: str, width) -> List[str]:
-        return text.splitlines()
-
 
 # noinspection PyCompatibility
 class ACArgumentParser(argparse.ArgumentParser):
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index a17e128f..c49ec0cc 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -2556,18 +2556,19 @@ Usage:  Usage: unalias [-a] name [name ...]
         else:
             raise LookupError("Parameter '%s' not supported (type 'set' for list of parameters)." % param)
 
-    set_parser = ACArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
+    set_description = "Sets a settable parameter or shows current settings of parameters.\n"
+    set_description += "\n"
+    set_description += "Accepts abbreviated parameter names so long as there is no ambiguity.\n"
+    set_description += "Call without arguments for a list of settable parameters with their values."
+
+    set_parser = ACArgumentParser(description=set_description)
     set_parser.add_argument('-a', '--all', action='store_true', help='display read-only settings as well')
     set_parser.add_argument('-l', '--long', action='store_true', help='describe function of parameter')
     set_parser.add_argument('settable', nargs=(0, 2), help='[param_name] [value]')
 
     @with_argparser(set_parser)
     def do_set(self, args: argparse.Namespace) -> None:
-        """Sets a settable parameter or shows current settings of parameters.
-
-        Accepts abbreviated parameter names so long as there is no ambiguity.
-        Call without arguments for a list of settable parameters with their values.
-        """
+        """Sets a settable parameter or shows current settings of parameters"""
         try:
             param_name, val = args.settable
             val = val.strip()
@@ -2882,7 +2883,7 @@ Paths or arguments that contain spaces must be enclosed in quotes
                     embed(banner1=banner, exit_msg=exit_msg)
                 load_ipy(bridge)
 
-    history_parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
+    history_parser = ACArgumentParser()
     history_parser_group = history_parser.add_mutually_exclusive_group()
     history_parser_group.add_argument('-r', '--run', action='store_true', help='run selected history items')
     history_parser_group.add_argument('-e', '--edit', action='store_true',
diff --git a/examples/tab_autocompletion.py b/examples/tab_autocompletion.py
index 38972358..6a2e683e 100755
--- a/examples/tab_autocompletion.py
+++ b/examples/tab_autocompletion.py
@@ -125,7 +125,9 @@ class TabCompleteExample(cmd2.Cmd):
     #  - The help output for arguments with multiple flags or with append=True is more concise
     #  - ACArgumentParser adds the ability to specify ranges of argument counts in 'nargs'
 
-    suggest_parser = argparse_completer.ACArgumentParser()
+    suggest_description = "Suggest command demonstrates argparse customizations.\n"
+    suggest_description += "See hybrid_suggest and orig_suggest to compare the help output."
+    suggest_parser = argparse_completer.ACArgumentParser(description=suggest_description)
 
     suggest_parser.add_argument('-t', '--type', choices=['movie', 'show'], required=True)
     suggest_parser.add_argument('-d', '--duration', nargs=(1, 2), action='append',
@@ -136,12 +138,7 @@ class TabCompleteExample(cmd2.Cmd):
     @cmd2.with_category(CAT_AUTOCOMPLETE)
     @cmd2.with_argparser(suggest_parser)
     def do_suggest(self, args) -> None:
-        """Suggest command demonstrates argparse customizations
-
-        See hybrid_suggest and orig_suggest to compare the help output.
-
-
-        """
+        """Suggest command demonstrates argparse customizations"""
         if not args.type:
             self.do_help('suggest')
 


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index 3f3b862e..f86a4c63 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -42,14 +42,14 @@ load                Runs commands in script file that is encoded as either ASCII
 py                  Invoke python command, shell, or script
 pyscript            Runs a python script file inside the console
 quit                Exits this application.
-set                 Sets a settable parameter or shows current settings of parameters.
+set                 Sets a settable parameter or shows current settings of parameters
 shell               Execute a command as if at the OS prompt.
 shortcuts           Lists shortcuts (aliases) available.
 unalias             Unsets aliases
 """
 
 # Help text for the history command
-HELP_HISTORY = """usage: history [-h] [-r | -e | -s | -o FILE | -t TRANSCRIPT | -c] [arg]
+HELP_HISTORY = """Usage: history [arg] [-h] [-r | -e | -s | -o FILE | -t TRANSCRIPT | -c]
 
 View, run, edit, save, or clear previously entered commands.
 
@@ -65,9 +65,9 @@ optional arguments:
   -r, --run             run selected history items
   -e, --edit            edit and then run selected history items
   -s, --script          script format; no separation lines
-  -o FILE, --output-file FILE
+  -o, --output-file FILE
                         output commands to a script file
-  -t TRANSCRIPT, --transcript TRANSCRIPT
+  -t, --transcript TRANSCRIPT
                         output commands and results to a transcript file
   -c, --clear           clears all history
 """
diff --git a/tests/test_autocompletion.py b/tests/test_autocompletion.py
index e0a71831..8aa26e0e 100644
--- a/tests/test_autocompletion.py
+++ b/tests/test_autocompletion.py
@@ -19,8 +19,8 @@ def cmd2_app():
 
 SUGGEST_HELP = '''Usage: suggest -t {movie, show} [-h] [-d DURATION{1..2}]
 
-Suggest command demonstrates argparse customizations See hybrid_suggest and
-orig_suggest to compare the help output.
+Suggest command demonstrates argparse customizations.
+See hybrid_suggest and orig_suggest to compare the help output.
 
 required arguments:
   -t, --type {movie, show}
@@ -59,7 +59,7 @@ def test_help_required_group(cmd2_app, capsys):
     assert out1 == out2
     assert out1[0].startswith('Usage: suggest')
     assert out1[1] == ''
-    assert out1[2].startswith('Suggest command demonstrates argparse customizations ')
+    assert out1[2].startswith('Suggest command demonstrates argparse customizations.')
     assert out1 == normalize(SUGGEST_HELP)
 
 
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index b6081f53..b75cd102 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -62,7 +62,7 @@ def test_base_argparse_help(base_app, capsys):
     out2 = run_cmd(base_app, 'help set')
 
     assert out1 == out2
-    assert out1[0].startswith('usage: set')
+    assert out1[0].startswith('Usage: set')
     assert out1[1] == ''
     assert out1[2].startswith('Sets a settable parameter')
 
@@ -71,10 +71,8 @@ def test_base_invalid_option(base_app, capsys):
     out, err = capsys.readouterr()
     out = normalize(out)
     err = normalize(err)
-    assert len(err) == 3
-    assert len(out) == 15
     assert 'Error: unrecognized arguments: -z' in err[0]
-    assert out[0] == 'usage: set [-h] [-a] [-l] [settable [settable ...]]'
+    assert out[0] == 'Usage: set settable{0..2} [-h] [-a] [-l]'
 
 def test_base_shortcuts(base_app):
     out = run_cmd(base_app, 'shortcuts')
@@ -1252,7 +1250,7 @@ load                Runs commands in script file that is encoded as either ASCII
 py                  Invoke python command, shell, or script
 pyscript            Runs a python script file inside the console
 quit                Exits this application.
-set                 Sets a settable parameter or shows current settings of parameters.
+set                 Sets a settable parameter or shows current settings of parameters
 shell               Execute a command as if at the OS prompt.
 shortcuts           Lists shortcuts (aliases) available.
 unalias             Unsets aliases