diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 80e783bd5..7d84590f4 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -492,8 +492,8 @@ def __init__( # Set header for table listing commands that have no help info. self.undoc_header = "Undocumented Commands" - # If any command has been categorized, then all other commands that haven't been categorized - # will display under this section in the help output. + # If any command has been categorized, then all other documented commands that + # haven't been categorized will display under this section in the help output. self.default_category = "Uncategorized Commands" # The error that prints when no help information can be found @@ -4072,10 +4072,13 @@ def do_help(self, args: argparse.Namespace) -> None: self.poutput(Text(self.doc_leader, style=Cmd2Style.HELP_LEADER)) self.poutput() - # Print any categories first and then the default category. + # Print any categories first and then the remaining documented commands. sorted_categories = sorted(cmds_cats.keys(), key=self.default_sort_key) all_cmds = {category: cmds_cats[category] for category in sorted_categories} - all_cmds[self.doc_header] = cmds_doc + if all_cmds: + all_cmds[self.default_category] = cmds_doc + else: + all_cmds[self.doc_header] = cmds_doc # Used to provide verbose table separation for better readability. previous_table_printed = False diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index 079edf067..abe578d8b 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -1365,6 +1365,9 @@ def test_columnize(capsys: pytest.CaptureFixture[str]) -> None: class HelpCategoriesApp(cmd2.Cmd): """Class for testing custom help_* methods which override docstring help.""" + SOME_CATEGORY = "Some Category" + CUSTOM_CATEGORY = "Custom Category" + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) @@ -1373,10 +1376,11 @@ def do_diddly(self, arg) -> None: """This command does diddly""" # This command will be in the "Some Category" section of the help menu even though it has no docstring - @cmd2.with_category("Some Category") + @cmd2.with_category(SOME_CATEGORY) def do_cat_nodoc(self, arg) -> None: pass + # This command will show in the category labeled with self.default_category def do_squat(self, arg) -> None: """This docstring help will never be shown because the help_squat method overrides it.""" @@ -1386,7 +1390,7 @@ def help_squat(self) -> None: def do_edit(self, arg) -> None: """This overrides the edit command and does nothing.""" - cmd2.categorize((do_squat, do_edit), 'Custom Category') + 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) -> None: @@ -1403,12 +1407,22 @@ def test_help_cat_base(helpcat_app) -> None: assert helpcat_app.last_result is True verify_help_text(helpcat_app, out) + help_text = ''.join(out) + assert helpcat_app.CUSTOM_CATEGORY in help_text + assert helpcat_app.SOME_CATEGORY in help_text + assert helpcat_app.default_category in help_text + def test_help_cat_verbose(helpcat_app) -> None: out, err = run_cmd(helpcat_app, 'help --verbose') assert helpcat_app.last_result is True verify_help_text(helpcat_app, out) + help_text = ''.join(out) + assert helpcat_app.CUSTOM_CATEGORY in help_text + assert helpcat_app.SOME_CATEGORY in help_text + assert helpcat_app.default_category in help_text + class SelectApp(cmd2.Cmd): def do_eat(self, arg) -> None: