blob: d0332aaf8f09f3d9d2558712115d460a8a78bc5e [file] [log] [blame]
Georg Brandl116aa622007-08-15 14:28:22 +00001:mod:`cmd` --- Support for line-oriented command interpreters
2=============================================================
3
4.. module:: cmd
5 :synopsis: Build line-oriented command interpreters.
6.. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>
7
8
9The :class:`Cmd` class provides a simple framework for writing line-oriented
10command interpreters. These are often useful for test harnesses, administrative
11tools, and prototypes that will later be wrapped in a more sophisticated
12interface.
13
14
Georg Brandl0d8f0732009-04-05 22:20:44 +000015.. class:: Cmd(completekey='tab', stdin=None, stdout=None)
Georg Brandl116aa622007-08-15 14:28:22 +000016
17 A :class:`Cmd` instance or subclass instance is a line-oriented interpreter
18 framework. There is no good reason to instantiate :class:`Cmd` itself; rather,
19 it's useful as a superclass of an interpreter class you define yourself in order
20 to inherit :class:`Cmd`'s methods and encapsulate action methods.
21
22 The optional argument *completekey* is the :mod:`readline` name of a completion
23 key; it defaults to :kbd:`Tab`. If *completekey* is not :const:`None` and
24 :mod:`readline` is available, command completion is done automatically.
25
26 The optional arguments *stdin* and *stdout* specify the input and output file
27 objects that the Cmd instance or subclass instance will use for input and
Georg Brandl0c77a822008-06-10 16:37:50 +000028 output. If not specified, they will default to :data:`sys.stdin` and
29 :data:`sys.stdout`.
30
31 If you want a given *stdin* to be used, make sure to set the instance's
32 :attr:`use_rawinput` attribute to ``False``, otherwise *stdin* will be
33 ignored.
Georg Brandl116aa622007-08-15 14:28:22 +000034
Georg Brandl116aa622007-08-15 14:28:22 +000035
36.. _cmd-objects:
37
38Cmd Objects
39-----------
40
41A :class:`Cmd` instance has the following methods:
42
43
Georg Brandl0d8f0732009-04-05 22:20:44 +000044.. method:: Cmd.cmdloop(intro=None)
Georg Brandl116aa622007-08-15 14:28:22 +000045
46 Repeatedly issue a prompt, accept input, parse an initial prefix off the
47 received input, and dispatch to action methods, passing them the remainder of
48 the line as argument.
49
50 The optional argument is a banner or intro string to be issued before the first
51 prompt (this overrides the :attr:`intro` class member).
52
53 If the :mod:`readline` module is loaded, input will automatically inherit
54 :program:`bash`\ -like history-list editing (e.g. :kbd:`Control-P` scrolls back
55 to the last command, :kbd:`Control-N` forward to the next one, :kbd:`Control-F`
56 moves the cursor to the right non-destructively, :kbd:`Control-B` moves the
57 cursor to the left non-destructively, etc.).
58
59 An end-of-file on input is passed back as the string ``'EOF'``.
60
61 An interpreter instance will recognize a command name ``foo`` if and only if it
62 has a method :meth:`do_foo`. As a special case, a line beginning with the
63 character ``'?'`` is dispatched to the method :meth:`do_help`. As another
64 special case, a line beginning with the character ``'!'`` is dispatched to the
65 method :meth:`do_shell` (if such a method is defined).
66
67 This method will return when the :meth:`postcmd` method returns a true value.
68 The *stop* argument to :meth:`postcmd` is the return value from the command's
69 corresponding :meth:`do_\*` method.
70
71 If completion is enabled, completing commands will be done automatically, and
72 completing of commands args is done by calling :meth:`complete_foo` with
73 arguments *text*, *line*, *begidx*, and *endidx*. *text* is the string prefix
74 we are attempting to match: all returned matches must begin with it. *line* is
75 the current input line with leading whitespace removed, *begidx* and *endidx*
76 are the beginning and ending indexes of the prefix text, which could be used to
77 provide different completion depending upon which position the argument is in.
78
Georg Brandlb2566cf2010-08-02 20:27:20 +000079 All subclasses of :class:`Cmd` inherit a predefined :meth:`do_help`. This
Georg Brandl116aa622007-08-15 14:28:22 +000080 method, called with an argument ``'bar'``, invokes the corresponding method
Georg Brandlb2566cf2010-08-02 20:27:20 +000081 :meth:`help_bar`, and if that is not present, prints the docstring of
82 :meth:`do_bar`, if available. With no argument, :meth:`do_help` lists all
83 available help topics (that is, all commands with corresponding
84 :meth:`help_\*` methods or commands that have docstrings), and also lists any
85 undocumented commands.
Georg Brandl116aa622007-08-15 14:28:22 +000086
87
88.. method:: Cmd.onecmd(str)
89
90 Interpret the argument as though it had been typed in response to the prompt.
91 This may be overridden, but should not normally need to be; see the
92 :meth:`precmd` and :meth:`postcmd` methods for useful execution hooks. The
93 return value is a flag indicating whether interpretation of commands by the
94 interpreter should stop. If there is a :meth:`do_\*` method for the command
95 *str*, the return value of that method is returned, otherwise the return value
96 from the :meth:`default` method is returned.
97
98
99.. method:: Cmd.emptyline()
100
101 Method called when an empty line is entered in response to the prompt. If this
102 method is not overridden, it repeats the last nonempty command entered.
103
104
105.. method:: Cmd.default(line)
106
107 Method called on an input line when the command prefix is not recognized. If
108 this method is not overridden, it prints an error message and returns.
109
110
111.. method:: Cmd.completedefault(text, line, begidx, endidx)
112
113 Method called to complete an input line when no command-specific
114 :meth:`complete_\*` method is available. By default, it returns an empty list.
115
116
117.. method:: Cmd.precmd(line)
118
119 Hook method executed just before the command line *line* is interpreted, but
120 after the input prompt is generated and issued. This method is a stub in
121 :class:`Cmd`; it exists to be overridden by subclasses. The return value is
122 used as the command which will be executed by the :meth:`onecmd` method; the
123 :meth:`precmd` implementation may re-write the command or simply return *line*
124 unchanged.
125
126
127.. method:: Cmd.postcmd(stop, line)
128
129 Hook method executed just after a command dispatch is finished. This method is
130 a stub in :class:`Cmd`; it exists to be overridden by subclasses. *line* is the
131 command line which was executed, and *stop* is a flag which indicates whether
132 execution will be terminated after the call to :meth:`postcmd`; this will be the
133 return value of the :meth:`onecmd` method. The return value of this method will
134 be used as the new value for the internal flag which corresponds to *stop*;
135 returning false will cause interpretation to continue.
136
137
138.. method:: Cmd.preloop()
139
140 Hook method executed once when :meth:`cmdloop` is called. This method is a stub
141 in :class:`Cmd`; it exists to be overridden by subclasses.
142
143
144.. method:: Cmd.postloop()
145
146 Hook method executed once when :meth:`cmdloop` is about to return. This method
147 is a stub in :class:`Cmd`; it exists to be overridden by subclasses.
148
149Instances of :class:`Cmd` subclasses have some public instance variables:
150
151
152.. attribute:: Cmd.prompt
153
154 The prompt issued to solicit input.
155
156
157.. attribute:: Cmd.identchars
158
159 The string of characters accepted for the command prefix.
160
161
162.. attribute:: Cmd.lastcmd
163
164 The last nonempty command prefix seen.
165
166
167.. attribute:: Cmd.intro
168
169 A string to issue as an intro or banner. May be overridden by giving the
170 :meth:`cmdloop` method an argument.
171
172
173.. attribute:: Cmd.doc_header
174
175 The header to issue if the help output has a section for documented commands.
176
177
178.. attribute:: Cmd.misc_header
179
180 The header to issue if the help output has a section for miscellaneous help
181 topics (that is, there are :meth:`help_\*` methods without corresponding
182 :meth:`do_\*` methods).
183
184
185.. attribute:: Cmd.undoc_header
186
187 The header to issue if the help output has a section for undocumented commands
188 (that is, there are :meth:`do_\*` methods without corresponding :meth:`help_\*`
189 methods).
190
191
192.. attribute:: Cmd.ruler
193
194 The character used to draw separator lines under the help-message headers. If
195 empty, no ruler line is drawn. It defaults to ``'='``.
196
197
198.. attribute:: Cmd.use_rawinput
199
200 A flag, defaulting to true. If true, :meth:`cmdloop` uses :func:`input` to
201 display a prompt and read the next command; if false, :meth:`sys.stdout.write`
202 and :meth:`sys.stdin.readline` are used. (This means that by importing
203 :mod:`readline`, on systems that support it, the interpreter will automatically
204 support :program:`Emacs`\ -like line editing and command-history keystrokes.)
205
Raymond Hettingerbd889e82010-09-09 01:40:50 +0000206Cmd Example
Alexander Belopolskyf0a0d142010-10-27 03:06:43 +0000207-----------
Raymond Hettingerbd889e82010-09-09 01:40:50 +0000208
209.. sectionauthor:: Raymond Hettinger <python at rcn dot com>
210
211The :mod:`cmd` module is mainly useful for building custom shells that let a
212user work with a program interactively.
213
214This section presents a simple example of how to build a shell around a few of
215the commands in the :mod:`turtle` module.
216
217Basic turtle commands such as :meth:`~turtle.forward` are added to a
218:class:`Cmd` subclass with method named :meth:`do_forward`. The argument is
219converted to a number and dispatched to the turtle module. The docstring is
220used in the help utility provided by the shell.
221
222The example also includes a basic record and playback facility implemented with
223the :meth:`~Cmd.precmd` method which is responsible for converting the input to
224lowercase and writing the commands to a file. The :meth:`do_playback` method
225reads the file and adds the recorded commands to the :attr:`cmdqueue` for
226immediate playback::
227
228 import cmd, sys
229 from turtle import *
230
231 class TurtleShell(cmd.Cmd):
232 intro = 'Welcome to the turtle shell. Type help or ? to list commands.\n'
233 prompt = '(turtle) '
234 file = None
235
236 # ----- basic turtle commands -----
237 def do_forward(self, arg):
238 'Move the turtle forward by the specified distance: FORWARD 10'
239 forward(*parse(arg))
240 def do_right(self, arg):
241 'Turn turtle right by given number of degrees: RIGHT 20'
242 right(*parse(arg))
243 def do_left(self, arg):
244 'Turn turtle left by given number of degrees: LEFT 90'
245 right(*parse(arg))
246 def do_goto(self, arg):
247 'Move turtle to an absolute position with changing orientation. GOTO 100 200'
248 goto(*parse(arg))
249 def do_home(self, arg):
250 'Return turtle to the home postion: HOME'
251 home()
252 def do_circle(self, arg):
253 'Draw circle with given radius an options extent and steps: CIRCLE 50'
254 circle(*parse(arg))
255 def do_position(self, arg):
256 'Print the current turle position: POSITION'
257 print('Current position is %d %d\n' % position())
258 def do_heading(self, arg):
259 'Print the current turle heading in degrees: HEADING'
260 print('Current heading is %d\n' % (heading(),))
261 def do_color(self, arg):
262 'Set the color: COLOR BLUE'
263 color(arg.lower())
264 def do_undo(self, arg):
265 'Undo (repeatedly) the last turtle action(s): UNDO'
266 def do_reset(self, arg):
267 'Clear the screen and return turtle to center: RESET'
268 reset()
269 def do_bye(self, arg):
270 'Stop recording, close the turtle window, and exit: BYE'
271 print('Thank you for using Turtle')
272 self.close()
273 bye()
274 sys.exit(0)
275
276 # ----- record and playback -----
277 def do_record(self, arg):
278 'Save future commands to filename: RECORD rose.cmd'
279 self.file = open(arg, 'w')
280 def do_playback(self, arg):
281 'Playback commands from a file: PLAYBACK rose.cmd'
282 self.close()
283 cmds = open(arg).read().splitlines()
284 self.cmdqueue.extend(cmds)
285 def precmd(self, line):
286 line = line.lower()
287 if self.file and 'playback' not in line:
288 print(line, file=self.file)
289 return line
290 def close(self):
291 if self.file:
292 self.file.close()
293 self.file = None
294
295 def parse(arg):
296 'Convert a series of zero or more numbers to an argument tuple'
297 return tuple(map(int, arg.split()))
298
299 if __name__ == '__main__':
300 TurtleShell().cmdloop()
301
302
303Here is a sample session with the turtle shell showing the help functions, using
304blank lines to repeat commands, and the simple record and playback facility::
305
306 Welcome to the turtle shell. Type help or ? to list commands.
307
308 (turtle) ?
309
310 Documented commands (type help <topic>):
311 ========================================
312 bye color goto home playback record right
313 circle forward heading left position reset undo
314
Raymond Hettingerbd889e82010-09-09 01:40:50 +0000315 (turtle) help forward
316 Move the turtle forward by the specified distance: FORWARD 10
317 (turtle) record spiral.cmd
318 (turtle) position
319 Current position is 0 0
320
321 (turtle) heading
322 Current heading is 0
323
324 (turtle) reset
325 (turtle) circle 20
326 (turtle) right 30
327 (turtle) circle 40
328 (turtle) right 30
329 (turtle) circle 60
330 (turtle) right 30
331 (turtle) circle 80
332 (turtle) right 30
333 (turtle) circle 100
334 (turtle) right 30
335 (turtle) circle 120
336 (turtle) right 30
337 (turtle) circle 120
338 (turtle) heading
339 Current heading is 180
340
341 (turtle) forward 100
342 (turtle)
343 (turtle) right 90
344 (turtle) forward 100
345 (turtle)
346 (turtle) right 90
347 (turtle) forward 400
348 (turtle) right 90
349 (turtle) forward 500
350 (turtle) right 90
351 (turtle) forward 400
352 (turtle) right 90
353 (turtle) forward 300
354 (turtle) playback spiral.cmd
355 Current position is 0 0
356
357 Current heading is 0
358
359 Current heading is 180
360
361 (turtle) bye
362 Thank you for using Turtle
363