# HG changeset patch # User devlinjs@FA7CZA6N1254998.wrightpatterson.afmc.ds.af.mil # Date 1198082963 18000 # Node ID d6d64c2e3b987cf3e53ee2b6c9fcc75d784f4d9b # Parent 25f22e742a6827f630ea31cfaabcf88807943edf shortcuts diff -r 25f22e742a68 -r d6d64c2e3b98 cmd2.py --- a/cmd2.py Wed Dec 19 11:30:13 2007 -0500 +++ b/cmd2.py Wed Dec 19 11:49:23 2007 -0500 @@ -1,51 +1,18 @@ -import cmd, re +"""Variant on standard library's cmd with extra features: -class HistoryItem(str): - def __init__(self, instr): - str.__init__(self, instr) - self.lowercase = self.lower() - self.idx = None - def pr(self): - print '-------------------------[%d]' % (self.idx) - print self - -class History(list): - rangeFrom = re.compile(r'^([\d])+\s*\-$') - def append(self, new): - new = HistoryItem(new) - list.append(self, new) - new.idx = len(self) - def extend(self, new): - for n in new: - self.append(n) - def get(self, getme): - try: - getme = int(getme) - if getme < 0: - return self[:(-1 * getme)] - else: - return [self[getme-1]] - except IndexError: - return [] - except (ValueError, TypeError): - getme = getme.strip() - mtch = self.rangeFrom.search(getme) - if mtch: - return self[(int(mtch.group(1))-1):] - if getme.startswith(r'/') and getme.endswith(r'/'): - finder = re.compile(getme[1:-1], re.DOTALL | re.MULTILINE | re.IGNORECASE) - def isin(hi): - return finder.search(hi) - else: - def isin(hi): - return (getme.lower() in hi.lowercase) - return [itm for itm in self if isin(itm)] +Searchable command history +Multi-line commands +Case-insensitive commands +Special-character shortcut commands +""" +import cmd, re, os class Cmd(cmd.Cmd): excludeFromHistory = '''run r list l history hi ed li'''.split() caseInsensitive = True multilineCommands = [] continuationPrompt = '> ' + shortcuts = {'?': 'help', '!': 'shell'} def __init__(self, *args, **kwargs): cmd.Cmd.__init__(self, *args, **kwargs) self.history = History() @@ -91,6 +58,26 @@ Override for your own needs.""" return bool(self.statementEndPattern.search(lines)) + def parseline(self, line): + """Parse the line into a command name and a string containing + the arguments. Returns a tuple containing (command, args, line). + 'command' and 'args' may be None if the line couldn't be parsed. + """ + line = line.strip() + if not line: + return None, None, line + shortcut = self.shortcuts.get(line[0]) + if shortcut and hasattr(self, 'do_%s' % shortcut): + line = '%s %s' % (shortcut, line[1:]) + i, n = 0, len(line) + while i < n and line[i] in self.identchars: i = i+1 + cmd, arg = line[:i], line[i:].strip() + return cmd, arg, line + + def do_shell(self, arg): + 'execute a command as if at the OS prompt.' + os.system(arg) + def do_history(self, arg): """history [arg]: lists past commands issued @@ -129,6 +116,47 @@ do_hi = do_history do_l = do_list do_li = do_list - + +class HistoryItem(str): + def __init__(self, instr): + str.__init__(self, instr) + self.lowercase = self.lower() + self.idx = None + def pr(self): + print '-------------------------[%d]' % (self.idx) + print self + +class History(list): + rangeFrom = re.compile(r'^([\d])+\s*\-$') + def append(self, new): + new = HistoryItem(new) + list.append(self, new) + new.idx = len(self) + def extend(self, new): + for n in new: + self.append(n) + def get(self, getme): + try: + getme = int(getme) + if getme < 0: + return self[:(-1 * getme)] + else: + return [self[getme-1]] + except IndexError: + return [] + except (ValueError, TypeError): + getme = getme.strip() + mtch = self.rangeFrom.search(getme) + if mtch: + return self[(int(mtch.group(1))-1):] + if getme.startswith(r'/') and getme.endswith(r'/'): + finder = re.compile(getme[1:-1], re.DOTALL | re.MULTILINE | re.IGNORECASE) + def isin(hi): + return finder.search(hi) + else: + def isin(hi): + return (getme.lower() in hi.lowercase) + return [itm for itm in self if isin(itm)] + diff -r 25f22e742a68 -r d6d64c2e3b98 sqlpyPlus.py --- a/sqlpyPlus.py Wed Dec 19 11:30:13 2007 -0500 +++ b/sqlpyPlus.py Wed Dec 19 11:49:23 2007 -0500 @@ -365,19 +365,11 @@ the arguments. Returns a tuple containing (command, args, line). 'command' and 'args' may be None if the line couldn't be parsed. Overrides cmd.cmd.parseline to accept variety of shortcuts..""" - line = line.strip() - if not line: - return None, None, line - shortcut = self.shortcuts.get(line[0]) - if shortcut: - cmd, arg = shortcut, line[1:].strip() - else: - i, n = 0, len(line) - while i < n and line[i] in self.identchars: i = i+1 - cmd, arg = line[:i], line[i:].strip() - if cmd.lower() in ('select', 'sleect', 'insert', 'update', 'delete', 'describe', + + cmd, arg. line = sqlpython.parseline(self, line) + if cmd in ('select', 'sleect', 'insert', 'update', 'delete', 'describe', 'desc', 'comments', 'pull', 'refs', 'desc', 'triggers', 'find') \ - and not hasattr(self, 'curs'): + and not hasattr(self, 'curs'): print 'Not connected.' return '', '', '' return cmd, arg, line @@ -426,7 +418,6 @@ for (scchar, scto) in self.shortcuts.items(): print '%s: %s' % (scchar, scto) - def colnames(self): return [d[0] for d in curs.description] @@ -689,10 +680,6 @@ def do_resolve(self, arg): print self.resolve(arg) - def do_shell(self, arg): - 'execute a command as if at the OS prompt.' - os.system(arg) - def spoolstop(self): if self.spoolFile: sys.stdout = self.stdoutBeforeSpool