Skip to content

# Initialization

Here is a basic example `cmd2` application which demonstrates many capabilities which you may wish to utilize while initializing the app:

examples/getting_started.py

    #!/usr/bin/env python3
    """A simple example cmd2 application demonstrating many common features.

    Features demonstrated include all of the following:
     1) Colorizing/stylizing output
     2) Using multiline commands
     3) Persistent history
     4) How to run an initialization script at startup
     5) How to group and categorize commands when displaying them in help
     6) Opting-in to using the ipy command to run an IPython shell
     7) Allowing access to your application in py and ipy
     8) Displaying an intro banner upon starting your application
     9) Using a custom prompt
    10) How to make custom attributes settable at runtime.
    11) Shortcuts for commands
    12) Persistent bottom toolbar with realtime status updates
    """

    import pathlib
    import threading
    import time

    from prompt_toolkit.formatted_text import FormattedText
    from rich.style import Style

    import cmd2
    from cmd2 import (
        Color,
        stylize,
    )

    class BasicApp(cmd2.Cmd):
        """Cmd2 application to demonstrate many common features."""

        DEFAULT_CATEGORY = "My Custom Commands"

        def __init__(self) -> None:
            """Initialize the cmd2 application."""
            # Startup script that defines a couple aliases for running shell commands
            alias_script = pathlib.Path(__file__).absolute().parent / ".cmd2rc"

            # Create a shortcut for one of our commands
            shortcuts = cmd2.DEFAULT_SHORTCUTS
            shortcuts.update({"&": "intro"})
            super().__init__(
                auto_suggest=True,
                bottom_toolbar=True,
                include_ipy=True,
                multiline_commands=["echo"],
                persistent_history_file="cmd2_history.dat",
                shortcuts=shortcuts,
                startup_script=str(alias_script),
            )

            # Spawn a background thread to refresh the bottom toolbar twice a second.
            # This is necessary because the toolbar contains a timestamp that we want to keep current.
            self._stop_refresh = False
            self._refresh_thread = threading.Thread(target=self._refresh_bottom_toolbar, daemon=True)
            self._refresh_thread.start()

            # Prints an intro banner once upon application startup
            self.intro = (
                stylize(
                    "Welcome to cmd2!",
                    style=Style(color=Color.GREEN1, bgcolor=Color.GRAY0, bold=True),
                )
                + " Note the full Unicode support:  😇 💩"
                + " and the persistent bottom bar with realtime status updates!"
            )

            # Show this as the prompt when asking for input
            self.prompt = "myapp> "

            # Used as prompt for multiline commands after the first line
            self.continuation_prompt = "... "

            # Allow access to your application in py and ipy via self
            self.self_in_py = True

            # Color to output text in with echo command
            self.foreground_color = Color.CYAN.value

            # Make echo_fg settable at runtime
            fg_colors = [c.value for c in Color]
            self.add_settable(
                cmd2.Settable(
                    "foreground_color",
                    str,
                    "Foreground color to use with echo command",
                    self,
                    choices=fg_colors,
                )
            )

        def get_rprompt(self) -> str | FormattedText | None:
            current_working_directory = pathlib.Path.cwd()
            style = "bg:ansired fg:ansiwhite"
            text = f"cwd={current_working_directory}"
            return FormattedText([(style, text)])

        def _refresh_bottom_toolbar(self) -> None:
            """Background thread target to refresh the bottom toolbar.

            This is a toy example to show how the bottom toolbar can be used to display
            realtime status updates in an otherwise line-oriented command interpreter.
            """
            import contextlib

            from prompt_toolkit.application.current import get_app

            while not self._stop_refresh:
                with contextlib.suppress(Exception):
                    # get_app() will return the currently running prompt-toolkit application
                    app = get_app()
                    if app:
                        app.invalidate()
                time.sleep(0.5)

        def do_intro(self, _: cmd2.Statement) -> None:
            """Display the intro banner."""
            self.poutput(self.intro)

        def do_echo(self, arg: cmd2.Statement) -> None:
            """Multiline command."""
            self.poutput(
                stylize(
                    arg,
                    style=Style(color=self.foreground_color),
                )
            )

    if __name__ == "__main__":
        import sys

        app = BasicApp()
        sys.exit(app.cmdloop())

## Cmd class initializer

A cmd2.Cmd instance or subclass instance is an interactive CLI application framework. There is no good reason to instantiate `Cmd` itself; rather, it's useful as a superclass of a class you define yourself in order to inherit `Cmd`'s methods and encapsulate action methods.

Certain things must be initialized within the `__init__()` method of your class derived from `cmd2.Cmd`(all arguments to `__init__()` are optional):

## `` cmd2.Cmd.__init__

    __init__(completekey=None, stdin=None, stdout=None, *, allow_cli_args=True, allow_clipboard=True, allow_redirection=True, auto_load_commands=False, auto_suggest=True, bottom_toolbar=False, command_sets=None, include_ipy=False, include_py=False, intro='', multiline_commands=None, persistent_history_file='', persistent_history_length=1000, shortcuts=None, silence_startup_script=False, startup_script='', suggest_similar_command=False, terminators=None)

Easy but powerful framework for writing line-oriented command interpreters, extends Python's cmd package.

PARAMETER | DESCRIPTION
--- | ---
`completekey` | name of a completion key, default to 'tab'. (If None or an empty string, 'tab' is used) TYPE: `str | None` DEFAULT: `None`
`stdin` | alternate input file object, if not specified, sys.stdin is used TYPE: `TextIO | None` DEFAULT: `None`
`stdout` | alternate output file object, if not specified, sys.stdout is used TYPE: `TextIO | None` DEFAULT: `None`
`allow_cli_args` | if `True`, then cmd2.Cmd.init will process command line arguments as either commands to be run. This should be set to `False` if your application parses its own command line arguments. TYPE: `bool` DEFAULT: `True`
`allow_clipboard` | If False, cmd2 will disable clipboard interactions TYPE: `bool` DEFAULT: `True`
`allow_redirection` | If `False`, prevent output redirection and piping to shell commands. This parameter prevents redirection and piping, but does not alter parsing behavior. A user can still type redirection and piping tokens, and they will be parsed as such but they won't do anything. TYPE: `bool` DEFAULT: `True`
`auto_load_commands` | If True, cmd2 will check for all subclasses of `CommandSet` that are currently loaded by Python and automatically instantiate and register all commands. If False, CommandSets must be manually installed with `register_command_set`. TYPE: `bool` DEFAULT: `False`
`auto_suggest` | If True, cmd2 will provide fish shell style auto-suggestions based on history. User can press right-arrow key to accept the provided suggestion. TYPE: `bool` DEFAULT: `True`
`bottom_toolbar` | if `True`, then a bottom toolbar will be displayed. TYPE: `bool` DEFAULT: `False`
`command_sets` | Provide CommandSet instances to load during cmd2 initialization. This allows CommandSets with custom constructor parameters to be loaded. This also allows the a set of CommandSets to be provided when `auto_load_commands` is set to False TYPE: `Iterable[CommandSet[Any]] | None` DEFAULT: `None`
`include_ipy` | should the "ipy" command be included for an embedded IPython shell TYPE: `bool` DEFAULT: `False`
`include_py` | should the "py" command be included for an embedded Python shell TYPE: `bool` DEFAULT: `False`
`intro` | introduction to display at startup TYPE: `RenderableType` DEFAULT: `''`
`multiline_commands` | Iterable of commands allowed to accept multi-line input TYPE: `Iterable[str] | None` DEFAULT: `None`
`persistent_history_file` | file path to load a persistent cmd2 command history from TYPE: `str` DEFAULT: `''`
`persistent_history_length` | max number of history items to write to the persistent history file TYPE: `int` DEFAULT: `1000`
`shortcuts` | Mapping containing shortcuts for commands. If not supplied, then defaults to constants.DEFAULT_SHORTCUTS. If you do not want any shortcuts, pass None and an empty dictionary will be created. TYPE: `Mapping[str, str] | None` DEFAULT: `None`
`silence_startup_script` | if `True`, then the startup script's output will be suppressed. Anything written to stderr will still display. TYPE: `bool` DEFAULT: `False`
`startup_script` | file path to a script to execute at startup TYPE: `str` DEFAULT: `''`
`suggest_similar_command` | if `True`, then when a command is not found, cmd2.Cmd will look for similar commands and suggest them. TYPE: `bool` DEFAULT: `False`
`terminators` | Iterable of characters that terminate a command. These are mainly intended for terminating multiline commands, but will also terminate single-line commands. If not supplied, the default is a semicolon. If your app only contains single-line commands and you want terminators to be treated as literals by the parser, then set this to None. TYPE: `Iterable[str] | None` DEFAULT: `None`

Source code in `cmd2/cmd2.py`

    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687

    def __init__(
        self,
        completekey: str | None = None,
        stdin: TextIO | None = None,
        stdout: TextIO | None = None,
        *,
        allow_cli_args: bool = True,
        allow_clipboard: bool = True,
        allow_redirection: bool = True,
        auto_load_commands: bool = False,
        auto_suggest: bool = True,
        bottom_toolbar: bool = False,
        command_sets: Iterable[CommandSet[Any]] | None = None,
        include_ipy: bool = False,
        include_py: bool = False,
        intro: RenderableType = "",
        multiline_commands: Iterable[str] | None = None,
        persistent_history_file: str = "",
        persistent_history_length: int = 1000,
        shortcuts: Mapping[str, str] | None = None,
        silence_startup_script: bool = False,
        startup_script: str = "",
        suggest_similar_command: bool = False,
        terminators: Iterable[str] | None = None,
    ) -> None:
        """Easy but powerful framework for writing line-oriented command interpreters, extends Python's cmd package.

        :param completekey: name of a completion key, default to 'tab'. (If None or an empty string, 'tab' is used)
        :param stdin: alternate input file object, if not specified, sys.stdin is used
        :param stdout: alternate output file object, if not specified, sys.stdout is used
        :param allow_cli_args: if ``True``, then [cmd2.Cmd.__init__][] will process command
                               line arguments as either commands to be run. This should be
                               set to ``False`` if your application parses its own command line
                               arguments.
        :param allow_clipboard: If False, cmd2 will disable clipboard interactions
        :param allow_redirection: If ``False``, prevent output redirection and piping to shell
                                  commands. This parameter prevents redirection and piping, but
                                  does not alter parsing behavior. A user can still type
                                  redirection and piping tokens, and they will be parsed as such
                                  but they won't do anything.
        :param auto_load_commands: If True, cmd2 will check for all subclasses of `CommandSet`
                                   that are currently loaded by Python and automatically
                                   instantiate and register all commands. If False, CommandSets
                                   must be manually installed with `register_command_set`.
        :param auto_suggest: If True, cmd2 will provide fish shell style auto-suggestions
                            based on history. User can press right-arrow key to accept the
                            provided suggestion.
        :param bottom_toolbar: if ``True``, then a bottom toolbar will be displayed.
        :param command_sets: Provide CommandSet instances to load during cmd2 initialization.
                             This allows CommandSets with custom constructor parameters to be
                             loaded.  This also allows the a set of CommandSets to be provided
                             when `auto_load_commands` is set to False
        :param include_ipy: should the "ipy" command be included for an embedded IPython shell
        :param include_py: should the "py" command be included for an embedded Python shell
        :param intro: introduction to display at startup
        :param multiline_commands: Iterable of commands allowed to accept multi-line input
        :param persistent_history_file: file path to load a persistent cmd2 command history from
        :param persistent_history_length: max number of history items to write
                                          to the persistent history file
        :param shortcuts: Mapping containing shortcuts for commands. If not supplied,
                          then defaults to constants.DEFAULT_SHORTCUTS. If you do not want
                          any shortcuts, pass None and an empty dictionary will be created.
        :param silence_startup_script: if ``True``, then the startup script's output will be
                                       suppressed. Anything written to stderr will still display.
        :param startup_script: file path to a script to execute at startup
        :param suggest_similar_command: if ``True``, then when a command is not found,
                                        [cmd2.Cmd][] will look for similar commands and suggest them.
        :param terminators: Iterable of characters that terminate a command. These are mainly
                            intended for terminating multiline commands, but will also
                            terminate single-line commands. If not supplied, the default
                            is a semicolon. If your app only contains single-line commands
                            and you want terminators to be treated as literals by the parser,
                            then set this to None.
        """
        # Check if py or ipy need to be disabled in this instance
        if not include_py:
            setattr(self, "do_py", None)  # noqa: B010
        if not include_ipy:
            setattr(self, "do_ipy", None)  # noqa: B010

        # initialize plugin system
        # needs to be done before we most of the other stuff below
        self._initialize_plugin_system()

        # Configure a few defaults
        self.prompt: str = self.DEFAULT_PROMPT
        self.intro = intro

        if not completekey:
            completekey = self.DEFAULT_COMPLETEKEY

        # What to use for standard input
        if stdin is not None:
            self.stdin = stdin
        else:
            self.stdin = sys.stdin

        # Standard output stream. The interactive UI remains attached to this initial
        # stream even when self.stdout is temporarily swapped during command output
        # redirection.
        if stdout is not None:
            self.stdout = stdout
        else:
            self.stdout = sys.stdout

        # Attributes which should NOT be dynamically settable via the set command at runtime
        self.allow_redirection = allow_redirection  # Security setting to prevent redirection of stdout

        # If True, cmd2 treats redirected input (pipes/files) as an interactive session.
        # It will display the prompt before reading each line to synchronize with
        # automation tools (like Pexpect) and will skip echoing the input to prevent
        # duplicate prompts in the output.
        self.interactive_pipe = False

        # Attributes which ARE dynamically settable via the set command at runtime
        self.debug = False
        self.echo = False
        self.editor = self.DEFAULT_EDITOR
        self.quiet = False  # Do not suppress nonessential output
        self.scripts_add_to_history = True  # Scripts and pyscripts add commands to history
        self.timing = False  # Prints elapsed time for each command

        # Default settings for Rich tracebacks created by format_exception().
        # This dictionary can contain any parameter accepted by the
        # rich.traceback.Traceback class. You can modify it to adjust
        # the detail and layout of tracebacks.
        self.traceback_kwargs: dict[str, Any] = {
            "width": 100,
            "code_width": None,  # Show all code characters
            "show_locals": False,
            "max_frames": 100,
            "word_wrap": True,  # Wrap long lines of code instead of truncate
            "indent_guides": True,
        }

        # Cached Rich consoles used by core print methods.
        self._console_cache = _ConsoleCache()

        # The maximum number of items to display in a completion table. If the number of completion
        # suggestions exceeds this number, then no table will appear.
        self.max_completion_table_items: int = 50

        # The maximum number of completion results to display in a single column (CompleteStyle.COLUMN).
        # If the number of results exceeds this, CompleteStyle.MULTI_COLUMN will be used.
        self.max_column_completion_results: int = 7

        # A dictionary mapping settable names to their Settable instance
        self._settables: dict[str, Settable] = {}
        self._always_prefix_settables: bool = False

        # CommandSet containers
        self._installed_command_sets: set[CommandSet[Any]] = set()
        self._cmd_to_command_sets: dict[str, CommandSet[Any]] = {}

        self.build_settables()

        # Use as prompt for multiline commands on the 2nd+ line of input
        self.continuation_prompt: str = "> "

        # Allow access to your application in embedded Python shells and pyscripts via self
        self.self_in_py = False

        # Commands to exclude from the help menu and completion
        self.hidden_commands = ["_eof", "_relative_run_script"]

        # Initialize history from a persistent history file (if present)
        self.persistent_history_file = ""
        self._persistent_history_length = persistent_history_length
        self._initialize_history(persistent_history_file)

        # Create the main PromptSession
        self.bottom_toolbar = bottom_toolbar
        self.main_session = self._create_main_session(auto_suggest, completekey)

        # The session currently holding focus (either the main REPL or a command's
        # custom prompt). Completion and UI logic should reference this variable
        # to ensure they modify the correct session state.
        self.active_session = self.main_session

        # Commands to exclude from the history command
        self.exclude_from_history = ["_eof", "history"]

        # Dictionary of macro names and their values
        self.macros: dict[str, Macro] = {}

        # Keeps track of typed command history in the Python shell
        self._py_history: list[str] = []

        # The name by which Python environments refer to the PyBridge to call app commands
        self.py_bridge_name = "app"

        # Defines app-specific variables/functions available in Python shells and pyscripts
        self.py_locals: dict[str, Any] = {}

        # True if running inside a Python shell or pyscript, False otherwise
        self._in_py = False

        self.statement_parser: StatementParser = StatementParser(
            terminators=terminators, multiline_commands=multiline_commands, shortcuts=shortcuts
        )

        # Stores results from the last command run to enable usage of results in Python shells and pyscripts
        self.last_result: Any = None

        # Used by run_script command to store current script dir as a LIFO queue to support _relative_run_script command
        self._script_dir: list[str] = []

        # Context manager used to protect critical sections in the main thread from stopping due to a KeyboardInterrupt
        self.sigint_protection: utils.ContextFlag = utils.ContextFlag()

        # If the current command created a process to pipe to, then this will be a ProcReader object.
        # Otherwise it will be None. It's used to know when a pipe process can be killed and/or waited upon.
        self._cur_pipe_proc_reader: utils.ProcReader | None = None

        # Used to keep track of whether we are redirecting or piping output
        self._redirecting = False

        # Set text which prints right before all of the help tables are listed.
        self.doc_leader = ""

        # The error that prints when no help information can be found
        self.help_error = "No help on {}"

        # The error that prints when a non-existent command is run
        self.default_error = "{} is not a recognized command, alias, or macro."

        # If non-empty, this string will be displayed if a broken pipe error occurs
        self.broken_pipe_warning = ""

        # Commands that will run at the beginning of the command loop
        self._startup_commands: list[str] = []

        # Store initial termios settings to restore after each command.
        # This is a faster way of accomplishing what "stty sane" does.
        self._initial_termios_settings = None
        if not sys.platform.startswith("win") and self.stdin.isatty():
            try:
                import io
                import termios

                self._initial_termios_settings = termios.tcgetattr(self.stdin.fileno())
            except (ImportError, io.UnsupportedOperation, termios.error):
                # This can happen if termios isn't available or stdin is a pseudo-TTY
                self._initial_termios_settings = None

        # If a startup script is provided and exists, then execute it in the startup commands
        if startup_script:
            startup_script = os.path.abspath(os.path.expanduser(startup_script))
            if os.path.exists(startup_script):
                script_cmd = f"run_script {su.quote(startup_script)}"
                if silence_startup_script:
                    script_cmd += f" {constants.REDIRECTION_OVERWRITE} {os.devnull}"
                self._startup_commands.append(script_cmd)

        # Check for command line args
        if allow_cli_args:
            parser = argparse_utils.DEFAULT_ARGUMENT_PARSER()
            _callopts, callargs = parser.parse_known_args()

            # If commands were supplied at invocation, then add them to the command queue
            if callargs:
                self._startup_commands.extend(callargs)

        # Set the pager(s) for use when displaying output using a pager
        if sys.platform.startswith("win"):
            self.pager = self.pager_chop = "more"
        else:
            # Here is the meaning of the various flags we are using with the less command:
            # -S causes lines longer than the screen width to be chopped (truncated) rather than wrapped
            # -R causes ANSI "style" escape sequences to be output in raw form (i.e. colors are displayed)
            # -X disables sending the termcap initialization and deinitialization strings to the terminal
            # -F causes less to automatically exit if the entire file can be displayed on the first screen
            self.pager = "less -RXF"
            self.pager_chop = "less -SRXF"

        # This boolean flag stores whether cmd2 will allow clipboard related features
        self.allow_clipboard = allow_clipboard

        # This determines the value returned by cmdloop() when exiting the application
        self.exit_code = 0

        # Commands disabled during specific application states
        # Key: Command name | Value: DisabledCommand object
        # NOTE: Use disable_command() and enable_command() to modify this dictionary.
        self.disabled_commands: dict[str, DisabledCommand] = {}

        # Categories of commands to be disabled
        # Key: Category name | Value: Message to display
        # NOTE: Use disable_category() and enable_category() to modify this dictionary.
        self.disabled_categories: dict[str, str] = {}

        # Command parsers for this Cmd instance.
        self.command_parsers: CommandParsers = CommandParsers(self)

        # Members related to printing asynchronous alerts
        self._alert_queue: deque[AsyncAlert] = deque()
        self._alert_condition = threading.Condition()
        self._alert_allowed = False
        self._alert_shutdown = False
        self._alert_thread: threading.Thread | None = None
        self._alert_prompt_timestamp: float = 0.0  # Uses time.monotonic()

        # Add functions decorated to be subcommands
        self._register_subcommands(self)

        ############################################################################################################
        # The following code block loads CommandSets, verifies command names, and registers subcommands.
        # This block should appear after all attributes have been created since the registration code
        # depends on them and it's possible a module's on_register() method may need to access some.
        ############################################################################################################
        # Load modular commands
        if command_sets:
            for command_set in command_sets:
                self.register_command_set(command_set)

        if auto_load_commands:
            self._autoload_commands()

        # Verify commands don't have invalid names (like starting with a shortcut)
        for cur_cmd in self.get_all_commands():
            valid, errmsg = self.statement_parser.is_valid_command(cur_cmd)
            if not valid:
                raise ValueError(f"Invalid command name '{cur_cmd}': {errmsg}")

        self.suggest_similar_command = suggest_similar_command
        self.default_suggestion_message = "Did you mean {}?"

        # the current command being executed
        self.current_command: Statement | None = None

## Cmd class variables

The `cmd2.Cmd` class provides several class-level variables that can be overridden in subclasses to change default behavior across all instances of that class.

- DEFAULT_CATEGORY: The default help category for commands defined in the class which haven't been explicitly categorized. (Default: `"Cmd2 Commands"`)
- DEFAULT_EDITOR: The default editor program used by the `edit` command.
- DEFAULT_PROMPT: The default prompt string. (Default: `"(Cmd) "`)
- MISC_HEADER: Header for the help section listing miscellaneous help topics. (Default: `"Miscellaneous Help Topics"`)

## Cmd instance attributes

The `cmd2.Cmd` class provides a large number of public instance attributes which allow developers to customize a `cmd2` application further beyond the options provided by the `__init__()` method.

### Public instance attributes

Here are instance attributes of `cmd2.Cmd` which developers might wish to override:

- bottom_toolbar: if `True`, then a bottom toolbar will be displayed (Default: `False`)
- broken_pipe_warning: if non-empty, this string will be displayed if a broken pipe error occurs
- continuation_prompt: used for multiline commands on 2nd+ line of input
- debug: if `True`, show full stack trace on error (Default: `False`)
- default_error: the error that prints when a non-existent command is run
- disabled_commands: commands that have been disabled from use. This is to support commands that are only available during specific states of the application. This dictionary's keys are the command names and its values are DisabledCommand objects.
- echo: if `True`, each command the user issues will be repeated to the screen before it is executed. This is particularly useful when running scripts. This behavior does not occur when running a command at the prompt. (Default: `False`)
- editor: text editor program to use with edit command (e.g. `vim`)
- exclude_from_history: commands to exclude from the history command
- exit_code: this determines the value returned by `cmdloop()` when exiting the application
- help_error: the error that prints when no help information can be found
- hidden_commands: commands to exclude from the help menu and tab completion
- last_result: stores results from the last command run to enable usage of results in a Python script or interactive console. Built-in commands don't make use of this. It is purely there for user-defined commands and convenience.
- macros: dictionary of macro names and their values
- max_column_completion_results: The maximum number of completion results to display in a single column (Default: 7)
- max_completion_table_items: The maximum number of completion results allowed for a completion table to appear (Default: 50)
- pager: sets the pager command used by the `Cmd.ppaged()` method for displaying wrapped output using a pager
- pager_chop: sets the pager command used by the `Cmd.ppaged()` method for displaying chopped/truncated output using a pager
- py_bridge_name: name by which embedded Python environments and scripts refer to the `cmd2` application by in order to call commands (Default: `app`)
- py_locals: dictionary that defines specific variables/functions available in Python shells and scripts (provides more fine-grained control than making everything available with self_in_py)
- quiet: if `True`, then completely suppress nonessential output (Default: `False`)
- scripts_add_to_history: if `True`, scripts and pyscripts add commands to history (Default: `True`)
- self_in_py: if `True`, allow access to your application in py command via `self` (Default: `False`)
- 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: `False`)