summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcmd2.py17
-rwxr-xr-xexamples/help_categories.py9
-rw-r--r--tests/conftest.py18
-rw-r--r--tests/test_cmd2.py103
4 files changed, 138 insertions, 9 deletions
diff --git a/cmd2.py b/cmd2.py
index 7084dc5e..201d608b 100755
--- a/cmd2.py
+++ b/cmd2.py
@@ -2934,10 +2934,9 @@ Usage: Usage: unalias [-a] name [name ...]
cmds_cats = {}
for command in visible_commands:
- if command in help_topics:
- cmds_doc.append(command)
- help_topics.remove(command)
- elif getattr(self, self._func_named(command)).__doc__:
+ if command in help_topics or getattr(self, self._func_named(command)).__doc__:
+ if command in help_topics:
+ help_topics.remove(command)
if hasattr(getattr(self, self._func_named(command)), HELP_CATEGORY):
category = getattr(getattr(self, self._func_named(command)), HELP_CATEGORY)
cmds_cats.setdefault(category, [])
@@ -2972,7 +2971,7 @@ Usage: Usage: unalias [-a] name [name ...]
widest = 0
# measure the commands
for command in cmds:
- width = wcswidth(command)
+ width = len(command)
if width > widest:
widest = width
# add a 4-space pad
@@ -2983,17 +2982,23 @@ Usage: Usage: unalias [-a] name [name ...]
if self.ruler:
self.stdout.write('{:{ruler}<{width}}\n'.format('', ruler=self.ruler, width=80))
+ help_topics = self.get_help_topics()
for command in cmds:
# Attempt to locate the first documentation block
doc = getattr(self, self._func_named(command)).__doc__
doc_block = []
found_first = False
+ in_usage = False
for doc_line in doc.splitlines():
str(doc_line).strip()
if len(doc_line.strip()) > 0:
+ if in_usage or doc_line.startswith('usage: '):
+ in_usage = True
+ continue
doc_block.append(doc_line.strip())
found_first = True
else:
+ in_usage = False
if found_first:
break
@@ -3101,7 +3106,7 @@ Usage: Usage: unalias [-a] name [name ...]
else:
raise LookupError("Parameter '%s' not supported (type 'show' for list of parameters)." % param)
- set_parser = argparse.ArgumentParser()
+ set_parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
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='*', help='[param_name] [value]')
diff --git a/examples/help_categories.py b/examples/help_categories.py
index 2a88edba..8a33e62c 100755
--- a/examples/help_categories.py
+++ b/examples/help_categories.py
@@ -4,7 +4,8 @@
A sample application for tagging categories on commands.
"""
-from cmd2 import Cmd, categorize, __version__
+from cmd2 import Cmd, categorize, __version__, with_argparser
+import argparse
class HelpCategories(Cmd):
@@ -51,6 +52,12 @@ class HelpCategories(Cmd):
"""Redeploy command"""
self.poutput('Redeploy')
+ restart_parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
+ restart_parser.add_argument('when', default='now',
+ choices=['now', 'later', 'sometime', 'whenever'],
+ help='Specify when to restart')
+
+ @with_argparser(restart_parser)
def do_restart(self, _):
"""Restart command"""
self.poutput('Restart')
diff --git a/tests/conftest.py b/tests/conftest.py
index 58ec8ee0..4170a5e1 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -19,6 +19,24 @@ alias help load pyscript set shortcuts
edit history py quit shell unalias
"""
+BASE_HELP_VERBOSE = """
+Documented commands (type help <topic>):
+================================================================================
+alias Define or display aliases
+edit Edit a file in a text editor.
+help List available commands with "help" or detailed help with "help cmd".
+history View, run, edit, and save previously entered commands.
+load Runs commands in script file that is encoded as either ASCII or UTF-8 text.
+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.
+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] [arg]
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 545cf1aa..0861c073 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -21,7 +21,8 @@ from optparse import make_option
import six.moves as sm
import cmd2
-from conftest import run_cmd, normalize, BASE_HELP, HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG, StdOut
+from conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \
+ HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG, StdOut
def test_ver():
@@ -38,6 +39,13 @@ def test_base_help(base_app):
expected = normalize(BASE_HELP)
assert out == expected
+def test_base_help_verbose(base_app):
+ out = run_cmd(base_app, 'help -v')
+ expected = normalize(BASE_HELP_VERBOSE)
+ assert out == expected
+
+ out = run_cmd(base_app, 'help --verbose')
+ assert out == expected
def test_base_help_history(base_app):
out = run_cmd(base_app, 'help history')
@@ -47,7 +55,7 @@ def test_base_argparse_help(base_app, capsys):
# Verify that "set -h" gives the same output as "help set" and that it starts in a way that makes sense
run_cmd(base_app, 'set -h')
out, err = capsys.readouterr()
- out1 = out.splitlines()
+ out1 = normalize(out)
out2 = run_cmd(base_app, 'help set')
@@ -1066,6 +1074,97 @@ def test_help_overridden_method(help_app):
assert out == expected
+class HelpCategoriesApp(cmd2.Cmd):
+ """Class for testing custom help_* methods which override docstring help."""
+ def __init__(self, *args, **kwargs):
+ # Need to use this older form of invoking super class constructor to support Python 2.x and Python 3.x
+ cmd2.Cmd.__init__(self, *args, **kwargs)
+
+ def do_diddly(self, arg):
+ """This command does diddly"""
+ pass
+
+ cmd2.categorize(do_diddly, "Some Category")
+
+ def do_squat(self, arg):
+ """This docstring help will never be shown because the help_squat method overrides it."""
+ pass
+
+ def help_squat(self):
+ self.stdout.write('This command does diddly squat...\n')
+
+ def do_edit(self, arg):
+ """This overrides the edit command and does nothing."""
+ pass
+
+ cmd2.categorize((do_squat, do_edit), 'Custom Category')
+
+ # This command will be in the "undocumented" section of the help menu
+ def do_undoc(self, arg):
+ pass
+
+@pytest.fixture
+def helpcat_app():
+ app = HelpCategoriesApp()
+ app.stdout = StdOut()
+ return app
+
+def test_help_cat_base(helpcat_app):
+ out = run_cmd(helpcat_app, 'help')
+ expected = normalize("""Documented commands (type help <topic>):
+
+Custom Category
+===============
+edit squat
+
+Some Category
+=============
+diddly
+
+Other
+=====
+alias help history load py pyscript quit set shell shortcuts unalias
+
+Undocumented commands:
+======================
+undoc
+""")
+ assert out == expected
+
+def test_help_cat_verbose(helpcat_app):
+ out = run_cmd(helpcat_app, 'help --verbose')
+ expected = normalize("""Documented commands (type help <topic>):
+
+Custom Category
+================================================================================
+edit This overrides the edit command and does nothing.
+squat This docstring help will never be shown because the help_squat method overrides it.
+
+Some Category
+================================================================================
+diddly This command does diddly
+
+Other
+================================================================================
+alias Define or display aliases
+help List available commands with "help" or detailed help with "help cmd".
+history View, run, edit, and save previously entered commands.
+load Runs commands in script file that is encoded as either ASCII or UTF-8 text.
+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.
+shell Execute a command as if at the OS prompt.
+shortcuts Lists shortcuts (aliases) available.
+unalias Unsets aliases
+
+Undocumented commands:
+======================
+undoc
+""")
+ assert out == expected
+
+
class SelectApp(cmd2.Cmd):
def do_eat(self, arg):
"""Eat something, with a selection of sauces to choose from."""