diff options
-rw-r--r-- | docs/examples/alternate_event_loops.rst | 82 | ||||
-rw-r--r-- | docs/examples/index.rst | 2 | ||||
-rw-r--r-- | docs/examples/removing_builtin_commands.rst | 7 | ||||
-rw-r--r-- | docs/features/commands.rst | 43 | ||||
-rw-r--r-- | docs/features/completion.rst | 31 | ||||
-rw-r--r-- | docs/features/embedded_python_shells.rst | 8 | ||||
-rw-r--r-- | docs/features/generating_output.rst | 60 | ||||
-rw-r--r-- | docs/features/history.rst | 7 | ||||
-rw-r--r-- | docs/features/misc.rst | 179 | ||||
-rw-r--r-- | docs/features/os.rst | 75 | ||||
-rw-r--r-- | docs/features/scripting.rst | 52 | ||||
-rw-r--r-- | docs/features/settings.rst | 95 | ||||
-rw-r--r-- | docs/features/shortcuts_aliases_macros.rst | 82 | ||||
-rw-r--r-- | docs/features/transcripts.rst | 6 | ||||
-rw-r--r-- | docs/freefeatures.rst | 136 | ||||
-rw-r--r-- | docs/index.rst | 21 | ||||
-rw-r--r-- | docs/integrating.rst | 164 | ||||
-rw-r--r-- | docs/settingchanges.rst | 194 | ||||
-rw-r--r-- | docs/unfreefeatures.rst | 231 |
19 files changed, 712 insertions, 763 deletions
diff --git a/docs/examples/alternate_event_loops.rst b/docs/examples/alternate_event_loops.rst new file mode 100644 index 00000000..317ebd9f --- /dev/null +++ b/docs/examples/alternate_event_loops.rst @@ -0,0 +1,82 @@ +Alternate Event Loops +===================== + +Throughout this documentation we have focused on the **90%** use case, that is +the use case we believe around **90+%** of our user base is looking for. This +focuses on ease of use and the best out-of-the-box experience where developers +get the most functionality for the least amount of effort. We are talking +about running cmd2 applications with the ``cmdloop()`` method:: + + from cmd2 import Cmd + class App(Cmd): + # customized attributes and methods here + app = App() + app.cmdloop() + +However, there are some limitations to this way of using ``cmd2``, mainly that +``cmd2`` owns the inner loop of a program. This can be unnecessarily +restrictive and can prevent using libraries which depend on controlling their +own event loop. + +Many Python concurrency libraries involve or require an event loop which they +are in control of such as asyncio_, gevent_, Twisted_, etc. + +.. _asyncio: https://docs.python.org/3/library/asyncio.html +.. _gevent: http://www.gevent.org/ +.. _Twisted: https://twistedmatrix.com + +``cmd2`` applications can be executed in a fashion where ``cmd2`` doesn't own +the main loop for the program by using code like the following:: + + import cmd2 + + class Cmd2EventBased(cmd2.Cmd): + def __init__(self): + cmd2.Cmd.__init__(self) + + # ... your class code here ... + + if __name__ == '__main__': + app = Cmd2EventBased() + app.preloop() + + # Do this within whatever event loop mechanism you wish to run a single command + cmd_line_text = "help history" + app.runcmds_plus_hooks([cmd_line_text]) + + app.postloop() + +The **runcmds_plus_hooks()** method is a convenience method to run multiple +commands via **onecmd_plus_hooks()**. + +The **onecmd_plus_hooks()** method will do the following to execute a single +``cmd2`` command in a normal fashion: + +#. Parse user input into `Statement` object +#. Call methods registered with `register_postparsing_hook()` +#. Redirect output, if user asked for it and it's allowed +#. Start timer +#. Call methods registered with `register_precmd_hook()` +#. Call `precmd()` - for backwards compatibility with ``cmd.Cmd`` +#. Add statement to history +#. Call `do_command` method +#. Call methods registered with `register_postcmd_hook()` +#. Call `postcmd(stop, statement)` - for backwards compatibility with + ``cmd.Cmd`` +#. Stop timer and display the elapsed time +#. Stop redirecting output if it was redirected +#. Call methods registered with `register_cmdfinalization_hook()` + +Running in this fashion enables the ability to integrate with an external event +loop. However, how to integrate with any specific event loop is beyond the +scope of this documentation. Please note that running in this fashion comes +with several disadvantages, including: + +* Requires the developer to write more code +* Does not support transcript testing +* Does not allow commands at invocation via command-line arguments + +Here is a little more info on ``runcmds_plus_hooks``: + +.. automethod:: cmd2.cmd2.Cmd.runcmds_plus_hooks + :noindex: diff --git a/docs/examples/index.rst b/docs/examples/index.rst index 2070b7a3..65cb475f 100644 --- a/docs/examples/index.rst +++ b/docs/examples/index.rst @@ -5,3 +5,5 @@ Examples :maxdepth: 1 first_app + removing_builtin_commands + alternate_event_loops diff --git a/docs/examples/removing_builtin_commands.rst b/docs/examples/removing_builtin_commands.rst new file mode 100644 index 00000000..63f5160a --- /dev/null +++ b/docs/examples/removing_builtin_commands.rst @@ -0,0 +1,7 @@ +Removing Builtin Commands +========================= + +Show how to remove built in comamnds. Say for example you don't like the +``quit`` command included in ``cmd2``. Your application has to subclass +``cmd2.Cmd`` to work, which means you inherit the ``quit`` command. Here's how +to remove it. diff --git a/docs/features/commands.rst b/docs/features/commands.rst index 3eec2373..6a8fedee 100644 --- a/docs/features/commands.rst +++ b/docs/features/commands.rst @@ -1,4 +1,47 @@ Commands ======== +.. _cmd: https://docs.python.org/3/library/cmd.html + How to create a command with a ``do_command`` method, + +Parsed statements +----------------- + +``cmd2`` passes ``arg`` to a ``do_`` method (or ``default``) as a Statement, a +subclass of string that includes many attributes of the parsed input: + +command + Name of the command called + +args + The arguments to the command with output redirection + or piping to shell commands removed + +command_and_args + A string of just the command and the arguments, with + output redirection or piping to shell commands removed + +argv + A list of arguments a-la ``sys.argv``, including + the command as ``argv[0]`` and the subsequent + arguments as additional items in the list. + Quotes around arguments will be stripped as will + any output redirection or piping portions of the command + +raw + Full input exactly as typed. + +terminator + Character used to end a multiline command + + + +If ``Statement`` does not contain an attribute, querying for it will return +``None``. + +(Getting ``arg`` as a ``Statement`` is technically "free", in that it requires +no application changes from the cmd_ standard, but there will be no result +unless you change your application to *use* any of the additional attributes.) + + diff --git a/docs/features/completion.rst b/docs/features/completion.rst index c89b24cc..5d2a722c 100644 --- a/docs/features/completion.rst +++ b/docs/features/completion.rst @@ -1,4 +1,33 @@ Completion ========== -How tab completion works and how to implement it in your own project +``cmd2`` adds tab-completion of file system paths for all built-in commands +where it makes sense, including: + +- ``edit`` +- ``run_pyscript`` +- ``run_script`` +- ``shell`` + +``cmd2`` also adds tab-completion of shell commands to the ``shell`` command. + +Additionally, it is trivial to add identical file system path completion to +your own custom commands. Suppose you have defined a custom command ``foo`` by +implementing the ``do_foo`` method. To enable path completion for the ``foo`` +command, then add a line of code similar to the following to your class which +inherits from ``cmd2.Cmd``:: + + complete_foo = self.path_complete + +This will effectively define the ``complete_foo`` readline completer method in +your class and make it utilize the same path completion logic as the built-in +commands. + +The built-in logic allows for a few more advanced path completion capabilities, +such as cases where you only want to match directories. Suppose you have a +custom command ``bar`` implemented by the ``do_bar`` method. You can enable +path completion of directories only for this command by adding a line of code +similar to the following to your class which inherits from ``cmd2.Cmd``:: + + # Make sure you have an "import functools" somewhere at the top + complete_bar = functools.partialmethod(cmd2.Cmd.path_complete, path_filter=os.path.isdir) diff --git a/docs/features/embedded_python_shells.rst b/docs/features/embedded_python_shells.rst index 7e8c027b..6d00536a 100644 --- a/docs/features/embedded_python_shells.rst +++ b/docs/features/embedded_python_shells.rst @@ -61,10 +61,10 @@ the application:: The ``py`` command also allows you to run Python scripts via ``py run('myscript.py')``. This provides a more complicated and more powerful scripting capability than that provided by the simple text file scripts -discussed in :ref:`scripts`. Python scripts can include conditional control -flow logic. See the **python_scripting.py** ``cmd2`` application and the -**script_conditional.py** script in the ``examples`` source code directory for -an example of how to achieve this in your own applications. +discussed in :ref:`features/scripting:Scripting`. Python scripts can include +conditional control flow logic. See the **python_scripting.py** ``cmd2`` +application and the **script_conditional.py** script in the ``examples`` source +code directory for an example of how to achieve this in your own applications. Using ``py`` to run scripts directly is considered deprecated. The newer ``run_pyscript`` command is superior for doing this in two primary ways: diff --git a/docs/features/generating_output.rst b/docs/features/generating_output.rst index 5813322b..c03f8778 100644 --- a/docs/features/generating_output.rst +++ b/docs/features/generating_output.rst @@ -9,6 +9,39 @@ how to generate output - exceptions - color support +Standard ``cmd`` applications produce their output with +``self.stdout.write('output')`` (or with ``print``, but ``print`` decreases +output flexibility). ``cmd2`` applications can use ``self.poutput('output')``, +``self.pfeedback('message')``, ``self.perror('errmsg')``, and +``self.ppaged('text')`` instead. These methods have these advantages: + +- Handle output redirection to file and/or pipe appropriately +- More concise + - ``.pfeedback()`` destination is controlled by ``quiet`` parameter. +- Option to display long output using a pager via ``ppaged()`` + +.. automethod:: cmd2.cmd2.Cmd.poutput + :noindex: +.. automethod:: cmd2.cmd2.Cmd.perror + :noindex: +.. automethod:: cmd2.cmd2.Cmd.pfeedback + :noindex: +.. automethod:: cmd2.cmd2.Cmd.ppaged + :noindex: + + +Suppressing non-essential output +-------------------------------- + +The ``quiet`` setting controls whether ``self.pfeedback()`` actually produces +any output. If ``quiet`` is ``False``, then the output will be produced. If +``quiet`` is ``True``, no output will be produced. + +This makes ``self.pfeedback()`` useful for non-essential output like status +messages. Users can control whether they would like to see these messages by +changing the value of the ``quiet`` setting. + + Output Redirection ------------------ @@ -43,3 +76,30 @@ If you need to include any of these redirection characters in your command, you can enclose them in quotation marks, ``mycommand 'with > in the argument'``. +Colored Output +-------------- + +The output methods in the previous section all honor the ``allow_ansi`` +setting, which has three possible values: + +Never + poutput(), pfeedback(), and ppaged() strip all ANSI escape sequences + which instruct the terminal to colorize output + +Terminal + (the default value) poutput(), pfeedback(), and ppaged() do not strip any + ANSI escape sequences when the output is a terminal, but if the output is a + pipe or a file the escape sequences are stripped. If you want colorized + output you must add ANSI escape sequences using either cmd2's internal ansi + module or another color library such as `plumbum.colors`, `colorama`, or + `colored`. + +Always + poutput(), pfeedback(), and ppaged() never strip ANSI escape sequences, + regardless of the output destination + +Colored and otherwise styled output can be generated using the `ansi.style()` +function: + +.. automethod:: cmd2.ansi.style + diff --git a/docs/features/history.rst b/docs/features/history.rst index 1a163c80..c1806065 100644 --- a/docs/features/history.rst +++ b/docs/features/history.rst @@ -160,9 +160,10 @@ would:: (Cmd) history --edit 2:4 If you want to save the commands to a text file, but not edit and re-run them, -use the ``-o`` or ``--output_file`` option. This is a great way to create -:ref:`scripts`, which can be executed using the ``run_script`` command. To -save the first 5 commands entered in this session to a text file:: +use the ``-o`` or ``--output-file`` option. This is a great way to create +:ref:`Scripts <features/scripting:Scripting>`, which can be executed using the +``run_script`` command. To save the first 5 commands entered in this session to +a text file:: (Cmd) history :5 -o history.txt diff --git a/docs/features/misc.rst b/docs/features/misc.rst index 4db9f682..92ab7537 100644 --- a/docs/features/misc.rst +++ b/docs/features/misc.rst @@ -12,4 +12,181 @@ each command to execute. Exiting ------- -Mention quit, exit, and EOF handling built into ``cmd2``. +Mention quit, and EOF handling built into ``cmd2``. + + +Shell Command +------------- + +``cmd2`` includes a ``shell`` command which executes it's arguments in the +operating system shell:: + + (Cmd) shell ls -al + +If you use the default :ref:`features/shortcuts_aliases_macros:Shortcuts` +defined in ``cmd2`` you'll get a ``!`` shortcut for ``shell``, which allows you +to type:: + + (Cmd) !ls -al + + +Commands At Invocation +---------------------- + +.. _Argparse: https://docs.python.org/3/library/argparse.html + +You can send commands to your app as you invoke it by including them as extra +arguments to the program. ``cmd2`` interprets each argument as a separate +command, so you should enclose each command in quotation marks if it is more +than a one-word command. + +.. code-block:: shell + + $ python examples/example.py "say hello" "say Gracie" quit + hello + Gracie + + +.. note:: + + If you wish to disable cmd2's consumption of command-line arguments, you can + do so by setting the ``allow_cli_args`` argument of your ``cmd2.Cmd`` class + instance to ``False``. This would be useful, for example, if you wish to + use something like Argparse_ to parse the overall command line arguments for + your application:: + + from cmd2 import Cmd + class App(Cmd): + def __init__(self): + super().__init__(allow_cli_args=False) + + +Initialization Script +--------------------- + +.. _AliasStartup: https://github.com/python-cmd2/cmd2/blob/master/examples/alias_startup.py + +You can execute commands from an initialization script by passing a file +path to the ``startup_script`` argument to the ``cmd2.Cmd.__init__()`` method +like so:: + + class StartupApp(cmd2.Cmd): + def __init__(self): + cmd2.Cmd.__init__(self, startup_script='.cmd2rc') + +This text file should contain a :ref:`Command Script +<features/scripting:Command Scripts>`. See the AliasStartup_ example for a +demonstration. + + +select +------ + +Presents numbered options to user, as bash ``select``. + +``app.select`` is called from within a method (not by the user directly; it is +``app.select``, not ``app.do_select``). + +.. automethod:: cmd2.cmd2.Cmd.select + :noindex: + +:: + + def do_eat(self, arg): + sauce = self.select('sweet salty', 'Sauce? ') + result = '{food} with {sauce} sauce, yum!' + result = result.format(food=arg, sauce=sauce) + self.stdout.write(result + '\n') + +:: + + (Cmd) eat wheaties + 1. sweet + 2. salty + Sauce? 2 + wheaties with salty sauce, yum! + + +Disabling Commands +------------------ + +``cmd2`` supports disabling commands during runtime. This is useful if certain +commands should only be available when the application is in a specific state. +When a command is disabled, it will not show up in the help menu or tab +complete. If a user tries to run the command, a command-specific message +supplied by the developer will be printed. The following functions support this +feature. + +enable_command() + Enable an individual command + +enable_category() + Enable an entire category of commands + +disable_command() + Disable an individual command and set the message that will print when this + command is run or help is called on it while disabled + +disable_category() + Disable an entire category of commands and set the message that will print + when anything in this category is run or help is called on it while + disabled + +See the definitions of these functions for descriptions of their arguments. + +See the ``do_enable_commands()`` and ``do_disable_commands()`` functions in the +HelpCategories_ example for a demonstration. + +.. _HelpCategories: https://github.com/python-cmd2/cmd2/blob/master/examples/help_categories.py + + +Exit code +--------- + +The ``self.exit_code`` attribute of your ``cmd2`` application controls what +exit code is returned from ``cmdloop()`` when it completes. It is your job to +make sure that this exit code gets sent to the shell when your application +exits by calling ``sys.exit(app.cmdloop())``. + + +Default to shell +---------------- + +Every ``cmd2`` application can execute operating-system level (shell) commands +with ``shell`` or a ``!`` shortcut:: + + (Cmd) shell which python + /usr/bin/python + (Cmd) !which python + /usr/bin/python + +However, if the parameter ``default_to_shell`` is ``True``, then *every* +command will be attempted on the operating system. Only if that attempt fails +(i.e., produces a nonzero return value) will the application's own ``default`` +method be called. + +:: + + (Cmd) which python + /usr/bin/python + (Cmd) my dog has fleas + sh: my: not found + *** Unknown syntax: my dog has fleas + + +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. + +:: + + (Cmd) typing a comma^C + (Cmd) + +.. warning:: + The default SIGINT behavior will only function properly if **cmdloop** is running + in the main thread. diff --git a/docs/features/os.rst b/docs/features/os.rst index 780e99f2..40a7cbf4 100644 --- a/docs/features/os.rst +++ b/docs/features/os.rst @@ -9,3 +9,78 @@ Integrating with the OS - Automation and calling cmd2 from other CLI/CLU tools via commands at invocation and quit + +Invoking With Arguments +----------------------- + +Typically you would invoke a ``cmd2`` program by typing:: + + $ python mycmd2program.py + +or:: + + $ mycmd2program.py + +Either of these methods will launch your program and enter the ``cmd2`` command +loop, which allows the user to enter commands, which are then executed by your +program. + +You may want to execute commands in your program without prompting the user for +any input. There are several ways you might accomplish this task. The easiest +one is to pipe commands and their arguments into your program via standard +input. You don't need to do anything to your program in order to use this +technique. Here's a demonstration using the ``examples/example.py`` included in +the source code of ``cmd2``:: + + $ echo "speak -p some words" | python examples/example.py + omesay ordsway + +Using this same approach you could create a text file containing the commands +you would like to run, one command per line in the file. Say your file was +called ``somecmds.txt``. To run the commands in the text file using your +``cmd2`` program (from a Windows command prompt):: + + c:\cmd2> type somecmds.txt | python.exe examples/example.py + omesay ordsway + +By default, ``cmd2`` programs also look for commands pass as arguments from the +operating system shell, and execute those commands before entering the command +loop:: + + $ python examples/example.py help + + Documented commands (type help <topic>): + ======================================== + alias help macro orate quit run_script set shortcuts + edit history mumble py run_pyscript say shell speak + + (Cmd) + +You may need more control over command line arguments passed from the operating +system shell. For example, you might have a command inside your ``cmd2`` +program which itself accepts arguments, and maybe even option strings. Say you +wanted to run the ``speak`` command from the operating system shell, but have +it say it in pig latin:: + + $ python example/example.py speak -p hello there + python example.py speak -p hello there + usage: speak [-h] [-p] [-s] [-r REPEAT] words [words ...] + speak: error: the following arguments are required: words + *** Unknown syntax: -p + *** Unknown syntax: hello + *** Unknown syntax: there + (Cmd) + +Uh-oh, that's not what we wanted. ``cmd2`` treated ``-p``, ``hello``, and +``there`` as commands, which don't exist in that program, thus the syntax +errors. + +There is an easy way around this, which is demonstrated in +``examples/cmd_as_argument.py``. By setting ``allow_cli_args=False`` you can so +your own argument parsing of the command line:: + + $ python examples/cmd_as_argument.py speak -p hello there + ellohay heretay + +Check the source code of this example, especially the ``main()`` function, to +see the technique. diff --git a/docs/features/scripting.rst b/docs/features/scripting.rst index 73566cde..52fab405 100644 --- a/docs/features/scripting.rst +++ b/docs/features/scripting.rst @@ -1,20 +1,62 @@ Scripting ========= -Document use cases and commands for ``run_script`` and ``run_pyscript`` +Operating system shells have long had the ability to execute a sequence of +commands saved in a text file. These script files make long sequences of +commands easier to repeatedly execute. ``cmd2`` supports two similar +mechanisms: command scripts and python scripts. + + +Command Scripts +--------------- + +A command script contains a sequence of commands typed at the the prompt of a +``cmd2`` based application. Unlike operating system shell scripts, command +scripts can't contain logic or loops. + + +Creating Command Scripts +~~~~~~~~~~~~~~~~~~~~~~~~ + +Command scripts can be created in several ways: + +- creating a text file using any method of your choice +- using the built-in ``edit`` command to create or edit an existing text file +- saving previously entered commands to a script file using ``history -s``. See + :ref:`features/history:History` for more details. + +If you create create a text file from scratch, just include one command per +line, exactly as you would type it inside a ``cmd2`` application. + + +Running Command Scripts +~~~~~~~~~~~~~~~~~~~~~~~ + +Command script files can be executed using the built-in ``run_script`` command. +Both ASCII and UTF-8 encoded unicode text files are supported. + Comments --------- +~~~~~~~~ Any command line input where the first non-whitespace character is a `#` will be treated as a comment. This means any `#` character appearing later in the command will be treated as a literal. The same applies to a `#` in the middle of a multiline command, even if it is the first character on a line. -Comments can be useful in :ref:`scripts`, but would be pointless within an -interactive session. +Comments are useful in scripts, but would be pointless within an interactive +session. :: (Cmd) # this is a comment - (Cmd) this # is not a comment + (Cmd) command # this is not a comment + + +Python Scripts +-------------- + +If you require logic flow, loops, branching, or other advanced features, you +can write a python script which executes in the context of your ``cmd2`` app. +This script is run using the ``run_pyscript`` command. See +:ref:`features/embedded_python_shells:Embedded Python Shells`. diff --git a/docs/features/settings.rst b/docs/features/settings.rst index 696b085f..21d5a9ee 100644 --- a/docs/features/settings.rst +++ b/docs/features/settings.rst @@ -4,3 +4,98 @@ Settings - current settings and what they do - how a developer can add their own - how to hide built in settings from a user + +Built In Settings +----------------- + +``cmd2`` has a number of built in settings, which a developer can set a default +value, and which users can modify to change the behavior of the application. + + +Timing +~~~~~~ + +Setting ``App.timing`` to ``True`` outputs timing data after every application +command is executed. |settable| + + +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. + + +Debug +~~~~~ + +Setting ``App.debug`` to ``True`` will produce detailed error stacks whenever +the application generates an error. |settable| + +.. |settable| replace:: The user can ``set`` this parameter + during application execution. + (See :ref:`parameters`) + +.. _parameters: + +Other user-settable parameters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A list of all user-settable parameters, with brief +comments, is viewable from within a running application +with:: + + (Cmd) set --long + allow_ansi: Terminal # Allow ANSI escape sequences in output (valid values: Terminal, Always, Never) + continuation_prompt: > # On 2nd+ line of input + debug: False # Show full error stack on error + echo: False # Echo command issued into output + editor: vim # Program used by ``edit`` + feedback_to_output: False # include nonessentials in `|`, `>` results + locals_in_py: False # Allow access to your application in py via self + prompt: (Cmd) # The prompt issued to solicit input + quiet: False # Don't print nonessential feedback + timing: False # Report execution times + +Any of these user-settable parameters can be set while running your app with +the ``set`` command like so:: + + set allow_ansi Never + + + +Create New Settings +------------------- + +Your application can define user-settable parameters which your code can +reference. First create a class attribute with the default value. Then update +the ``settable`` dictionary with your setting name and a short description +before you initialize the superclass. Here's an example, from +``examples/environment.py``: + +.. literalinclude:: ../../examples/environment.py + +If you want to be notified when a setting changes (as we do above), then define +a method ``_onchange_{setting}()``. This method will be called after the user +changes a setting, and will receive both the old value and the new value. + +.. code-block:: text + + (Cmd) set --long | grep sunny + sunny: False # Is it sunny outside? + (Cmd) set --long | grep degrees + degrees_c: 22 # Temperature in Celsius + (Cmd) sunbathe + Too dim. + (Cmd) set degrees_c 41 + degrees_c - was: 22 + now: 41 + (Cmd) set sunny + sunny: True + (Cmd) sunbathe + UV is bad for your skin. + (Cmd) set degrees_c 13 + degrees_c - was: 41 + now: 13 + (Cmd) sunbathe + It's 13 C - are you a penguin? diff --git a/docs/features/shortcuts_aliases_macros.rst b/docs/features/shortcuts_aliases_macros.rst index 7b91a4b5..0f06fe08 100644 --- a/docs/features/shortcuts_aliases_macros.rst +++ b/docs/features/shortcuts_aliases_macros.rst @@ -4,10 +4,92 @@ Shortcuts, Aliases, and Macros Shortcuts --------- +Command shortcuts for long command names and common commands can make life more +convenient for your users. Shortcuts are used without a space separating them +from their arguments, like ``!ls``. By default, the following shortcuts are +defined: + + ``?`` + help + + ``!`` + shell: run as OS-level command + + ``@`` + run script file + + ``@@`` + run script file; filename is relative to current script location + +To define more shortcuts, update the dict ``App.shortcuts`` with the +{'shortcut': 'command_name'} (omit ``do_``):: + + class App(Cmd2): + def __init__(self): + shortcuts = dict(cmd2.DEFAULT_SHORTCUTS) + shortcuts.update({'*': 'sneeze', '~': 'squirm'}) + cmd2.Cmd.__init__(self, shortcuts=shortcuts) + +.. warning:: + + Shortcuts need to be created by updating the ``shortcuts`` dictionary + attribute prior to calling the ``cmd2.Cmd`` super class ``__init__()`` + method. Moreover, that super class init method needs to be called after + updating the ``shortcuts`` attribute This warning applies in general to many + other attributes which are not settable at runtime. + Aliases ------- +In addition to shortcuts, ``cmd2`` provides a full alias feature via the +``alias`` command. Aliases work in a similar fashion to aliases in the Bash +shell. + +The syntax to create an alias is: ``alias create name command [args]``. + + Ex: ``alias create ls !ls -lF`` + +For more details run: ``help alias create`` + +Use ``alias list`` to see all or some of your aliases. The output of this +command displays your aliases using the same command that was used to create +them. Therefore you can place this output in a ``cmd2`` startup script to +recreate your aliases each time you start the application + + Ex: ``alias list`` + +For more details run: ``help alias list`` + +Use ``alias delete`` to remove aliases + +For more details run: ``help alias delete`` + Macros ------ + +``cmd2`` provides a feature that is similar to aliases called macros. The major +difference between macros and aliases is that macros can contain argument +placeholders. Arguments are expressed when creating a macro using {#} notation +where {1} means the first argument. + +The following creates a macro called my_macro that expects two arguments: + + macro create my_macro make_dinner -meat {1} -veggie {2} + +When the macro is called, the provided arguments are resolved and the assembled +command is run. For example: + + my_macro beef broccoli ---> make_dinner -meat beef -veggie broccoli + +For more details run: ``help macro create`` + +The macro command has ``list`` and ``delete`` subcommands that function +identically to the alias subcommands of the same name. Like aliases, macros can +be created via a ``cmd2`` startup script to preserve them across application +sessions. + +For more details on listing macros run: ``help macro list`` + +For more details on deleting macros run: ``help macro delete`` diff --git a/docs/features/transcripts.rst b/docs/features/transcripts.rst index 18daeb78..fe074cfa 100644 --- a/docs/features/transcripts.rst +++ b/docs/features/transcripts.rst @@ -152,9 +152,9 @@ the path instead of specifying it verbatim, or we can escape the slashes:: Some terminal emulators strip trailing space when you copy text from them. This could make the actual data generated by your app different than the text you pasted into the transcript, and it might not be readily obvious why - the transcript is not passing. Consider using :ref:`output_redirection` to - the clipboard or to a file to ensure you accurately capture the output of - your command. + the transcript is not passing. Consider using + :ref:`features/generating_output:Output Redirection` to the clipboard or to + a file to ensure you accurately capture the output of your command. If you aren't using regular expressions, make sure the newlines at the end of your transcript exactly match the output of your commands. A common cause diff --git a/docs/freefeatures.rst b/docs/freefeatures.rst deleted file mode 100644 index cb693be8..00000000 --- a/docs/freefeatures.rst +++ /dev/null @@ -1,136 +0,0 @@ -=================================== -Features requiring no modifications -=================================== - -These features are provided "for free" to a cmd_-based application -simply by replacing ``import cmd`` with ``import cmd2 as cmd``. - -.. _cmd: https://docs.python.org/3/library/cmd.html - -.. _scripts: - -Script files -============ - -Text files can serve as scripts for your ``cmd2``-based application, with the -``run_script``, ``_relative_run_script``, and ``edit`` commands. - -Both ASCII and UTF-8 encoded unicode text files are supported. - -Simply include one command per line, typed exactly as you would inside a -``cmd2`` application. - -.. automethod:: cmd2.cmd2.Cmd.do_run_script - :noindex: - -.. automethod:: cmd2.cmd2.Cmd.do__relative_run_script - :noindex: - -.. automethod:: cmd2.cmd2.Cmd.do_edit - :noindex: - - -Startup Initialization Script -============================= - -You can execute commands from a startup initialization script by passing a file -path to the ``startup_script`` argument to the ``cmd2.Cmd.__init__()`` method -like so:: - - class StartupApp(cmd2.Cmd): - def __init__(self): - cmd2.Cmd.__init__(self, startup_script='.cmd2rc') - -See the AliasStartup_ example for a demonstration. - -.. _AliasStartup: https://github.com/python-cmd2/cmd2/blob/master/examples/alias_startup.py - -Commands at invocation -====================== - -You can send commands to your app as you invoke it by -including them as extra arguments to the program. -``cmd2`` interprets each argument as a separate -command, so you should enclose each command in -quotation marks if it is more than a one-word command. - -:: - - cat@eee:~/proj/cmd2/example$ python example.py "say hello" "say Gracie" quit - hello - Gracie - cat@eee:~/proj/cmd2/example$ - -.. note:: - - If you wish to disable cmd2's consumption of command-line arguments, you can do so by setting the ``allow_cli_args`` - argument of your ``cmd2.Cmd`` class instance to ``False``. This would be useful, for example, if you wish to use - something like Argparse_ to parse the overall command line arguments for your application:: - - from cmd2 import Cmd - class App(Cmd): - def __init__(self): - super().__init__(allow_cli_args=False) - -.. _Argparse: https://docs.python.org/3/library/argparse.html - -.. _output_redirection: - - - -Quitting the application -======================== - -``cmd2`` pre-defines a ``quit`` command for you. -It's trivial, but it's one less thing for you to remember. - - -Misc. pre-defined commands -========================== - -Several generically useful commands are defined -with automatically included ``do_`` methods. - -.. automethod:: cmd2.cmd2.Cmd.do_quit - :noindex: - -.. automethod:: cmd2.cmd2.Cmd.do_shell - :noindex: - -( ``!`` is a shortcut for ``shell``; thus ``!ls`` -is equivalent to ``shell ls``.) - - -Tab-Completion -============== - -``cmd2`` adds tab-completion of file system paths for all built-in commands -where it makes sense, including: - -- ``edit`` -- ``run_pyscript`` -- ``run_script`` -- ``shell`` - -``cmd2`` also adds tab-completion of shell commands to the ``shell`` command. - -Additionally, it is trivial to add identical file system path completion to -your own custom commands. Suppose you have defined a custom command ``foo`` by -implementing the ``do_foo`` method. To enable path completion for the ``foo`` -command, then add a line of code similar to the following to your class which -inherits from ``cmd2.Cmd``:: - - complete_foo = self.path_complete - -This will effectively define the ``complete_foo`` readline completer method in -your class and make it utilize the same path completion logic as the built-in -commands. - -The built-in logic allows for a few more advanced path completion capabilities, -such as cases where you only want to match directories. Suppose you have a -custom command ``bar`` implemented by the ``do_bar`` method. You can enable -path completion of directories only for this command by adding a line of code -similar to the following to your class which inherits from ``cmd2.Cmd``:: - - # Make sure you have an "import functools" somewhere at the top - complete_bar = functools.partialmethod(cmd2.Cmd.path_complete, path_filter=os.path.isdir) diff --git a/docs/index.rst b/docs/index.rst index d9b5b14c..c21cfeb1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -88,24 +88,3 @@ Meta doc_conventions copyright - - -To Be Integrated -================ - -Files from old documentation to be integrated into new structure - -* :doc:`freefeatures` -* :doc:`integrating` -* :doc:`settingchanges` -* :doc:`unfreefeatures` - -.. toctree:: - :maxdepth: 2 - :hidden: - :caption: To Be Integrated - - freefeatures - integrating - settingchanges - unfreefeatures diff --git a/docs/integrating.rst b/docs/integrating.rst deleted file mode 100644 index 9b0cf737..00000000 --- a/docs/integrating.rst +++ /dev/null @@ -1,164 +0,0 @@ -.. cmd2 documentation for integration with other tools - -Integrating cmd2 with external tools -==================================== - - -Integrating cmd2 with the shell -------------------------------- - -Typically you would invoke a ``cmd2`` program by typing:: - - $ python mycmd2program.py - -or:: - - $ mycmd2program.py - -Either of these methods will launch your program and enter the ``cmd2`` command -loop, which allows the user to enter commands, which are then executed by your -program. - -You may want to execute commands in your program without prompting the user for -any input. There are several ways you might accomplish this task. The easiest -one is to pipe commands and their arguments into your program via standard -input. You don't need to do anything to your program in order to use this -technique. Here's a demonstration using the ``examples/example.py`` included in -the source code of ``cmd2``:: - - $ echo "speak -p some words" | python examples/example.py - omesay ordsway - -Using this same approach you could create a text file containing the commands -you would like to run, one command per line in the file. Say your file was -called ``somecmds.txt``. To run the commands in the text file using your -``cmd2`` program (from a Windows command prompt):: - - c:\cmd2> type somecmds.txt | python.exe examples/example.py - omesay ordsway - -By default, ``cmd2`` programs also look for commands pass as arguments from the -operating system shell, and execute those commands before entering the command -loop:: - - $ python examples/example.py help - - Documented commands (type help <topic>): - ======================================== - alias help macro orate quit run_script set shortcuts - edit history mumble py run_pyscript say shell speak - - (Cmd) - -You may need more control over command line arguments passed from the operating -system shell. For example, you might have a command inside your ``cmd2`` -program which itself accepts arguments, and maybe even option strings. Say you -wanted to run the ``speak`` command from the operating system shell, but have -it say it in pig latin:: - - $ python example/example.py speak -p hello there - python example.py speak -p hello there - usage: speak [-h] [-p] [-s] [-r REPEAT] words [words ...] - speak: error: the following arguments are required: words - *** Unknown syntax: -p - *** Unknown syntax: hello - *** Unknown syntax: there - (Cmd) - -Uh-oh, that's not what we wanted. ``cmd2`` treated ``-p``, ``hello``, and -``there`` as commands, which don't exist in that program, thus the syntax -errors. - -There is an easy way around this, which is demonstrated in -``examples/cmd_as_argument.py``. By setting ``allow_cli_args=False`` you can so -your own argument parsing of the command line:: - - $ python examples/cmd_as_argument.py speak -p hello there - ellohay heretay - -Check the source code of this example, especially the ``main()`` function, to -see the technique. - - -Integrating cmd2 with event loops ---------------------------------- - -Throughout this documentation we have focused on the **90%** use case, that is -the use case we believe around **90+%** of our user base is looking for. This -focuses on ease of use and the best out-of-the-box experience where developers -get the most functionality for the least amount of effort. We are talking -about running cmd2 applications with the ``cmdloop()`` method:: - - from cmd2 import Cmd - class App(Cmd): - # customized attributes and methods here - app = App() - app.cmdloop() - -However, there are some limitations to this way of using ``cmd2``, mainly that -``cmd2`` owns the inner loop of a program. This can be unnecessarily -restrictive and can prevent using libraries which depend on controlling their -own event loop. - -Many Python concurrency libraries involve or require an event loop which they -are in control of such as asyncio_, gevent_, Twisted_, etc. - -.. _asyncio: https://docs.python.org/3/library/asyncio.html -.. _gevent: http://www.gevent.org/ -.. _Twisted: https://twistedmatrix.com - -``cmd2`` applications can be executed in a fashion where ``cmd2`` doesn't own -the main loop for the program by using code like the following:: - - import cmd2 - - class Cmd2EventBased(cmd2.Cmd): - def __init__(self): - cmd2.Cmd.__init__(self) - - # ... your class code here ... - - if __name__ == '__main__': - app = Cmd2EventBased() - app.preloop() - - # Do this within whatever event loop mechanism you wish to run a single command - cmd_line_text = "help history" - app.runcmds_plus_hooks([cmd_line_text]) - - app.postloop() - -The **runcmds_plus_hooks()** method is a convenience method to run multiple -commands via **onecmd_plus_hooks()**. - -The **onecmd_plus_hooks()** method will do the following to execute a single -``cmd2`` command in a normal fashion: - -#. Parse user input into `Statement` object -#. Call methods registered with `register_postparsing_hook()` -#. Redirect output, if user asked for it and it's allowed -#. Start timer -#. Call methods registered with `register_precmd_hook()` -#. Call `precmd()` - for backwards compatibility with ``cmd.Cmd`` -#. Add statement to history -#. Call `do_command` method -#. Call methods registered with `register_postcmd_hook()` -#. Call `postcmd(stop, statement)` - for backwards compatibility with - ``cmd.Cmd`` -#. Stop timer and display the elapsed time -#. Stop redirecting output if it was redirected -#. Call methods registered with `register_cmdfinalization_hook()` - -Running in this fashion enables the ability to integrate with an external event -loop. However, how to integrate with any specific event loop is beyond the -scope of this documentation. Please note that running in this fashion comes -with several disadvantages, including: - -* Requires the developer to write more code -* Does not support transcript testing -* Does not allow commands at invocation via command-line arguments - -Here is a little more info on ``runcmds_plus_hooks``: - -.. automethod:: cmd2.cmd2.Cmd.runcmds_plus_hooks - :noindex: diff --git a/docs/settingchanges.rst b/docs/settingchanges.rst deleted file mode 100644 index d4f277fd..00000000 --- a/docs/settingchanges.rst +++ /dev/null @@ -1,194 +0,0 @@ -========================================= -Features requiring only parameter changes -========================================= - -Several aspects of a ``cmd2`` application's behavior -can be controlled simply by setting attributes of ``App``. -A parameter can also be changed at runtime by the user *if* -its name is included in the dictionary ``app.settable``. -(To define your own user-settable parameters, see :ref:`parameters`) - - -Shortcuts -========= - -Command shortcuts for long command names and common commands can make life more -convenient for your users. Shortcuts are used without a space separating them -from their arguments, like ``!ls``. By default, the following shortcuts are -defined: - - ``?`` - help - - ``!`` - shell: run as OS-level command - - ``@`` - run script file - - ``@@`` - run script file; filename is relative to current script location - -To define more shortcuts, update the dict ``App.shortcuts`` with the -{'shortcut': 'command_name'} (omit ``do_``):: - - class App(Cmd2): - def __init__(self): - shortcuts = dict(cmd2.DEFAULT_SHORTCUTS) - shortcuts.update({'*': 'sneeze', '~': 'squirm'}) - cmd2.Cmd.__init__(self, shortcuts=shortcuts) - -.. warning:: - - Shortcuts need to be created by updating the ``shortcuts`` dictionary - attribute prior to calling the ``cmd2.Cmd`` super class ``__init__()`` - method. Moreover, that super class init method needs to be called after - updating the ``shortcuts`` attribute This warning applies in general to many - other attributes which are not settable at runtime. - - -Aliases -======= - -In addition to shortcuts, ``cmd2`` provides a full alias feature via the -``alias`` command. Aliases work in a similar fashion to aliases in the Bash -shell. - -The syntax to create an alias is: ``alias create name command [args]``. - - Ex: ``alias create ls !ls -lF`` - -For more details run: ``help alias create`` - -Use ``alias list`` to see all or some of your aliases. The output of this -command displays your aliases using the same command that was used to create -them. Therefore you can place this output in a ``cmd2`` startup script to -recreate your aliases each time you start the application - - Ex: ``alias list`` - -For more details run: ``help alias list`` - -Use ``alias delete`` to remove aliases - -For more details run: ``help alias delete`` - -Macros -====== - -``cmd2`` provides a feature that is similar to aliases called macros. The major -difference between macros and aliases is that macros can contain argument -placeholders. Arguments are expressed when creating a macro using {#} notation -where {1} means the first argument. - -The following creates a macro called my_macro that expects two arguments: - - macro create my_macro make_dinner -meat {1} -veggie {2} - -When the macro is called, the provided arguments are resolved and the assembled -command is run. For example: - - my_macro beef broccoli ---> make_dinner -meat beef -veggie broccoli - -For more details run: ``help macro create`` - -The macro command has ``list`` and ``delete`` subcommands that function -identically to the alias subcommands of the same name. Like aliases, macros can -be created via a ``cmd2`` startup script to preserve them across application -sessions. - -For more details on listing macros run: ``help macro list`` - -For more details on deleting macros run: ``help macro delete`` - - -Default to shell -================ - -Every ``cmd2`` application can execute operating-system level (shell) commands -with ``shell`` or a ``!`` shortcut:: - - (Cmd) shell which python - /usr/bin/python - (Cmd) !which python - /usr/bin/python - -However, if the parameter ``default_to_shell`` is ``True``, then *every* -command will be attempted on the operating system. Only if that attempt fails -(i.e., produces a nonzero return value) will the application's own ``default`` -method be called. - -:: - - (Cmd) which python - /usr/bin/python - (Cmd) my dog has fleas - sh: my: not found - *** Unknown syntax: my dog has fleas - -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. - -:: - - (Cmd) typing a comma^C - (Cmd) - -.. warning:: - The default SIGINT behavior will only function properly if **cmdloop** is running - in the main thread. - - -Timing -====== - -Setting ``App.timing`` to ``True`` outputs timing data after every application -command is executed. |settable| - -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. - -Debug -===== - -Setting ``App.debug`` to ``True`` will produce detailed error stacks whenever -the application generates an error. |settable| - -.. |settable| replace:: The user can ``set`` this parameter - during application execution. - (See :ref:`parameters`) - -.. _parameters: - -Other user-settable parameters -============================== - -A list of all user-settable parameters, with brief -comments, is viewable from within a running application -with:: - - (Cmd) set --long - allow_ansi: Terminal # Allow ANSI escape sequences in output (valid values: Terminal, Always, Never) - continuation_prompt: > # On 2nd+ line of input - debug: False # Show full error stack on error - echo: False # Echo command issued into output - editor: vim # Program used by ``edit`` - feedback_to_output: False # include nonessentials in `|`, `>` results - locals_in_py: False # Allow access to your application in py via self - prompt: (Cmd) # The prompt issued to solicit input - quiet: False # Don't print nonessential feedback - timing: False # Report execution times - -Any of these user-settable parameters can be set while running your app with -the ``set`` command like so:: - - set allow_ansi Never - diff --git a/docs/unfreefeatures.rst b/docs/unfreefeatures.rst deleted file mode 100644 index 19c4e547..00000000 --- a/docs/unfreefeatures.rst +++ /dev/null @@ -1,231 +0,0 @@ -Features requiring application changes -====================================== - - -Parsed statements ------------------ - -``cmd2`` passes ``arg`` to a ``do_`` method (or ``default``) as a Statement, a -subclass of string that includes many attributes of the parsed input: - -command - Name of the command called - -args - The arguments to the command with output redirection - or piping to shell commands removed - -command_and_args - A string of just the command and the arguments, with - output redirection or piping to shell commands removed - -argv - A list of arguments a-la ``sys.argv``, including - the command as ``argv[0]`` and the subsequent - arguments as additional items in the list. - Quotes around arguments will be stripped as will - any output redirection or piping portions of the command - -raw - Full input exactly as typed. - -terminator - Character used to end a multiline command - - - -If ``Statement`` does not contain an attribute, querying for it will return -``None``. - -(Getting ``arg`` as a ``Statement`` is technically "free", in that it requires -no application changes from the cmd_ standard, but there will be no result -unless you change your application to *use* any of the additional attributes.) - -.. _cmd: https://docs.python.org/3/library/cmd.html - - -Environment parameters ----------------------- - -Your application can define user-settable parameters which your code can -reference. First create a class attribute with the default value. Then update -the ``settable`` dictionary with your setting name and a short description -before you initialize the superclass. Here's an example, from -``examples/environment.py``: - -.. literalinclude:: ../examples/environment.py - -If you want to be notified when a setting changes (as we do above), then define -a method ``_onchange_{setting}()``. This method will be called after the user -changes a setting, and will receive both the old value and the new value. - -.. code-block:: text - - (Cmd) set --long | grep sunny - sunny: False # Is it sunny outside? - (Cmd) set --long | grep degrees - degrees_c: 22 # Temperature in Celsius - (Cmd) sunbathe - Too dim. - (Cmd) set degrees_c 41 - degrees_c - was: 22 - now: 41 - (Cmd) set sunny - sunny: True - (Cmd) sunbathe - UV is bad for your skin. - (Cmd) set degrees_c 13 - degrees_c - was: 41 - now: 13 - (Cmd) sunbathe - It's 13 C - are you a penguin? - - -Commands with flags -=================== - -All ``do_`` methods are responsible for interpreting the arguments passed to -them. However, ``cmd2`` lets a ``do_`` methods accept Unix-style *flags*. It -uses argparse_ to parse the flags, and they work the same way as for that -module. - -``cmd2`` defines a few decorators which change the behavior of how arguments -get parsed for and passed to a ``do_`` method. See the section -:ref:`decorators` for more information. - -.. _argparse: https://docs.python.org/3/library/argparse.html - -poutput, pfeedback, perror, ppaged -================================== - -Standard ``cmd`` applications produce their output with -``self.stdout.write('output')`` (or with ``print``, but ``print`` decreases -output flexibility). ``cmd2`` applications can use ``self.poutput('output')``, -``self.pfeedback('message')``, ``self.perror('errmsg')``, and -``self.ppaged('text')`` instead. These methods have these advantages: - -- Handle output redirection to file and/or pipe appropriately -- More concise - - ``.pfeedback()`` destination is controlled by :ref:`quiet` parameter. -- Option to display long output using a pager via ``ppaged()`` - -.. automethod:: cmd2.cmd2.Cmd.poutput - :noindex: -.. automethod:: cmd2.cmd2.Cmd.perror - :noindex: -.. automethod:: cmd2.cmd2.Cmd.pfeedback - :noindex: -.. automethod:: cmd2.cmd2.Cmd.ppaged - :noindex: - - -Colored Output -============== - -The output methods in the previous section all honor the ``allow_ansi`` -setting, which has three possible values: - -Never - poutput(), pfeedback(), and ppaged() strip all ANSI escape sequences - which instruct the terminal to colorize output - -Terminal - (the default value) poutput(), pfeedback(), and ppaged() do not strip any - ANSI escape sequences when the output is a terminal, but if the output is a - pipe or a file the escape sequences are stripped. If you want colorized - output you must add ANSI escape sequences using either cmd2's internal ansi - module or another color library such as `plumbum.colors`, `colorama`, or - `colored`. - -Always - poutput(), pfeedback(), and ppaged() never strip ANSI escape sequences, - regardless of the output destination - -Colored and otherwise styled output can be generated using the `ansi.style()` -function: - -.. automethod:: cmd2.ansi.style - - -.. _quiet: - -Suppressing non-essential output -================================ - -The ``quiet`` setting controls whether ``self.pfeedback()`` actually produces -any output. If ``quiet`` is ``False``, then the output will be produced. If -``quiet`` is ``True``, no output will be produced. - -This makes ``self.pfeedback()`` useful for non-essential output like status -messages. Users can control whether they would like to see these messages by -changing the value of the ``quiet`` setting. - - -select -====== - -Presents numbered options to user, as bash ``select``. - -``app.select`` is called from within a method (not by the user directly; it is -``app.select``, not ``app.do_select``). - -.. automethod:: cmd2.cmd2.Cmd.select - :noindex: - -:: - - def do_eat(self, arg): - sauce = self.select('sweet salty', 'Sauce? ') - result = '{food} with {sauce} sauce, yum!' - result = result.format(food=arg, sauce=sauce) - self.stdout.write(result + '\n') - -:: - - (Cmd) eat wheaties - 1. sweet - 2. salty - Sauce? 2 - wheaties with salty sauce, yum! - - -Exit code to shell -================== - -The ``self.exit_code`` attribute of your ``cmd2`` application controls what -exit code is returned from ``cmdloop()`` when it completes. It is your job to -make sure that this exit code gets sent to the shell when your application -exits by calling ``sys.exit(app.cmdloop())``. - - -Disabling Commands -================== - -``cmd2`` supports disabling commands during runtime. This is useful if certain -commands should only be available when the application is in a specific state. -When a command is disabled, it will not show up in the help menu or tab -complete. If a user tries to run the command, a command-specific message -supplied by the developer will be printed. The following functions support this -feature. - -enable_command() - Enable an individual command - -enable_category() - Enable an entire category of commands - -disable_command() - Disable an individual command and set the message that will print when this - command is run or help is called on it while disabled - -disable_category() - Disable an entire category of commands and set the message that will print - when anything in this category is run or help is called on it while - disabled - -See the definitions of these functions for descriptions of their arguments. - -See the ``do_enable_commands()`` and ``do_disable_commands()`` functions in the -HelpCategories_ example for a demonstration. - -.. _HelpCategories: https://github.com/python-cmd2/cmd2/blob/master/examples/help_categories.py |