Move LocalHelpCommand and LocalExitCommand from ui.commandline to plugin.engine.
authorW. Trevor King <wking@drexel.edu>
Thu, 12 Aug 2010 17:10:37 +0000 (13:10 -0400)
committerW. Trevor King <wking@drexel.edu>
Thu, 12 Aug 2010 17:10:37 +0000 (13:10 -0400)
It's not a good idea to have UI-specific commands that get sent down
to the CommandEngine.

hooke/plugin/__init__.py
hooke/plugin/engine.py [new file with mode: 0644]
hooke/ui/commandline.py

index 7f58b82e4cae6076f11799e2e3972db9b64b7a97..63f17a34bf6f028cfc99b3a6ec689dd2bdb4f347 100644 (file)
@@ -58,6 +58,7 @@ BUILTIN_MODULES = [
     'config',
     'curve',
     'debug',
+    'engine',
     'license',
     'note',
     'playlist',
diff --git a/hooke/plugin/engine.py b/hooke/plugin/engine.py
new file mode 100644 (file)
index 0000000..89f560a
--- /dev/null
@@ -0,0 +1,81 @@
+# Copyright
+
+"""The `engine` module provides :class:`EnginePlugin` and several
+associated :class:`hooke.command.Command`\s for basic
+:class:`~hooke.hooke.Hooke` and :class:`~hooke.engine.CommandEngine`
+interaction.
+"""
+
+from ..command import CommandExit, Exit, Command, Argument
+from ..interaction import BooleanRequest
+from . import Builtin
+
+
+class EnginePlugin (Builtin):
+    def __init__(self):
+        super(EnginePlugin, self).__init__(name='engine')
+        self._commands = [
+            ExitCommand(self), HelpCommand(self)]
+
+
+class ExitCommand (Command):
+    """Exit Hooke cleanly.
+    """
+    def __init__(self, plugin):
+        super(ExitCommand, self).__init__(
+            name='exit',
+            arguments = [
+                Argument(name='force', type='bool', default=False,
+                         help="""
+Exit without prompting the user.  Use if you save often or don't make
+typing mistakes ;).
+""".strip()),
+                ],
+             help=self.__doc__, plugin=plugin)
+
+    def _run(self, hooke, inqueue, outqueue, params):
+        """Exit Hooke, prompting if there are unsaved changes.
+        """
+        _exit = True
+        if params['force'] == False:
+            not_saved = [p.name for p in hooke.playlists
+                         if p.is_saved() == False]
+            msg = 'Exit?'
+            default = True
+            if len(not_saved) > 0:
+                msg = 'Unsaved playlists (%s).  %s' \
+                    % (', '.join([str(p) for p in not_saved]), msg)
+                default = False
+            outqueue.put(BooleanRequest(msg, default))
+            result = inqueue.get()
+            assert result.type == 'boolean'
+            _exit = result.value
+            if _exit == False:
+                return
+            # TODO: check for unsaved config file
+        if _exit == True:
+            raise Exit()
+
+
+class HelpCommand (Command):
+    """Called with an argument, prints that command's documentation.
+
+    With no argument, lists all available help topics as well as any
+    undocumented commands.
+    """
+    def __init__(self, plugin):
+        super(HelpCommand, self).__init__(
+            name='help', help=self.__doc__, plugin=plugin)
+        # We set .arguments now (vs. using th arguments option to __init__),
+        # to overwrite the default help argument.  We don't override
+        # :meth:`cmd.Cmd.do_help`, so `help --help` is not a valid command.
+        self.arguments = [
+            Argument(name='command', type='string', optional=True,
+                     help='The name of the command you want help with.')
+            ]
+
+    def _run(self, hooke, inqueue, outqueue, params):
+        if params['command'] == None:
+            outqueue.put(sorted([c.name for c in hooke.commands]))
+        else:
+            outqueue.put(hooke.command_by_name[params['command']].help())
index 14236ca24580e883e4e38596cc162ffb29f292fc..5f04c366623a0db03689ab29284b19bef6a664a3 100644 (file)
@@ -33,7 +33,7 @@ import shlex
 
 from ..command import CommandExit, Exit, Command, Argument, StoreValue
 from ..engine import CommandMessage
-from ..interaction import Request, BooleanRequest, ReloadUserInterfaceConfig
+from ..interaction import Request, ReloadUserInterfaceConfig
 from ..ui import UserInterface
 from ..util.convert import from_string
 from ..util.encoding import get_input_encoding, get_output_encoding
@@ -297,6 +297,8 @@ class DoCommand (CommandMethod):
 
 
 class HelpCommand (CommandMethod):
+    """Supersedes :class:`hooke.plugin.engine.HelpCommand`.
+    """
     def __init__(self, *args, **kwargs):
         super(HelpCommand, self).__init__(*args, **kwargs)
         self.parser = CommandLineParser(self.command, self.name_fn)
@@ -328,63 +330,6 @@ class CompleteCommand (CommandMethod):
         pass
 
 
-# Define some additional commands
-
-class LocalHelpCommand (Command):
-    """Called with an argument, prints that command's documentation.
-
-    With no argument, lists all available help topics as well as any
-    undocumented commands.
-    """
-    def __init__(self):
-        super(LocalHelpCommand, self).__init__(name='help', help=self.__doc__)
-        # We set .arguments now (vs. using th arguments option to __init__),
-        # to overwrite the default help argument.  We don't override
-        # :meth:`cmd.Cmd.do_help`, so `help --help` is not a valid command.
-        self.arguments = [
-            Argument(name='command', type='string', optional=True,
-                     help='The name of the command you want help with.')
-            ]
-
-    def _run(self, hooke, inqueue, outqueue, params):
-        raise NotImplementedError # cmd.Cmd already implements .do_help()
-
-class LocalExitCommand (Command):
-    """Exit Hooke cleanly.
-    """
-    def __init__(self):
-        super(LocalExitCommand, self).__init__(
-            name='exit', aliases=['quit', 'EOF'], help=self.__doc__,
-            arguments = [
-                Argument(name='force', type='bool', default=False,
-                         help="""
-Exit without prompting the user.  Use if you save often or don't make
-typing mistakes ;).
-""".strip()),
-                ])
-
-    def _run(self, hooke, inqueue, outqueue, params):
-        """The guts of the `do_exit/_quit/_EOF` commands.
-
-        A `True` return stops :meth:`.cmdloop` execution.
-        """
-        _exit = True
-        if params['force'] == False:
-            not_saved = [p.name for p in hooke.playlists
-                         if p.is_saved() == False]
-            msg = 'Exit?'
-            default = True
-            if len(not_saved) > 0:
-                msg = 'Unsaved playlists (%s).  %s' \
-                    % (', '.join([str(p) for p in not_saved]), msg)
-                default = False
-            outqueue.put(BooleanRequest(msg, default))
-            result = inqueue.get()
-            assert result.type == 'boolean'
-            _exit = result.value
-        if _exit == True:
-            raise Exit()
-
 
 # Now onto the main attraction.
 
@@ -393,7 +338,6 @@ class HookeCmd (cmd.Cmd):
         cmd.Cmd.__init__(self)
         self.ui = ui
         self.commands = commands
-        self.local_commands = [LocalExitCommand(), LocalHelpCommand()]
         self.prompt = 'hooke> '
         self._add_command_methods()
         self.inqueue = inqueue
@@ -403,7 +347,9 @@ class HookeCmd (cmd.Cmd):
         return name.replace(' ', '_')
 
     def _add_command_methods(self):
-        for command in self.commands + self.local_commands:
+        for command in self.commands:
+            if command.name == 'exit':
+                command.aliases.extend(['quit', 'EOF'])
             for name in [command.name] + command.aliases:
                 name = self._name_fn(name)
                 setattr(self.__class__, 'help_%s' % name,