11# A generic class to build line-oriented command interpreters
2+ #
3+ # Interpreters constructed with this class obey the following conventions:
4+ #
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+ #
19+ # The `default' method may be overridden to intercept commands for which there
20+ # is no do_ method.
21+ #
22+ # The data member `self.ruler' sets the character used to draw separator lines
23+ # in the help messages. If empty, no ruler line is drawn. It defaults to "=".
24+ #
25+ # If the value of `self.intro' is nonempty when the cmdloop method is called,
26+ # it is printed out on interpreter startup. This value may be overridden
27+ # via an optional argument to the cmdloop() method.
28+ #
29+ # The data members `self.doc_header', `self.misc_header', and
30+ # `self.undoc_header' set the headers used for the help function's
31+ # listings of documented functions, miscellaneous topics, and undocumented
32+ # functions respectively.
33+ #
34+ # These interpreters use raw_input; thus, if the readline module is loaded,
35+ # they automatically support Emacs-like command history and editing features.
36+ #
237
338import string
439import sys
843IDENTCHARS = string .letters + string .digits + '_'
944
1045class Cmd :
46+ prompt = PROMPT
47+ identchars = IDENTCHARS
48+ ruler = '='
49+ lastcmd = ''
50+ intro = None
51+ doc_header = "Documented commands (type help <topic>):"
52+ misc_header = "Miscellaneous help topics:"
53+ undoc_header = "Undocumented commands:"
1154
12- def __init__ (self ):
13- self .prompt = PROMPT
14- self . identchars = IDENTCHARS
15- self .lastcmd = ''
16-
17- def cmdloop ( self ):
55+ def cmdloop (self , intro = None ):
56+ self .preloop ()
57+ if intro != None :
58+ self .intro = intro
59+ if self . intro :
60+ print self . intro
1861 stop = None
1962 while not stop :
2063 try :
2164 line = raw_input (self .prompt )
2265 except EOFError :
2366 line = 'EOF'
67+ self .precmd ()
2468 stop = self .onecmd (line )
69+ self .postcmd ()
70+ self .postloop ()
71+
72+ def precmd (self ):
73+ pass
74+
75+ def postcmd (self ):
76+ pass
77+
78+ def preloop (self ):
79+ pass
80+
81+ def postloop (self ):
82+ pass
2583
2684 def onecmd (self , line ):
2785 line = string .strip (line )
28- if not line :
29- line = self .lastcmd
30- else :
31- self .lastcmd = line
86+ if line == '?' :
87+ line = 'help'
88+ elif line == '!' :
89+ if hasattr (self , 'do_shell' ):
90+ line = 'shell'
91+ else :
92+ self .default (line )
93+ return
94+ elif not line :
95+ self .emptyline ()
96+ return
97+ self .lastcmd = line
3298 i , n = 0 , len (line )
3399 while i < n and line [i ] in self .identchars : i = i + 1
34100 cmd , arg = line [:i ], string .strip (line [i :])
@@ -41,6 +107,9 @@ def onecmd(self, line):
41107 return self .default (line )
42108 return func (arg )
43109
110+ def emptyline (self ):
111+ return self .onecmd (self .lastcmd )
112+
44113 def default (self , line ):
45114 print '*** Unknown syntax:' , line
46115
@@ -70,17 +139,15 @@ def do_help(self, arg):
70139 else :
71140 cmds_undoc .append (cmd )
72141 print
73- self .print_topics ("Documented commands (type help " \
74- "<topic>):" ,cmds_doc , 15 , 80 )
75- self .print_topics ("Miscellaneous help topics:" ,
76- help .keys (), 15 , 80 )
77- self .print_topics ("Undocumented commands:" ,
78- cmds_undoc , 15 , 80 )
142+ self .print_topics (self .doc_header , cmds_doc , 15 ,80 )
143+ self .print_topics (self .misc_header , help .keys (),15 ,80 )
144+ self .print_topics (self .undoc_header , cmds_undoc , 15 ,80 )
79145
80146 def print_topics (self , header , cmds , cmdlen , maxcol ):
81147 if cmds :
82148 print header ;
83- print "=" * len (header )
149+ if self .ruler :
150+ print self .ruler * len (header )
84151 (cmds_per_line ,junk )= divmod (maxcol ,cmdlen )
85152 col = cmds_per_line
86153 for cmd in cmds :
0 commit comments