1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
.. cmd2 documentation for application and command lifecycle and the hooks which are available
cmd2 Application Lifecycle and Hooks
====================================
The typical way of starting a cmd2 application is as follows::
import cmd2
class App(cmd2.Cmd):
# customized attributes and methods here
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 command processing loop.
Application Lifecycle Hook Methods
----------------------------------
The ``preloop`` and ``postloop`` methods run before and after the main loop, respectively.
.. automethod:: cmd2.cmd2.Cmd.preloop
.. automethod:: cmd2.cmd2.Cmd.postloop
Application Lifecycle Attributes
--------------------------------
There are numerous attributes (member variables of the ``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:
- **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
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.
.. automethod:: cmd2.cmd2.Cmd.onecmd_plus_hooks
As the ``onecmd_plus_hooks`` name implies, there are a number of *hook* methods that can be defined in order to inject
application-specific behavior at various points during the processing of a line of text entered by the user. ``cmd2``
increases the 2 hooks provided by ``cmd`` (**precmd** and **postcmd**) to 6 for greater flexibility. Here are
the various hook methods, presented in chronological order starting with the ones called earliest in the process.
.. automethod:: cmd2.cmd2.Cmd.preparse
.. automethod:: cmd2.cmd2.Cmd.postparse
.. automethod:: cmd2.cmd2.Cmd.postparsing_precmd
.. automethod:: cmd2.cmd2.Cmd.precmd
.. automethod:: cmd2.cmd2.Cmd.postcmd
.. automethod:: cmd2.cmd2.Cmd.postparsing_postcmd
|