Added interaction to hooke.ui.commandline.LocalCommandExit.
[hooke.git] / hooke / command.py
index c044c0682135271bda016d921e83138aa6bb0088..73f01fe3d443a20b0fb9483ed462896e4a2f3884 100644 (file)
@@ -9,21 +9,51 @@ import traceback
 
 
 class CommandExit (Exception):
-    def __str__(self):
-        return self.__class__.__name__
+    pass
 
 class Success (CommandExit):
     pass
 
+class Exit (Success):
+    """The command requests an end to the interpreter session.
+    """
+    pass
+
 class Failure (CommandExit):
     pass
 
 class UncaughtException (Failure):
     def __init__(self, exception):
-        super(UncaughtException, self).__init__(exception)
         self.exception = exception
         self.exc_string = traceback.format_exc()
         sys.exc_clear()
+        super(UncaughtException, self).__init__(self.exc_string)
+
+class Interaction (object):
+    """Mid-command inter-process interaction.
+    """
+    pass
+
+class Request (Interaction):
+    """Command engine requests for information from the UI.
+    """
+    def __init__(self, msg, default=None):
+        super(Request, self).__init__()
+        self.msg = msg
+        self.default = default
+
+class Response (Interaction):
+    """UI response to a :class:`Request`.
+    """
+    def __init__(self, value):
+        super(Response, self).__init__()
+        self.value = value
+
+class BooleanRequest (Request):
+    pass
+
+class BooleanResponse (Response):
+    pass
 
 class Command (object):
     """One-line command description here.
@@ -68,14 +98,15 @@ class Command (object):
             self._run(hooke, inqueue, outqueue, params)
         except CommandExit, e:
             if isinstance(e, Failure):
-                outqueue.put(str(e))
                 outqueue.put(e)
                 return 1
+            # other CommandExit subclasses fall through to the end
         except Exception, e:
             x = UncaughtException(e)
-            outqueue.put(x.exc_string)
             outqueue.put(x)
             return 1
+        else:
+            e = Success()
         outqueue.put(e)
         return 0
 
@@ -113,16 +144,24 @@ class Command (object):
             argument.validate(value)
         return params
 
-    def help(self, *args):
-        name_part = 'Command: %s' % self.name
+    def help(self, name_fn=lambda name:name):
+        """Return a help message describing the `Command`.
+
+        `name_fn(internal_name) -> external_name` gives calling
+        :class:`hooke.ui.UserInterface`\s a means of changing the
+        display names if it wants (e.g. to remove spaces from command
+        line tokens).
+        """
+        name_part = 'Command: %s' % name_fn(self.name)
         if len(self.aliases) > 0:
-            name_part += ' (%s)' % ', '.join(self.aliases)
+            name_part += ' (%s)' % ', '.join(
+                [name_fn(n) for n in self.aliases])
         parts = [name_part]
         if len(self.arguments) > 0:
             argument_part = ['Arguments:', '']
             for a in self.arguments:
                 argument_part.append(textwrap.fill(
-                        a.help(),
+                        a.help(name_fn),
                         initial_indent="",
                         subsequent_indent="    "))
             argument_part = '\n'.join(argument_part)
@@ -159,8 +198,15 @@ class Argument (object):
     def __repr__(self):
         return self.__str__()
 
-    def help(self):
-        parts = ['%s ' % self.name]
+    def help(self, name_fn=lambda name:name):
+        """Return a help message describing the `Argument`.
+
+        `name_fn(internal_name) -> external_name` gives calling
+        :class:`hooke.ui.UserInterface`\s a means of changing the
+        display names if it wants (e.g. to remove spaces from command
+        line tokens).
+        """        
+        parts = ['%s ' % name_fn(self.name)]
         if self.metavar != None:
             parts.append('%s ' % self.metavar)
         parts.extend(['(%s) ' % self.type, self._help])