Description: This module let "tab" key can indent and completing valid python identifiers, keywords, and filenames. This module support history view also.
Note1: original python rlcompleter module only avail in unix-like environment Note2: if you seek a more simple completer you could try Jian Ding Chen's recipe at: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496812 Source: Text Source
__author__ = 'Sunjoong LEE ' __date__ = '2006-06-29' __version__ = '1.0'
from atexit import register from itertools import count as icount, ifilter, imap from os import listdir, remove from os.path import exists, expanduser, split as psplit from readline import clear_history, get_current_history_length, \ get_completer_delims, get_history_item, get_line_buffer, \ insert_text, parse_and_bind, read_history_file, redisplay, \ set_completer, set_completer_delims, set_history_length, \ set_pre_input_hook, write_history_file from pwd import getpwall from rlcompleter import Completer from tempfile import mktemp
import __main__
historyPath = expanduser('~/.pyhistory') HISTORY_LENGTH = 100
class History: def __init__(self): self.recall() set_history_length(HISTORY_LENGTH)
parse_and_bind('tab: complete') delims = ' \t\n`!@#$%^&*()-=+[{]}\\|;:,<>?' set_completer_delims(delims) set_completer(irlcompleter().complete)
def __repr__(self): """print out current history information""" command = get_history_item(get_current_history_length()) if command == 'history': length = get_current_history_length() if length > 1: return reduce(lambda x, y: '%s\n%s' % (x, y), imap(get_history_item, xrange(1, length))) else: return '' else: return '<%s instance>' % __name__
def __call__(self): """print out current history information with line number""" length = get_current_history_length() if length > 1: kount = icount(1).next for command in imap(get_history_item, xrange(1, length)): print '%s\t%s' % (kount(), command)
def save(self, filename, pos = None, end = None): """write history number from pos to end into filename file""" length = get_current_history_length() if length > 1: if not pos: pos = 1 elif pos >= length - 1: pos = length - 1 elif pos < 1: pos = length + pos - 1 if not end: end = length elif end >= length: end = length if end < 0: end = length + end else: end = end + 1
fp = open(filename, 'w') write = fp.write if pos < end: map(lambda x: write('%s\n' % x), imap(get_history_item, xrange(pos, end))) else: write('%s\n' % get_history_item(pos)) fp.close()
def clear(self): """save the current history and clear it""" write_history_file(historyPath) clear_history()
def recall(self, historyPath = historyPath): """clear the current history and recall it from saved""" clear_history() if exists(historyPath): read_history_file(historyPath)
def execute(self, pos, end = None): """execute history number from pos to end""" length = get_current_history_length() if length > 1: if pos >= length - 1: pos = length - 1 elif pos < 1: pos = length + pos - 1 if not end: end = pos + 1 elif end >= length: end = length if end < 0: end = length + end else: end = end + 1
to_execute = map(get_history_item, xrange(pos, end))
filename = mktemp() fp = open(filename, 'w') write = fp.write map(lambda x: write('%s\n' % x), to_execute.__iter__()) fp.close()
try: execfile(filename, __main__.__dict__) read_history_file(filename) remove(filename) except: remove(filename)
class irlcompleter(Completer): def complete(self, text, state): if text == '': return [' ', None][state] elif text.count("'") == 1: if not state: self.file_matches(text, "'") try: return self.matches[state] except IndexError: return None elif text.count('"') == 1: if not state: self.file_matches(text, '"') try: return self.matches[state] except IndexError: return None else: return Completer.complete(self, text, state)
def file_matches(self, text, mark): if '~' in text: if '/' in text: text = '%s%s%s' % (mark, expanduser( text[text.find('~'):text.find('/')]), text[text.find('/'):]) else: self.user_matches(text, mark) return
text1 = text[1:] delim = '/'
if not text1: directory = '' elif text1 == '.': directory = '.' elif text1 == '..': directory = '..' elif text1 == '/': directory = '/' delim = '' elif text1[-1] == '/': directory = text1[:-1] delim = text1[len(directory):] else: directory, partial = psplit(text1) delim = text1[len(directory):][:-len(partial)]
if directory: listing = map(lambda x: '%s%s%s%s' % (mark, directory, delim, x), listdir(directory).__iter__()) else: listing = map(lambda x: '%s%s' % (mark, x), listdir('.').__iter__())
n = len(text) self.matches = filter(lambda x: x[:n] == text, listing.__iter__())
def user_matches(self, text, mark): n = len(text) self.matches = filter(lambda x: x[:n] == text, imap(lambda x: '%s~%s' % (mark, x[0]), getpwall().__iter__()))
def save_history(historyPath = historyPath): from readline import write_history_file write_history_file(historyPath) register(save_history)
def hook(): from readline import set_pre_input_hook import __main__ set_pre_input_hook() delattr(__main__, 'History') delattr(__main__, '__file__') set_pre_input_hook(hook) setattr(__main__.__builtins__, 'history', History())
Discussion: To show an example, I had input as below; i[tab][tab]m[tab] pwd[return] pri[tab] pwd.[tab]__do[tab][return] fp = op[tab]('/[tab][tab]e[tab]/pas[tab]', 'r')[return] hi[tab][return]
>>> i i if in int is issubclass id import input intern isinstance iter
>>> import pwd >>> print pwd. pwd.__class__ pwd.__init__ pwd.__str__ pwd.__delattr__ pwd.__name__ pwd.getpwall pwd.__dict__ pwd.__new__ pwd.getpwnam pwd.__doc__ pwd.__reduce__ pwd.getpwuid pwd.__file__ pwd.__reduce_ex__ pwd.struct_passwd pwd.__getattribute__ pwd.__repr__ pwd.struct_pwent pwd.__hash__ pwd.__setattr__
>>> fp = open('/ '/bin '/home '/mnt '/sbin '/boot '/lib '/opt '/tmp '/dev '/lost+found '/proc '/usr '/etc '/media '/root '/var
>>> history import pwd print pwd.__doc__ fp = open('/etc/passwd', 'r') |
No comments:
Post a Comment