diff options
Diffstat (limited to 'cmd2/cmd2.py')
-rw-r--r-- | cmd2/cmd2.py | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index ce19cda8..045e6a1b 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -408,6 +408,10 @@ class Cmd(cmd.Cmd): import atexit atexit.register(readline.write_history_file, persistent_history_file) + # initialize plugin system + # needs to be done before we call __init__(0) + self._initialize_plugin_system() + # Call super class constructor super().__init__(completekey=completekey, stdin=stdin, stdout=stdout) @@ -1670,7 +1674,7 @@ class Cmd(cmd.Cmd): statement = self.statement_parser.parse_command_only(line) return statement.command, statement.args, statement.command_and_args - def onecmd_plus_hooks(self, line): + def onecmd_plus_hooks(self, line: str) -> bool: """Top-level function called by cmdloop() to handle parsing a line and running the command and all of its hooks. :param line: str - line of text read from input @@ -1680,9 +1684,17 @@ class Cmd(cmd.Cmd): stop = False try: statement = self._complete_statement(line) - (stop, statement) = self.postparsing_precmd(statement) + # call the postparsing hooks + for func in self._postparsing_hooks: + (stop, statement) = func(statement) + if stop: + break + if not stop: + (stop, statement) = self.postparsing_precmd(statement) if stop: - return self.postparsing_postcmd(stop) + # we need to not run the command, but + # we need to run the finalization hooks + raise EmptyStatement try: if self.allow_redirection: @@ -1690,9 +1702,20 @@ class Cmd(cmd.Cmd): timestart = datetime.datetime.now() if self._in_py: self._last_result = None + + # precommand hooks + for func in self._precmd_hooks: + statement = func(statement) statement = self.precmd(statement) + + # go run the command function stop = self.onecmd(statement) + + # postcommand hooks + for func in self._postcmd_hooks: + stop = func(stop, statement) stop = self.postcmd(stop, statement) + if self.timing: self.pfeedback('Elapsed: %s' % str(datetime.datetime.now() - timestart)) finally: @@ -3047,6 +3070,8 @@ Script should contain one command per line, just like command would be typed in self.cmdqueue.extend(callargs) # Always run the preloop first + for func in self._preloop_hooks: + func() self.preloop() # If transcript-based regression testing was requested, then do that instead of the main loop @@ -3065,8 +3090,43 @@ Script should contain one command per line, just like command would be typed in self._cmdloop() # Run the postloop() no matter what + for func in self._postloop_hooks: + func() self.postloop() + ### + # + # plugin related functions + # + ### + def _initialize_plugin_system(self): + """Initialize the plugin system""" + self._preloop_hooks = [] + self._postloop_hooks = [] + self._postparsing_hooks = [] + self._precmd_hooks = [] + self._postcmd_hooks = [] + + def register_preloop_hook(self, func): + """Register a function to be called at the beginning of the command loop.""" + self._preloop_hooks.append(func) + + def register_postloop_hook(self, func): + """Register a function to be called at the end of the command loop.""" + self._postloop_hooks.append(func) + + def register_postparsing_hook(self, func): + """Register a function to be called after parsing user input but before running the command""" + self._postparsing_hooks.append(func) + + def register_precmd_hook(self, func): + """Register a function to be called before the command function.""" + self._precmd_hooks.append(func) + + def register_postcmd_hook(self, func): + """Register a function to be called after the command function.""" + self._postcmd_hooks.append(func) + class HistoryItem(str): """Class used to represent an item in the History list. |