diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/api/cmd.rst | 20 | ||||
-rw-r--r-- | docs/features/hooks.rst | 76 | ||||
-rw-r--r-- | docs/features/plugins.rst | 56 | ||||
-rw-r--r-- | docs/features/transcripts.rst | 7 |
4 files changed, 97 insertions, 62 deletions
diff --git a/docs/api/cmd.rst b/docs/api/cmd.rst index 34c0dcf7..3fcd3352 100644 --- a/docs/api/cmd.rst +++ b/docs/api/cmd.rst @@ -24,8 +24,19 @@ cmd2.Cmd .. attribute:: prompt - The prompt issued to solicit input. - Default: ``(Cmd)``. + The prompt issued to solicit input. The default value is ``(Cmd)``. + See :ref:`features/prompt:Prompt` for more information. + + .. attribute:: continuation_prompt + + The prompt issued to solicit input for the 2nd and subsequent lines + of a :ref:`multiline command <features/multiline_commands:Multiline Commands>` + + .. attribute:: echo + + If ``True``, output the prompt and user input before executing the command. + When redirecting a series of commands to an output file, this allows you to + see the command in the output. .. attribute:: settable @@ -47,3 +58,8 @@ cmd2.Cmd An instance of :class:`cmd2.parsing.StatementParser` initialized and configured appropriately for parsing user input. + + .. attribute:: intro + + Set an introduction message which is displayed to the user before + the :ref:`features/hooks:Command Processing Loop` begins. diff --git a/docs/features/hooks.rst b/docs/features/hooks.rst index 9cac40cd..fec8e258 100644 --- a/docs/features/hooks.rst +++ b/docs/features/hooks.rst @@ -19,7 +19,11 @@ command processing loop. Application Lifecycle Hooks --------------------------- -You can register methods to be called at the beginning of the command loop:: +You can run a script on initialization by passing the script filename in the +``startup_script`` parameter of :meth:`cmd2.Cmd.__init__`. + +You can also register methods to be called at the beginning of the command +loop:: class App(cmd2.Cmd): def __init__(self, *args, *kwargs): @@ -29,8 +33,9 @@ You can register methods to be called at the beginning of the command loop:: def myhookmethod(self): self.poutput("before the loop begins") -To retain backwards compatibility with `cmd.Cmd`, after all registered preloop -hooks have been called, the ``preloop()`` method is called. +To retain backwards compatibility with ``cmd.Cmd``, after all registered +preloop hooks have been called, the :meth:`~cmd2.Cmd.preloop` method is +called. A similar approach allows you to register functions to be called after the command loop has finished:: @@ -43,54 +48,68 @@ command loop has finished:: def myhookmethod(self): self.poutput("before the loop begins") -To retain backwards compatibility with `cmd.Cmd`, after all registered postloop -hooks have been called, the ``postloop()`` method is called. +To retain backwards compatibility with ``cmd.Cmd``, after all registered +postloop hooks have been called, the :meth:`~cmd2.Cmd.postloop` method is +called. Preloop and postloop hook methods are not passed any parameters and any return value is ignored. +The approach of registering hooks instead of overriding methods allows multiple +hooks to be called before the command loop begins or ends. Plugin authors +should review :ref:`features/plugins:Hooks` for best practices writing hooks. + Application Lifecycle Attributes -------------------------------- -There are numerous attributes of and arguments to ``cmd2.Cmd`` which have a -significant effect on the application behavior upon entering or during the main -loop. A partial list of some of the more important ones is presented here: +There are numerous attributes on :class:`cmd2.Cmd` which affect application +behavior upon entering or during the command loop: + +- :data:`~cmd2.Cmd.intro` - if provided this serves as the intro banner printed + once at start of application, after :meth:`~cmd2.Cmd.preloop` is called. +- :data:`~cmd2.Cmd.prompt` - see :ref:`features/prompt:Prompt` for more + information. +- :data:`~cmd2.Cmd.continuation_prompt` - The prompt issued to solicit input + for the 2nd and subsequent lines of a + :ref:`multiline command <features/multiline_commands:Multiline Commands>` +- :data:`~cmd2.Cmd.echo` - if ``True`` write the prompt and the command into + the output stream. -- **intro**: *str* - if provided this serves as the intro banner printed once - at start of application, after ``preloop`` runs -- **allow_cli_args**: *bool* - if True (default), then searches for -t or - --test at command line to invoke transcript testing mode instead of a normal - main loop and also processes any commands provided as arguments on the - command line just prior to entering the main loop -- **echo**: *bool* - if True, then the command line entered is echoed to the - screen (most useful when running scripts) -- **prompt**: *str* - sets the prompt which is displayed, can be dynamically - changed based on application state and/or command results +In addition, several arguments to :meth:`cmd2.Cmd.__init__` also affect +the command loop behavior: + +- ``allow_cli_args`` - allows commands to be specified on the operating system + command line which are executed before the command processing loop begins. +- ``transcript_files`` - see :ref:`features/transcripts:Transcripts` for more + information +- ``startup_script`` - run a script on initialization. See + :ref:`features/scripting:Scripting` for more information. Command Processing Loop ----------------------- -When you call `.cmdloop()`, the following sequence of events are repeated until -the application exits: +When you call :meth:`cmd2.Cmd.cmdloop`, the following sequence of events are +repeated until the application exits: #. Output the prompt #. Accept user input -#. Parse user input into `Statement` object -#. Call methods registered with `register_postparsing_hook()` +#. Parse user input into a :class:`~cmd2.Statement` object +#. Call methods registered with :meth:`~cmd2.Cmd.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 methods registered with :meth:`~cmd2.Cmd.register_precmd_hook` +#. Call :meth:`~cmd2.Cmd.precmd` - for backwards compatibility with ``cmd.Cmd`` +#. Add statement to :ref:`features/history:History` #. Call `do_command` method -#. Call methods registered with `register_postcmd_hook()` -#. Call `postcmd(stop, statement)` - for backwards compatibility with +#. Call methods registered with :meth:`~cmd2.Cmd.register_postcmd_hook()` +#. Call :meth:`~cmd2.Cmd.postcmd` - 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()` +#. Call methods registered with + :meth:`~cmd2.Cmd.register_cmdfinalization_hook()` By registering hook methods, steps 4, 8, 12, and 16 allow you to run code during, and control the flow of the command processing loop. Be aware that @@ -103,6 +122,7 @@ Postparsing, precommand, and postcommand hook methods share some common ways to influence the command processing loop. If a hook raises an exception: + - no more hooks (except command finalization hooks) of any kind will be called - if the command has not yet been executed, it will not be executed - the exception message will be displayed for the user. diff --git a/docs/features/plugins.rst b/docs/features/plugins.rst index d6e3eb9c..ecd3a32d 100644 --- a/docs/features/plugins.rst +++ b/docs/features/plugins.rst @@ -5,18 +5,15 @@ Plugins a ``cmd2`` plugin which can extend basic ``cmd2`` functionality and can be used by multiple applications. -Adding functionality --------------------- - There are many ways to add functionality to ``cmd2`` using a plugin. Most plugins will be implemented as a mixin. A mixin is a class that encapsulates and injects code into another class. Developers who use a plugin in their -``cmd2`` project, will inject the plugin's code into their subclass of -``cmd2.Cmd``. +``cmd2`` project will inject the plugin's code into their subclass of +:class:`cmd2.Cmd`. Mixin and Initialization -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ The following short example shows how to mix in a plugin and how the plugin gets initialized. @@ -29,7 +26,6 @@ Here's the plugin:: super().__init__(*args, **kwargs) # code placed here runs after cmd2.Cmd initializes - and an example app which uses the plugin:: import cmd2 @@ -44,23 +40,24 @@ and an example app which uses the plugin:: # code placed here runs after cmd2.Cmd and # all plugins have initialized -Note how the plugin must be inherited (or mixed in) before ``cmd2.Cmd``. +Note how the plugin must be inherited (or mixed in) before :class:`cmd2.Cmd`. This is required for two reasons: -- The ``cmd.Cmd.__init__()`` method in the python standard library does not +- The ``cmd.Cmd.__init__`` method in the python standard library does not call ``super().__init__()``. Because of this oversight, if you don't inherit from ``MyPlugin`` first, the ``MyPlugin.__init__()`` method will never be called. -- You may want your plugin to be able to override methods from ``cmd2.Cmd``. - If you mixin the plugin after ``cmd2.Cmd``, the python method resolution - order will call ``cmd2.Cmd`` methods before it calls those in your plugin. +- You may want your plugin to be able to override methods from + :class:`cmd2.Cmd`. If you mixin the plugin after ``cmd2.Cmd``, the python + method resolution order will call :class:`cmd2.Cmd` methods before it calls + those in your plugin. Add commands -~~~~~~~~~~~~ +------------ Your plugin can add user visible commands. You do it the same way in a plugin -that you would in a ``cmd2.Cmd`` app:: +that you would in a :class:`cmd2.Cmd` app:: class MyPlugin: def do_say(self, statement): @@ -68,12 +65,12 @@ that you would in a ``cmd2.Cmd`` app:: self.poutput(statement) You have all the same capabilities within the plugin that you do inside a -``cmd2.Cmd`` app, including argument parsing via decorators and custom help -methods. +:class:`cmd2.Cmd` app, including argument parsing via decorators and custom +help methods. Add (or hide) settings -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- A plugin may add user controllable settings to the application. Here's an example:: @@ -86,33 +83,34 @@ example:: self.mysetting = 'somevalue' self.add_settable(cmd2.Settable('mysetting', str, 'short help message for mysetting')) -You can also hide settings from the user by removing them from -``self.settables``. +You can hide settings from the user by calling +:meth:`~cmd2.Cmd.remove_settable`. See :ref:`features/settings:Settings` for +more information. Decorators -~~~~~~~~~~ +---------- Your plugin can provide a decorator which users of your plugin can use to wrap functionality around their own commands. Override methods -~~~~~~~~~~~~~~~~ +---------------- -Your plugin can override core ``cmd2.Cmd`` methods, changing their behavior. -This approach should be used sparingly, because it is very brittle. If a -developer chooses to use multiple plugins in their application, and several -of the plugins override the same method, only the first plugin to be mixed in -will have the overridden method called. +Your plugin can override core :class:`cmd2.Cmd` methods, changing their +behavior. This approach should be used sparingly, because it is very brittle. +If a developer chooses to use multiple plugins in their application, and +several of the plugins override the same method, only the first plugin to be +mixed in will have the overridden method called. Hooks are a much better approach. Hooks -~~~~~ +----- -Plugins can register hook methods, which are called by :class:`~cmd2.Cmd` +Plugins can register hook methods, which are called by :class:`cmd2.Cmd` during various points in the application and command processing lifecycle. Plugins should not override any of the deprecated hook methods, instead they should register their hooks as described in the :ref:`features/hooks:Hooks` @@ -147,7 +145,7 @@ ways hooks can influence the lifecycle. Classes and Functions -~~~~~~~~~~~~~~~~~~~~~ +--------------------- Your plugin can also provide classes and functions which can be used by developers of ``cmd2`` based applications. Describe these classes and diff --git a/docs/features/transcripts.rst b/docs/features/transcripts.rst index 1af2a74f..fa6d9cb3 100644 --- a/docs/features/transcripts.rst +++ b/docs/features/transcripts.rst @@ -185,9 +185,10 @@ output matches the expected result from the transcript. .. note:: - If you have set ``allow_cli_args`` to False in order to disable parsing of - command line arguments at invocation, then the use of ``-t`` or ``--test`` to - run transcript testing is automatically disabled. In this case, you can + If you have passed an ``allow_cli_args`` parameter containing `False` to + :meth:`cmd2.Cmd.__init__` in order to disable parsing of command line + arguments at invocation, then the use of ``-t`` or ``--test`` to run + transcript testing is automatically disabled. In this case, you can alternatively provide a value for the optional ``transcript_files`` when constructing the instance of your ``cmd2.Cmd`` derived class in order to cause a transcript test to run:: |