Added basic commandline framework to ui.commandline (using cmd.Cmd)
[hooke.git] / hooke / ui / commandline.py
1 """Defines :class:`CommandLine` for driving Hooke from the command
2 line.
3 """
4
5 import cmd
6 import readline
7
8 from ..ui import UserInterface
9
10
11 class HookeCmd (cmd.Cmd):
12     def __init__(self, hooke):
13         cmd.Cmd.__init__(self)
14         self.hooke = hooke
15         self.prompt = 'hooke> '
16         self._add_do_methods()
17
18     def _safe_name(self, name):
19         return name.lower().replace(' ', '_')
20
21     def _add_do_methods(self):
22         for command in self.hooke.commands:
23             for name in [command.name] + command.aliases:
24                 name = self._safe_name(name)
25                 def do_fn(self, args):
26                     pass
27                 setattr(self.__class__, 'do_%s' % name, do_fn)
28                 def help_fn(self):
29                     pass
30                 setattr(self.__class__, 'help_%s' % name, help_fn)
31                 def complete_fn(self, text, line, begidx, endidx):
32                     pass
33                 setattr(self.__class__, 'complete_%s' % name, complete_fn)
34
35     def _help(self, name, aliases, message, usage_args=None):
36         if len(aliases) == 0:
37             alias_string = ''
38         else:
39             alias_string = ' (%s)' % ', '.join(aliases)
40         if usage_args == None:
41             usage_string = name
42         else:
43             usage_string = '%s %s' % (name, usage_args)
44         self.stdout.write(("""
45 %s%s
46
47 %s
48 ------
49 Usage: %s
50 """ % (name, alias_string, message.strip(), usage_string)).lstrip())
51
52     def help_help(self):
53         return self._help('help', [], """
54 Called with an argument, prints that command's documentation.
55
56 With no argument, lists all available help topics as well as any
57 undocumented commands.
58 """,
59                           '[command]')
60
61     def do_exit(self, args):
62         return True # the True return stops .cmdloop execution
63
64     def help_exit(self):
65         return self._help('exit', ['quit', 'EOF'], "Exit Hooke cleanly.")
66
67     def do_quit(self, args):
68         return self.do_exit(args)
69
70     def help_quit(self):
71         return self.help_exit()
72
73     def do_EOF(self, args):
74         return self.do_exit(args) 
75
76     def help_EOF(self):
77         return self.help_exit()
78
79 class CommandLine (UserInterface):
80     """Command line interface.  Simple and powerful.
81     """
82     def __init__(self):
83         super(CommandLine, self).__init__(name='command line')
84
85     def run(self, hooke, ui_to_command_queue, command_to_ui_queue):
86         cmd = HookeCmd(hooke)
87         cmd.cmdloop(self._splash_text())