|
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 <sunjoong@gmail.com>'
__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')
|
|
Add comment
|
|
Number of comments: 9
history view, Sunjoong LEE, 2006/06/26
>>> history
Add comment
history view with number, Sunjoong LEE, 2006/06/26
>>> history()
Add comment
save history to another file, Sunjoong LEE, 2006/06/26
>>> history.save('saved.py')
Add comment
save history number from 1 to 3 into 'saved.py', Sunjoong LEE, 2006/06/26
>>> history.save('saved.py', 1, 3)
Add comment
clear history buffer, Sunjoong LEE, 2006/06/26
>>> history.clear()
Add comment
recall history, Sunjoong LEE, 2006/06/26
>>> history.recall()
Add comment
recall history from another file, Sunjoong LEE, 2006/06/26
>>> history.recall('saved.py')
Add comment
execute history, Sunjoong LEE, 2006/06/28
>>> a = 1
>>> b = a + 1
>>> c = b + 1
>>> print a, b, c
1 2 3
>>> history()
1 a = 1
2 b = a + 1
3 c = b + 1
4 print a, b, c
>>> a = 2
>>> history.run(2, 4)
2 3 4
Add comment
change history.run to history.execute, Sunjoong LEE, 2006/06/28
I has changed the run mathod name to execute.
Add comment
|
|
|