summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorkotfu <kotfu@kotfu.net>2018-05-26 16:23:15 -0600
committerkotfu <kotfu@kotfu.net>2018-05-26 16:23:15 -0600
commit4d7d98c0c856cb5ce1ac1dbe214a542f4a83a813 (patch)
tree0c7ae5f309d6a7141118d75beaa4c69efc1c1fde /docs
parentc390a6bc1aed393b7c7d4e493d61636b34bcdc9a (diff)
downloadcmd2-git-4d7d98c0c856cb5ce1ac1dbe214a542f4a83a813.tar.gz
Document and test postparsing hooks
Diffstat (limited to 'docs')
-rw-r--r--docs/hooks.rst123
1 files changed, 96 insertions, 27 deletions
diff --git a/docs/hooks.rst b/docs/hooks.rst
index 1402fee5..9e6c8b82 100644
--- a/docs/hooks.rst
+++ b/docs/hooks.rst
@@ -5,14 +5,16 @@ cmd2 Application Lifecycle and Hooks
The typical way of starting a cmd2 application is as follows::
- from cmd2 import Cmd
- class App(Cmd):
+ import cmd2
+ class App(cmd2.Cmd):
# customized attributes and methods here
- app = App()
- app.cmdloop()
+
+ if __name__ == '__main__':
+ app = App()
+ app.cmdloop()
There are several pre-existing methods and attributes which you can tweak to control the overall behavior of your
-application before, during, and after the main loop.
+application before, during, and after the command processing loop.
Application Lifecycle Hook Methods
----------------------------------
@@ -36,8 +38,94 @@ behavior upon entering or during the main loop. A partial list of some of the m
command results
-Command Processing Hooks
-------------------------
+Command Processing Loop
+-----------------------
+
+When you call `.cmdloop()`, the following sequence of events are repeated
+until the application exits:
+
+1. Output the prompt
+2. Accept user input
+3. Call methods registered with `register_preparsing_hook()`
+4. Parse user input into `Statement` object
+5. Call methods registered with `register_postparsing_hook()`
+6. Call `postparsing_precmd()` - for backwards compatibility deprecated
+7. Redirect output, if user asked for it and it's allowed
+8. Start command timer
+9. Call methods registered with `register_precmd_hook()`
+10. Call `precmd()` - for backwards compatibility deprecated
+11. Add statement to history
+12. Call `do_command` method
+13. Call methods registered with `register_postcmd_hook()`
+14. Call `postcmd()` - for backwards compatibility deprecated
+15. Stop timer
+16. Stop redirecting output, if it was redirected
+17. Call methods registered with `register_cmdcompleted_hook()`
+18. Call `postparsing_postcmd()` - for backwards compatibility - deprecated
+
+By registering hook methods, steps 3, 5, 9, 13, and 17 allow you to run code
+during, and control the flow of the command processing loop. Be aware that
+plugins also utilize these hooks, so there may be code running that is not
+part of your application. Methods registered for a hook are called in the
+order they were registered. You can register a function more than once, and
+it will be called each time it was registered.
+
+Preparsing Hooks
+^^^^^^^^^^^^^^^^
+
+Postparsing Hooks
+^^^^^^^^^^^^^^^^^
+
+You can register one or more methods which are called after the user input
+has been parsed, but before output is redirected, the timer is started, and
+before the command is run.
+
+To define and register a postparsing hook, do the following::
+
+ class App(cmd2.Cmd):
+ def __init__(self, *args, *kwargs):
+ super().__init__(*args, **kwargs)
+ self.register_postparsing_hook(self.myhookmethod)
+
+ def myhookmethod(self, statement):
+ return False, statement
+
+The hook method will be passed one parameter, a `Statement` object containing
+the parsed user input. There are many useful attributes in the Statement
+object, including `.raw` which contains exactly what the user typed. The hook
+method must return a tuple: the first element indicates whether to fatally fail
+this command and exit the application, and the second element is a potentially
+modified `Statement` object.
+
+To modify the user input, you create and return a new `Statement` object::
+
+ def myhookmethod(self, statement):
+ if not '|' in statement.raw:
+ newinput = statement.raw + ' | less'
+ statement = self.statement_parser.parse(newinput)
+ return False, statement
+
+There are several other mechanisms for controlling the flow of command
+processing. If you raise an `cmd2.EmptyStatement` exception, no further
+postparsing hooks will be run, nor will the command be run. No error will
+be displayed for the user either.
+
+If you raise any other exception, no further postprocessing hooks will be run,
+nor will the command be executed. The exception message will be displayed for
+the user.
+
+Precommand Hooks
+^^^^^^^^^^^^^^^^^
+
+Postcommand Hooks
+^^^^^^^^^^^^^^^^^^
+
+Command Completed Hooks
+^^^^^^^^^^^^^^^^^^^^^^^
+
+
+Deprecated Command Processing Hooks
+-----------------------------------
Inside the main loop, every time the user hits <Enter> the line is processed by the ``onecmd_plus_hooks`` method.
@@ -58,23 +146,4 @@ the various hook methods, presented in chronological order starting with the one
.. automethod:: cmd2.cmd2.Cmd.postcmd
-.. automethod:: cmd2.cmd2.Cmd.postparsing_postcmd
-
-Registering hooks
------------------
-
-As an alternative to overriding one of the hook methods, you can register any number of functions
-to be called when the hook is processed. These registered functions are called before any overridden
-method.
-
-This method of registering and calling multiple hooks allows plugins to tap into the hook mechanism
-without interfering with each other or with your code.
-
-register_preloop_hook
-register_postloop_hook
-
-register_preparsing_hook
-register_postparsing_hook
-register_precmd_hook
-register_postcmd_hook
-register_cmdcompleted_hook
+.. automethod:: cmd2.cmd2.Cmd.postparsing_postcmd \ No newline at end of file