1 """A generic class to build line-oriented command interpreters.
3 Interpreters constructed with this class obey the following conventions:
5 1. End of file on input is processed as the command 'EOF'.
6 2. A command is parsed out of each line by collecting the prefix composed
7 of characters in the identchars member.
8 3. A command `foo' is dispatched to a method 'do_foo()'; the do_ method
9 is passed a single argument consisting of the remainder of the line.
10 4. Typing an empty line repeats the last command. (Actually, it calls the
11 method `emptyline', which may be overridden in a subclass.)
12 5. There is a predefined `help' method. Given an argument `topic', it
13 calls the command `help_topic'. With no arguments, it lists all topics
14 with defined help_ functions, broken into up to three topics; documented
15 commands, miscellaneous help topics, and undocumented commands.
16 6. The command '?' is a synonym for `help'. The command '!' is a synonym
17 for `shell', if a do_shell method exists.
18 7. If completion is enabled, completing commands will be done automatically,
19 and completing of commands args is done by calling complete_foo() with
20 arguments text, line, begidx, endidx. text is string we are matching
21 against, all returned matches must begin with it. line is the current
22 input line (lstripped), begidx and endidx are the beginning and end
23 indexes of the text being matched, which could be used to provide
24 different completion depending upon which position the argument is in.
26 The `default' method may be overridden to intercept commands for which there
29 The `completedefault' method may be overridden to intercept completions for
30 commands that have no complete_ method.
32 The data member `self.ruler' sets the character used to draw separator lines
33 in the help messages. If empty, no ruler line is drawn. It defaults to "=".
35 If the value of `self.intro' is nonempty when the cmdloop method is called,
36 it is printed out on interpreter startup. This value may be overridden
37 via an optional argument to the cmdloop() method.
39 The data members `self.doc_header', `self.misc_header', and
40 `self.undoc_header' set the headers used for the help function's
41 listings of documented functions, miscellaneous topics, and undocumented
42 functions respectively.
44 These interpreters use raw_input; thus, if the readline module is loaded,
45 they automatically support Emacs-like command history and editing features.
53 IDENTCHARS
= string
.ascii_letters
+ string
.digits
+ '_'
57 identchars
= IDENTCHARS
63 doc_header
= "Documented commands (type help <topic>):"
64 misc_header
= "Miscellaneous help topics:"
65 undoc_header
= "Undocumented commands:"
66 nohelp
= "*** No help on %s"
69 def __init__(self
, completekey
='tab'):
73 readline
.set_completer(self
.complete
)
74 readline
.parse_and_bind(completekey
+": complete")
78 def cmdloop(self
, intro
=None):
87 line
= self
.cmdqueue
[0]
92 line
= raw_input(self
.prompt
)
96 sys
.stdout
.write(self
.prompt
)
97 line
= sys
.stdin
.readline()
101 line
= line
[:-1] # chop \n
102 line
= self
.precmd(line
)
103 stop
= self
.onecmd(line
)
104 stop
= self
.postcmd(stop
, line
)
107 def precmd(self
, line
):
110 def postcmd(self
, stop
, line
):
119 def parseline(self
, line
):
122 return None, None, line
124 line
= 'help ' + line
[1:]
126 if hasattr(self
, 'do_shell'):
127 line
= 'shell ' + line
[1:]
129 return None, None, line
131 while i
< n
and line
[i
] in self
.identchars
: i
= i
+1
132 cmd
, arg
= line
[:i
], line
[i
:].strip()
133 return cmd
, arg
, line
135 def onecmd(self
, line
):
136 cmd
, arg
, line
= self
.parseline(line
)
138 return self
.emptyline()
140 return self
.default(line
)
143 return self
.default(line
)
146 func
= getattr(self
, 'do_' + cmd
)
147 except AttributeError:
148 return self
.default(line
)
153 return self
.onecmd(self
.lastcmd
)
155 def default(self
, line
):
156 print '*** Unknown syntax:', line
158 def completedefault(self
, *ignored
):
161 def completenames(self
, text
, *ignored
):
163 return [a
[3:] for a
in self
.get_names() if a
.startswith(dotext
)]
165 def complete(self
, text
, state
):
166 """Return the next possible completion for 'text'.
168 If a command has not been entered, then complete against command list.
169 Otherwise try to call complete_<command> to get list of completions.
173 origline
= readline
.get_line_buffer()
174 line
= origline
.lstrip()
175 stripped
= len(origline
) - len(line
)
176 begidx
= readline
.get_begidx() - stripped
177 endidx
= readline
.get_endidx() - stripped
179 cmd
, args
, foo
= self
.parseline(line
)
181 compfunc
= self
.completedefault
184 compfunc
= getattr(self
, 'complete_' + cmd
)
185 except AttributeError:
186 compfunc
= self
.completedefault
188 compfunc
= self
.completenames
189 self
.completion_matches
= compfunc(text
, line
, begidx
, endidx
)
191 return self
.completion_matches
[state
]
196 # Inheritance says we have to look in class and
197 # base classes; order is not important.
199 classes
= [self
.__class
__]
203 classes
= classes
+ list(aclass
.__bases
__)
204 names
= names
+ dir(aclass
)
208 def complete_help(self
, *args
):
209 return self
.completenames(*args
)
211 def do_help(self
, arg
):
213 # XXX check arg syntax
215 func
= getattr(self
, 'help_' + arg
)
218 doc
=getattr(self
, 'do_' + arg
).__doc
__
224 print self
.nohelp
% (arg
,)
228 names
= self
.get_names()
233 if name
[:5] == 'help_':
236 # There can be duplicates if routines overridden
239 if name
[:3] == 'do_':
244 if help.has_key(cmd
):
247 elif getattr(self
, name
).__doc
__:
250 cmds_undoc
.append(cmd
)
251 print self
.doc_leader
252 self
.print_topics(self
.doc_header
, cmds_doc
, 15,80)
253 self
.print_topics(self
.misc_header
, help.keys(),15,80)
254 self
.print_topics(self
.undoc_header
, cmds_undoc
, 15,80)
256 def print_topics(self
, header
, cmds
, cmdlen
, maxcol
):
260 print self
.ruler
* len(header
)
261 (cmds_per_line
,junk
)=divmod(maxcol
,cmdlen
)
265 print (("%-"+`cmdlen`
+"s") % cmd
),
266 col
= (col
+1) % cmds_per_line