diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04351333..bae7f7d7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,6 @@
 ## 1.0.2 (TBD, 2020)
+* Bug Fixes
+    * Ctrl-C now stops a running text script instead of just the current script command
 * Enhancements
     * `do_shell()` now saves the return code of the command it runs in `self.last_result` for use in pyscripts
 
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 630ab9b2..fdc7a2d8 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -187,7 +187,7 @@ class Cmd(cmd.Cmd):
 
         # Attributes which should NOT be dynamically settable via the set command at runtime
         self.default_to_shell = False  # Attempt to run unrecognized commands as shell commands
-        self.quit_on_sigint = False  # Quit the loop on interrupt instead of just resetting prompt
+        self.quit_on_sigint = False  # Ctrl-C at the prompt will quit the program instead of just resetting prompt
         self.allow_redirection = allow_redirection  # Security setting to prevent redirection of stdout
 
         # Attributes which ARE dynamically settable via the set command at runtime
@@ -1584,11 +1584,15 @@ class Cmd(cmd.Cmd):
         statement = self.statement_parser.parse_command_only(line)
         return statement.command, statement.args, statement.command_and_args
 
-    def onecmd_plus_hooks(self, line: str, *, add_to_history: bool = True, py_bridge_call: bool = False) -> bool:
+    def onecmd_plus_hooks(self, line: str, *, add_to_history: bool = True,
+                          raise_keyboard_interrupt: bool = False, py_bridge_call: bool = False) -> bool:
         """Top-level function called by cmdloop() to handle parsing a line and running the command and all of its hooks.
 
         :param line: command line to run
         :param add_to_history: If True, then add this command to history. Defaults to True.
+        :param raise_keyboard_interrupt: if True, then KeyboardInterrupt exceptions will be raised. This is used when
+                                         running commands in a loop to be able to stop the whole loop and not just
+                                         the current command. Defaults to False.
         :param py_bridge_call: This should only ever be set to True by PyBridge to signify the beginning
                                of an app() call from Python. It is used to enable/disable the storage of the
                                command's stdout.
@@ -1681,14 +1685,18 @@ class Cmd(cmd.Cmd):
                     if py_bridge_call:
                         # Stop saving command's stdout before command finalization hooks run
                         self.stdout.pause_storage = True
-
+        except KeyboardInterrupt as ex:
+            if raise_keyboard_interrupt:
+                raise ex
         except (Cmd2ArgparseError, EmptyStatement):
             # Don't do anything, but do allow command finalization hooks to run
             pass
         except Exception as ex:
             self.pexcept(ex)
         finally:
-            return self._run_cmdfinalization_hooks(stop, statement)
+            stop = self._run_cmdfinalization_hooks(stop, statement)
+
+        return stop
 
     def _run_cmdfinalization_hooks(self, stop: bool, statement: Optional[Statement]) -> bool:
         """Run the command finalization hooks"""
@@ -1711,13 +1719,16 @@ class Cmd(cmd.Cmd):
         except Exception as ex:
             self.pexcept(ex)
 
-    def runcmds_plus_hooks(self, cmds: List[Union[HistoryItem, str]], *, add_to_history: bool = True) -> bool:
+    def runcmds_plus_hooks(self, cmds: List[Union[HistoryItem, str]], *, add_to_history: bool = True,
+                           stop_on_keyboard_interrupt: bool = True) -> bool:
         """
         Used when commands are being run in an automated fashion like text scripts or history replays.
         The prompt and command line for each command will be printed if echo is True.
 
         :param cmds: commands to run
         :param add_to_history: If True, then add these commands to history. Defaults to True.
+        :param stop_on_keyboard_interrupt: stop command loop if Ctrl-C is pressed instead of just
+                                           moving to the next command. Defaults to True.
         :return: True if running of commands should stop
         """
         for line in cmds:
@@ -1727,8 +1738,14 @@ class Cmd(cmd.Cmd):
             if self.echo:
                 self.poutput('{}{}'.format(self.prompt, line))
 
-            if self.onecmd_plus_hooks(line, add_to_history=add_to_history):
-                return True
+            try:
+                if self.onecmd_plus_hooks(line, add_to_history=add_to_history,
+                                          raise_keyboard_interrupt=stop_on_keyboard_interrupt):
+                    return True
+            except KeyboardInterrupt as e:
+                if stop_on_keyboard_interrupt:
+                    self.perror(e)
+                    break
 
         return False
 
@@ -3269,9 +3286,6 @@ class Cmd(cmd.Cmd):
                         if saved_cmd2_env is not None:
                             self._restore_cmd2_env(saved_cmd2_env)
 
-        except KeyboardInterrupt:
-            pass
-
         finally:
             with self.sigint_protection:
                 if saved_sys_path is not None:
@@ -3302,8 +3316,6 @@ class Cmd(cmd.Cmd):
             if selection != 'Yes':
                 return
 
-        py_return = False
-
         # Save current command line arguments
         orig_args = sys.argv
 
@@ -3314,9 +3326,6 @@ class Cmd(cmd.Cmd):
             # noinspection PyTypeChecker
             py_return = self.do_py('--pyscript {}'.format(utils.quote_string(args.script_path)))
 
-        except KeyboardInterrupt:
-            pass
-
         finally:
             # Restore command line arguments to original state
             sys.argv = orig_args
@@ -3629,7 +3638,12 @@ class Cmd(cmd.Cmd):
                 self.stdout = utils.StdSim(self.stdout)
 
                 # then run the command and let the output go into our buffer
-                stop = self.onecmd_plus_hooks(history_item)
+                try:
+                    stop = self.onecmd_plus_hooks(history_item, raise_keyboard_interrupt=True)
+                except KeyboardInterrupt as e:
+                    self.perror(e)
+                    stop = True
+
                 commands_run += 1
 
                 # add the regex-escaped output to the transcript
diff --git a/docs/features/initialization.rst b/docs/features/initialization.rst
index b1ca4f05..d79b3818 100644
--- a/docs/features/initialization.rst
+++ b/docs/features/initialization.rst
@@ -146,8 +146,8 @@ override:
   everything available with **self_in_py**)
 - **quiet**: if ``True`` then completely suppress nonessential output (Default:
   ``False``)
-- **quit_on_sigint**: if ``True`` quit the main loop on interrupt instead of
-  just resetting prompt
+- **quit_on_sigint**: if ``True`` Ctrl-C at the prompt will quit the program
+  instead of just resetting prompt
 - **settable**: dictionary that controls which of these instance attributes
   are settable at runtime using the *set* command
 - **timing**: if ``True`` display execution time for each command (Default:
diff --git a/docs/features/misc.rst b/docs/features/misc.rst
index 0dc1939c..3825065f 100644
--- a/docs/features/misc.rst
+++ b/docs/features/misc.rst
@@ -104,10 +104,10 @@ method be called.
 Quit on SIGINT
 --------------
 
-On many shells, SIGINT (most often triggered by the user pressing Ctrl+C) only
-cancels the current line, not the entire command loop. By default, a ``cmd2``
-application will quit on receiving this signal. However, if ``quit_on_sigint``
-is set to ``False``, then the current line will simply be cancelled.
+On many shells, SIGINT (most often triggered by the user pressing Ctrl+C)
+while at the prompt only cancels the current line, not the entire command
+loop. By default, a ``cmd2`` application matches this behavior. However, if
+``quit_on_sigint`` is set to ``True``, the command loop will quit instead.
 
 ::
 

command scripts cannot be interrupted
It seems that even with quit_on_sigint set to True, ^C doesn't interrupt a command script.  Am I missing something?
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 66ef33de..b86ddfa6 100755
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -376,6 +376,28 @@ set allow_style Never""" % (prefilepath, postfilepath)
     out, err = run_cmd(base_app, 'history -s')
     assert out == normalize(expected)
 
+def test_runcmds_plus_hooks_ctrl_c(base_app, capsys):
+    """Test Ctrl-C while in runcmds_plus_hooks"""
+    import types
+
+    def do_keyboard_interrupt(self, _):
+        raise KeyboardInterrupt('Interrupting this command')
+    setattr(base_app, 'do_keyboard_interrupt', types.MethodType(do_keyboard_interrupt, base_app))
+
+    # Default behavior is to stop command loop on Ctrl-C
+    base_app.history.clear()
+    base_app.runcmds_plus_hooks(['help', 'keyboard_interrupt', 'shortcuts'])
+    out, err = capsys.readouterr()
+    assert err.startswith("Interrupting this command")
+    assert len(base_app.history) == 2
+
+    # Ctrl-C should not stop command loop in this case
+    base_app.history.clear()
+    base_app.runcmds_plus_hooks(['help', 'keyboard_interrupt', 'shortcuts'], stop_on_keyboard_interrupt=False)
+    out, err = capsys.readouterr()
+    assert not err
+    assert len(base_app.history) == 3
+
 def test_relative_run_script(base_app, request):
     test_dir = os.path.dirname(request.module.__file__)
     filename = os.path.join(test_dir, 'script.txt')
diff --git a/tests/test_transcript.py b/tests/test_transcript.py
index 64c95b30..aa6f8c4e 100644
--- a/tests/test_transcript.py
+++ b/tests/test_transcript.py
@@ -81,6 +81,9 @@ class CmdLineApp(cmd2.Cmd):
         """Do nothing and output nothing"""
         pass
 
+    def do_keyboard_interrupt(self, _):
+        raise KeyboardInterrupt('Interrupting this command')
+
 
 def test_commands_at_invocation():
     testargs = ["prog", "say hello", "say Gracie", "quit"]
@@ -235,6 +238,12 @@ def test_generate_transcript_stop(capsys):
     _, err = capsys.readouterr()
     assert err.startswith("Command 2 triggered a stop")
 
+    # keyboard_interrupt command should stop the loop and not run the third command
+    commands = ['help', 'keyboard_interrupt', 'set']
+    app._generate_transcript(commands, transcript_fname)
+    _, err = capsys.readouterr()
+    assert err.startswith("Interrupting this command\nCommand 2 triggered a stop")
+
 
 @pytest.mark.parametrize('expected, transformed', [
     # strings with zero or one slash or with escaped slashes means no regular

pip install -e .[dev]
parse_log_pytest
Pipfile
pytest pytest-cov pytest-mock
apt-get update apt-get install -y gcc
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.16
anyio==4.9.0
attrs==25.3.0
babel==2.17.0
backports.tarfile==1.2.0
cachetools==5.5.2
certifi==2025.1.31
cffi==1.17.1
chardet==5.2.0
charset-normalizer==3.4.1
click==8.1.8
-e git+https://github.com/python-cmd2/cmd2.git@990ec45e087aed2a9a6309db893c8a25cb3a89fd#egg=cmd2
codecov==2.1.13
colorama==0.4.6
coverage==7.8.0
cryptography==44.0.2
distlib==0.3.9
doc8==1.1.2
docutils==0.21.2
exceptiongroup==1.2.2
filelock==3.18.0
flake8==7.2.0
h11==0.14.0
id==1.5.0
idna==3.10
imagesize==1.4.1
importlib_metadata==8.6.1
iniconfig==2.1.0
invoke==2.2.0
jaraco.classes==3.4.0
jaraco.context==6.0.1
jaraco.functools==4.1.0
jeepney==0.9.0
Jinja2==3.1.6
keyring==25.6.0
markdown-it-py==3.0.0
MarkupSafe==3.0.2
mccabe==0.7.0
mdurl==0.1.2
more-itertools==10.6.0
nh3==0.2.21
packaging==24.2
pbr==6.1.1
pipfile==0.0.2
platformdirs==4.3.7
pluggy==1.5.0
pycodestyle==2.13.0
pycparser==2.22
pyflakes==3.3.1
Pygments==2.19.1
pyperclip==1.9.0
pyproject-api==1.9.0
pytest==8.3.5
pytest-cov==6.0.0
pytest-mock==3.14.0
readme_renderer==44.0
requests==2.32.3
requests-toolbelt==1.0.0
restructuredtext_lint==1.4.0
rfc3986==2.0.0
rich==14.0.0
SecretStorage==3.3.3
sniffio==1.3.1
snowballstemmer==2.2.0
Sphinx==7.4.7
sphinx-autobuild==2024.10.3
sphinx-rtd-theme==3.0.2
sphinxcontrib-applehelp==2.0.0
sphinxcontrib-devhelp==2.0.0
sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
starlette==0.46.1
stevedore==5.4.1
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
tomli==2.2.1
tox==4.25.0
twine==6.1.0
typing_extensions==4.13.0
urllib3==2.3.0
uvicorn==0.34.0
virtualenv==20.29.3
watchfiles==1.0.4
wcwidth==0.2.13
websockets==15.0.1
zipp==3.21.0

name: cmd2
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - pipfile=0.0.2=py_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - toml=0.10.2=pyhd3eb1b0_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.16
      - anyio==4.9.0
      - attrs==25.3.0
      - babel==2.17.0
      - backports-tarfile==1.2.0
      - cachetools==5.5.2
      - certifi==2025.1.31
      - cffi==1.17.1
      - chardet==5.2.0
      - charset-normalizer==3.4.1
      - click==8.1.8
      - codecov==2.1.13
      - colorama==0.4.6
      - coverage==7.8.0
      - cryptography==44.0.2
      - distlib==0.3.9
      - doc8==1.1.2
      - docutils==0.21.2
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - flake8==7.2.0
      - h11==0.14.0
      - id==1.5.0
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - invoke==2.2.0
      - jaraco-classes==3.4.0
      - jaraco-context==6.0.1
      - jaraco-functools==4.1.0
      - jeepney==0.9.0
      - jinja2==3.1.6
      - keyring==25.6.0
      - markdown-it-py==3.0.0
      - markupsafe==3.0.2
      - mccabe==0.7.0
      - mdurl==0.1.2
      - more-itertools==10.6.0
      - nh3==0.2.21
      - packaging==24.2
      - pbr==6.1.1
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pycodestyle==2.13.0
      - pycparser==2.22
      - pyflakes==3.3.1
      - pygments==2.19.1
      - pyperclip==1.9.0
      - pyproject-api==1.9.0
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - readme-renderer==44.0
      - requests==2.32.3
      - requests-toolbelt==1.0.0
      - restructuredtext-lint==1.4.0
      - rfc3986==2.0.0
      - rich==14.0.0
      - secretstorage==3.3.3
      - sniffio==1.3.1
      - snowballstemmer==2.2.0
      - sphinx==7.4.7
      - sphinx-autobuild==2024.10.3
      - sphinx-rtd-theme==3.0.2
      - sphinxcontrib-applehelp==2.0.0
      - sphinxcontrib-devhelp==2.0.0
      - sphinxcontrib-htmlhelp==2.1.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==2.0.0
      - sphinxcontrib-serializinghtml==2.0.0
      - starlette==0.46.1
      - stevedore==5.4.1
      - tomli==2.2.1
      - tox==4.25.0
      - twine==6.1.0
      - typing-extensions==4.13.0
      - urllib3==2.3.0
      - uvicorn==0.34.0
      - virtualenv==20.29.3
      - watchfiles==1.0.4
      - wcwidth==0.2.13
      - websockets==15.0.1
      - zipp==3.21.0
prefix: /opt/conda/envs/cmd2

tests/test_cmd2.py::test_runcmds_plus_hooks_ctrl_c tests/test_transcript.py::test_generate_transcript_stop
tests/test_cmd2.py::test_not_in_main_thread tests/test_cmd2.py::test_which_editor_good
tests/test_cmd2.py::test_version tests/test_cmd2.py::test_empty_statement tests/test_cmd2.py::test_base_help tests/test_cmd2.py::test_base_help_verbose tests/test_cmd2.py::test_base_argparse_help tests/test_cmd2.py::test_base_invalid_option tests/test_cmd2.py::test_base_shortcuts tests/test_cmd2.py::test_command_starts_with_shortcut tests/test_cmd2.py::test_base_show tests/test_cmd2.py::test_base_show_long tests/test_cmd2.py::test_set tests/test_cmd2.py::test_set_val_empty tests/test_cmd2.py::test_set_val_is_flag tests/test_cmd2.py::test_set_not_supported tests/test_cmd2.py::test_set_no_settables tests/test_cmd2.py::test_set_allow_style[Never-True-Never] tests/test_cmd2.py::test_set_allow_style[neVeR-True-Never] tests/test_cmd2.py::test_set_allow_style[Terminal-True-Terminal] tests/test_cmd2.py::test_set_allow_style[TeRMInal-True-Terminal] tests/test_cmd2.py::test_set_allow_style[Always-True-Always] tests/test_cmd2.py::test_set_allow_style[AlWaYs-True-Always] tests/test_cmd2.py::test_set_allow_style[invalid-False-Terminal] tests/test_cmd2.py::test_set_onchange_hook tests/test_cmd2.py::test_base_shell tests/test_cmd2.py::test_shell_last_result tests/test_cmd2.py::test_base_py tests/test_cmd2.py::test_base_error tests/test_cmd2.py::test_run_script tests/test_cmd2.py::test_run_script_with_empty_args tests/test_cmd2.py::test_run_script_with_nonexistent_file tests/test_cmd2.py::test_run_script_with_directory tests/test_cmd2.py::test_run_script_with_empty_file tests/test_cmd2.py::test_run_script_with_binary_file tests/test_cmd2.py::test_run_script_with_python_file tests/test_cmd2.py::test_run_script_with_utf8_file tests/test_cmd2.py::test_run_script_nested_run_scripts tests/test_cmd2.py::test_runcmds_plus_hooks tests/test_cmd2.py::test_relative_run_script tests/test_cmd2.py::test_relative_run_script_with_odd_file_names[nothingweird] tests/test_cmd2.py::test_relative_run_script_with_odd_file_names[has tests/test_cmd2.py::test_relative_run_script_with_odd_file_names["is_double_quoted"] tests/test_cmd2.py::test_relative_run_script_with_odd_file_names['is_single_quoted'] tests/test_cmd2.py::test_relative_run_script_requires_an_argument tests/test_cmd2.py::test_in_script tests/test_cmd2.py::test_output_redirection tests/test_cmd2.py::test_output_redirection_to_nonexistent_directory tests/test_cmd2.py::test_output_redirection_to_too_long_filename tests/test_cmd2.py::test_feedback_to_output_true tests/test_cmd2.py::test_feedback_to_output_false tests/test_cmd2.py::test_disallow_redirection tests/test_cmd2.py::test_pipe_to_shell tests/test_cmd2.py::test_pipe_to_shell_and_redirect tests/test_cmd2.py::test_pipe_to_shell_error tests/test_cmd2.py::test_base_timing tests/test_cmd2.py::test_base_debug tests/test_cmd2.py::test_debug_not_settable tests/test_cmd2.py::test_remove_settable_keyerror tests/test_cmd2.py::test_edit_file tests/test_cmd2.py::test_edit_file_with_odd_file_names[nothingweird] tests/test_cmd2.py::test_edit_file_with_odd_file_names[has tests/test_cmd2.py::test_edit_file_with_odd_file_names["is_double_quoted"] tests/test_cmd2.py::test_edit_file_with_odd_file_names['is_single_quoted'] tests/test_cmd2.py::test_edit_file_with_spaces tests/test_cmd2.py::test_edit_blank tests/test_cmd2.py::test_base_py_interactive tests/test_cmd2.py::test_base_cmdloop_with_startup_commands tests/test_cmd2.py::test_base_cmdloop_without_startup_commands tests/test_cmd2.py::test_cmdloop_without_rawinput tests/test_cmd2.py::test_stty_sane tests/test_cmd2.py::test_precmd_hook_success tests/test_cmd2.py::test_precmd_hook_failure tests/test_cmd2.py::test_interrupt_quit tests/test_cmd2.py::test_interrupt_noquit tests/test_cmd2.py::test_default_to_shell tests/test_cmd2.py::test_ansi_prompt_not_esacped tests/test_cmd2.py::test_ansi_prompt_escaped tests/test_cmd2.py::test_custom_command_help tests/test_cmd2.py::test_custom_help_menu tests/test_cmd2.py::test_help_undocumented tests/test_cmd2.py::test_help_overridden_method tests/test_cmd2.py::test_help_cat_base tests/test_cmd2.py::test_help_cat_verbose tests/test_cmd2.py::test_select_options tests/test_cmd2.py::test_select_invalid_option_too_big tests/test_cmd2.py::test_select_invalid_option_too_small tests/test_cmd2.py::test_select_list_of_strings tests/test_cmd2.py::test_select_list_of_tuples tests/test_cmd2.py::test_select_uneven_list_of_tuples tests/test_cmd2.py::test_select_eof tests/test_cmd2.py::test_select_ctrl_c tests/test_cmd2.py::test_help_with_no_docstring tests/test_cmd2.py::test_which_editor_bad tests/test_cmd2.py::test_multiline_complete_empty_statement_raises_exception tests/test_cmd2.py::test_multiline_complete_statement_without_terminator tests/test_cmd2.py::test_multiline_complete_statement_with_unclosed_quotes tests/test_cmd2.py::test_multiline_input_line_to_statement tests/test_cmd2.py::test_clipboard_failure tests/test_cmd2.py::test_commandresult_truthy tests/test_cmd2.py::test_commandresult_falsy tests/test_cmd2.py::test_is_text_file_bad_input tests/test_cmd2.py::test_eof tests/test_cmd2.py::test_echo tests/test_cmd2.py::test_read_input_rawinput_true tests/test_cmd2.py::test_read_input_rawinput_false tests/test_cmd2.py::test_read_command_line_eof tests/test_cmd2.py::test_poutput_string tests/test_cmd2.py::test_poutput_zero tests/test_cmd2.py::test_poutput_empty_string tests/test_cmd2.py::test_poutput_none tests/test_cmd2.py::test_poutput_ansi_always tests/test_cmd2.py::test_poutput_ansi_never tests/test_cmd2.py::test_get_alias_completion_items tests/test_cmd2.py::test_get_macro_completion_items tests/test_cmd2.py::test_get_settable_completion_items tests/test_cmd2.py::test_alias_no_subcommand tests/test_cmd2.py::test_alias_create tests/test_cmd2.py::test_alias_create_with_quoted_value tests/test_cmd2.py::test_alias_create_invalid_name[""] tests/test_cmd2.py::test_alias_create_invalid_name[#] tests/test_cmd2.py::test_alias_create_invalid_name[!no_shortcut] tests/test_cmd2.py::test_alias_create_invalid_name[">"] tests/test_cmd2.py::test_alias_create_invalid_name["no>pe"] tests/test_cmd2.py::test_alias_create_invalid_name["no tests/test_cmd2.py::test_alias_create_invalid_name["nopipe|"] tests/test_cmd2.py::test_alias_create_invalid_name["noterm;"] tests/test_cmd2.py::test_alias_create_invalid_name[noembedded"quotes] tests/test_cmd2.py::test_alias_create_with_command_name tests/test_cmd2.py::test_alias_create_with_macro_name tests/test_cmd2.py::test_alias_that_resolves_into_comment tests/test_cmd2.py::test_alias_list_invalid_alias tests/test_cmd2.py::test_alias_delete tests/test_cmd2.py::test_alias_delete_all tests/test_cmd2.py::test_alias_delete_non_existing tests/test_cmd2.py::test_alias_delete_no_name tests/test_cmd2.py::test_multiple_aliases tests/test_cmd2.py::test_macro_no_subcommand tests/test_cmd2.py::test_macro_create tests/test_cmd2.py::test_macro_create_with_quoted_value tests/test_cmd2.py::test_macro_create_invalid_name[""] tests/test_cmd2.py::test_macro_create_invalid_name[#] tests/test_cmd2.py::test_macro_create_invalid_name[!no_shortcut] tests/test_cmd2.py::test_macro_create_invalid_name[">"] tests/test_cmd2.py::test_macro_create_invalid_name["no>pe"] tests/test_cmd2.py::test_macro_create_invalid_name["no tests/test_cmd2.py::test_macro_create_invalid_name["nopipe|"] tests/test_cmd2.py::test_macro_create_invalid_name["noterm;"] tests/test_cmd2.py::test_macro_create_invalid_name[noembedded"quotes] tests/test_cmd2.py::test_macro_create_with_command_name tests/test_cmd2.py::test_macro_create_with_alias_name tests/test_cmd2.py::test_macro_create_with_args tests/test_cmd2.py::test_macro_create_with_escaped_args tests/test_cmd2.py::test_macro_usage_with_missing_args tests/test_cmd2.py::test_macro_usage_with_exta_args tests/test_cmd2.py::test_macro_create_with_missing_arg_nums tests/test_cmd2.py::test_macro_create_with_invalid_arg_num tests/test_cmd2.py::test_macro_create_with_unicode_numbered_arg tests/test_cmd2.py::test_macro_create_with_missing_unicode_arg_nums tests/test_cmd2.py::test_macro_that_resolves_into_comment tests/test_cmd2.py::test_macro_list_invalid_macro tests/test_cmd2.py::test_macro_delete tests/test_cmd2.py::test_macro_delete_all tests/test_cmd2.py::test_macro_delete_non_existing tests/test_cmd2.py::test_macro_delete_no_name tests/test_cmd2.py::test_multiple_macros tests/test_cmd2.py::test_nonexistent_macro tests/test_cmd2.py::test_perror_style tests/test_cmd2.py::test_perror_no_style tests/test_cmd2.py::test_pwarning_style tests/test_cmd2.py::test_pwarning_no_style tests/test_cmd2.py::test_ppaged tests/test_cmd2.py::test_ppaged_blank tests/test_cmd2.py::test_ppaged_none tests/test_cmd2.py::test_ppaged_strips_ansi_when_redirecting tests/test_cmd2.py::test_ppaged_strips_ansi_when_redirecting_if_always tests/test_cmd2.py::test_parseline_empty tests/test_cmd2.py::test_parseline tests/test_cmd2.py::test_onecmd_raw_str_continue tests/test_cmd2.py::test_onecmd_raw_str_quit tests/test_cmd2.py::test_onecmd_add_to_history tests/test_cmd2.py::test_get_all_commands tests/test_cmd2.py::test_get_help_topics tests/test_cmd2.py::test_get_help_topics_hidden tests/test_cmd2.py::test_exit_code_default tests/test_cmd2.py::test_exit_code_nonzero tests/test_cmd2.py::test_ansi_pouterr_always_tty tests/test_cmd2.py::test_ansi_pouterr_always_notty tests/test_cmd2.py::test_ansi_terminal_tty tests/test_cmd2.py::test_ansi_terminal_notty tests/test_cmd2.py::test_ansi_never_tty tests/test_cmd2.py::test_ansi_never_notty tests/test_cmd2.py::test_disable_and_enable_category tests/test_cmd2.py::test_enable_enabled_command tests/test_cmd2.py::test_disable_fake_command tests/test_cmd2.py::test_disable_command_twice tests/test_cmd2.py::test_disabled_command_not_in_history tests/test_cmd2.py::test_disabled_message_command_name tests/test_cmd2.py::test_startup_script tests/test_cmd2.py::test_startup_script_with_odd_file_names[nothingweird] tests/test_cmd2.py::test_startup_script_with_odd_file_names[has tests/test_cmd2.py::test_startup_script_with_odd_file_names["is_double_quoted"] tests/test_cmd2.py::test_startup_script_with_odd_file_names['is_single_quoted'] tests/test_cmd2.py::test_transcripts_at_init tests/test_transcript.py::test_commands_at_invocation tests/test_transcript.py::test_transcript[bol_eol.txt-False] tests/test_transcript.py::test_transcript[characterclass.txt-False] tests/test_transcript.py::test_transcript[dotstar.txt-False] tests/test_transcript.py::test_transcript[extension_notation.txt-False] tests/test_transcript.py::test_transcript[from_cmdloop.txt-True] tests/test_transcript.py::test_transcript[multiline_no_regex.txt-False] tests/test_transcript.py::test_transcript[multiline_regex.txt-False] tests/test_transcript.py::test_transcript[no_output.txt-False] tests/test_transcript.py::test_transcript[no_output_last.txt-False] tests/test_transcript.py::test_transcript[regex_set.txt-False] tests/test_transcript.py::test_transcript[singleslash.txt-False] tests/test_transcript.py::test_transcript[slashes_escaped.txt-False] tests/test_transcript.py::test_transcript[slashslash.txt-False] tests/test_transcript.py::test_transcript[spaces.txt-False] tests/test_transcript.py::test_transcript[word_boundaries.txt-False] tests/test_transcript.py::test_history_transcript tests/test_transcript.py::test_history_transcript_bad_filename tests/test_transcript.py::test_run_script_record_transcript tests/test_transcript.py::test_parse_transcript_expected[text tests/test_transcript.py::test_parse_transcript_expected[specials tests/test_transcript.py::test_parse_transcript_expected[use tests/test_transcript.py::test_parse_transcript_expected[/tmp tests/test_transcript.py::test_parse_transcript_expected[slash tests/test_transcript.py::test_parse_transcript_expected[not tests/test_transcript.py::test_parse_transcript_expected[/.*/-.*] tests/test_transcript.py::test_parse_transcript_expected[/a{6}/ tests/test_transcript.py::test_parse_transcript_expected[lots tests/test_transcript.py::test_transcript_failure tests/test_transcript.py::test_transcript_no_file
docs/features/misc.rst cmd2/cmd2.py CHANGELOG.md docs/features/initialization.rst
docs/features/misc.rst cmd2/cmd2.py CHANGELOG.md docs/features/initialization.rst