Mercurial > sqlpython
comparison cmd2.py @ 21:8b55aaa52ce9
working on load, and preserving stdin/out
author | devlinjs@FA7CZA6N1254998.wrightpatterson.afmc.ds.af.mil |
---|---|
date | Wed, 19 Dec 2007 13:40:39 -0500 |
parents | d6d64c2e3b98 |
children | 221095f3a4af |
comparison
equal
deleted
inserted
replaced
20:d6d64c2e3b98 | 21:8b55aaa52ce9 |
---|---|
2 | 2 |
3 Searchable command history | 3 Searchable command history |
4 Multi-line commands | 4 Multi-line commands |
5 Case-insensitive commands | 5 Case-insensitive commands |
6 Special-character shortcut commands | 6 Special-character shortcut commands |
7 | |
8 still to do: | |
9 environment (maxrows, etc.) | |
10 edit | |
11 | |
7 """ | 12 """ |
8 import cmd, re, os | 13 import cmd, re, os |
9 | 14 |
10 class Cmd(cmd.Cmd): | 15 class Cmd(cmd.Cmd): |
11 excludeFromHistory = '''run r list l history hi ed li'''.split() | |
12 caseInsensitive = True | 16 caseInsensitive = True |
13 multilineCommands = [] | 17 multilineCommands = [] |
14 continuationPrompt = '> ' | 18 continuationPrompt = '> ' |
15 shortcuts = {'?': 'help', '!': 'shell'} | 19 shortcuts = {'?': 'help', '!': 'shell', '@': 'load'} |
20 excludeFromHistory = '''run r list l history hi ed li'''.split() | |
21 defaultExtension = 'txt' | |
16 def __init__(self, *args, **kwargs): | 22 def __init__(self, *args, **kwargs): |
17 cmd.Cmd.__init__(self, *args, **kwargs) | 23 cmd.Cmd.__init__(self, *args, **kwargs) |
18 self.history = History() | 24 self.history = History() |
19 | 25 |
20 def precmd(self, line): | 26 def precmd(self, line): |
44 return stop | 50 return stop |
45 | 51 |
46 def finishStatement(self, firstline): | 52 def finishStatement(self, firstline): |
47 statement = firstline | 53 statement = firstline |
48 while not self.statementHasEnded(statement): | 54 while not self.statementHasEnded(statement): |
49 statement = '%s\n%s' % (statement, raw_input(self.continuationPrompt)) | 55 statement = '%s\n%s' % (statement, self.pseudo_raw_input(self.continuationPrompt)) |
50 return statement | 56 return statement |
51 # assembling a list of lines and joining them at the end would be faster, | 57 # assembling a list of lines and joining them at the end would be faster, |
52 # but statementHasEnded needs a string arg; anyway, we're getting | 58 # but statementHasEnded needs a string arg; anyway, we're getting |
53 # user input and users are slow. | 59 # user input and users are slow. |
54 | 60 |
61 def pseudo_raw_input(self, prompt): | |
62 """copied from cmd's cmdloop; like raw_input, but accounts for changed stdin, stdout""" | |
63 | |
64 if self.use_rawinput: | |
65 try: | |
66 line = raw_input(prompt) | |
67 except EOFError: | |
68 line = 'EOF' | |
69 else: | |
70 self.stdout.write(prompt) | |
71 self.stdout.flush() | |
72 line = self.stdin.readline() | |
73 if not len(line): | |
74 line = 'EOF' | |
75 else: | |
76 line = line[:-1] # chop \n | |
77 return line | |
78 | |
55 statementEndPattern = re.compile(r'[\n;]\s*$') | 79 statementEndPattern = re.compile(r'[\n;]\s*$') |
56 def statementHasEnded(self, lines): | 80 def statementHasEnded(self, lines): |
57 """This version lets statements end with ; or with a blank line. | 81 """This version lets statements end with ; or with a blank line. |
58 Override for your own needs.""" | 82 Override for your own needs.""" |
59 return bool(self.statementEndPattern.search(lines)) | 83 return bool(self.statementEndPattern.search(lines)) |
89 if arg: | 113 if arg: |
90 history = self.history.get(arg) | 114 history = self.history.get(arg) |
91 else: | 115 else: |
92 history = self.history | 116 history = self.history |
93 for hi in history: | 117 for hi in history: |
94 hi.pr() | 118 self.stdout.write(hi.pr()) |
95 def last_matching(self, arg): | 119 def last_matching(self, arg): |
96 try: | 120 try: |
97 if arg: | 121 if arg: |
98 return self.history.get(arg)[-1] | 122 return self.history.get(arg)[-1] |
99 else: | 123 else: |
108 - arg, arg - (integer) -> list up to or after #arg | 132 - arg, arg - (integer) -> list up to or after #arg |
109 arg is string -> list last command matching string search | 133 arg is string -> list last command matching string search |
110 arg is /enclosed in forward-slashes/ -> regular expression search | 134 arg is /enclosed in forward-slashes/ -> regular expression search |
111 """ | 135 """ |
112 try: | 136 try: |
113 self.last_matching(arg).pr() | 137 self.stdout.write(self.last_matching(arg).pr()) |
114 except: | 138 except: |
115 pass | 139 pass |
116 do_hi = do_history | 140 do_hi = do_history |
117 do_l = do_list | 141 do_l = do_list |
118 do_li = do_list | 142 do_li = do_list |
143 | |
144 def breakupStatements(self, txt): | |
145 """takes text that may include multiple statements and | |
146 breaks it into a list of individual statements.""" | |
147 result = [''] | |
148 for line in txt.splitlines(): | |
149 result[-1] += line | |
150 if self.statementHasEnded(result[-1]): | |
151 result.append('') | |
152 | |
153 def do_load(self, fname): | |
154 """Runs command(s) from a file.""" | |
155 stdin = self.stdin | |
156 try: | |
157 self.stdin = open(fname, 'r') | |
158 except IOError, e: | |
159 try: | |
160 self.stdin = open('%s.%s' % (fname, self.defaultExtension), 'r') | |
161 except: | |
162 print 'Problem opening file %s: \n%s' % (fname, e) | |
163 self.stdin = stdin | |
164 return | |
165 use_rawinput = self.use_rawinput | |
166 self.use_rawinput = False | |
167 print 'stdin = ' + str(self.stdin) | |
168 self.cmdloop() | |
169 self.stdin.close() | |
170 self.stdin = stdin | |
171 self.use_rawinput = use_rawinput | |
119 | 172 |
120 class HistoryItem(str): | 173 class HistoryItem(str): |
121 def __init__(self, instr): | 174 def __init__(self, instr): |
122 str.__init__(self, instr) | 175 str.__init__(self, instr) |
123 self.lowercase = self.lower() | 176 self.lowercase = self.lower() |
124 self.idx = None | 177 self.idx = None |
125 def pr(self): | 178 def pr(self): |
126 print '-------------------------[%d]' % (self.idx) | 179 return '-------------------------[%d]\n%s\n' % (self.idx, str(self)) |
127 print self | |
128 | 180 |
129 class History(list): | 181 class History(list): |
130 rangeFrom = re.compile(r'^([\d])+\s*\-$') | 182 rangeFrom = re.compile(r'^([\d])+\s*\-$') |
131 def append(self, new): | 183 def append(self, new): |
132 new = HistoryItem(new) | 184 new = HistoryItem(new) |