[IPython-User] Problem: Custom Tab-Completion through Pyreadline
yaluen@u...
yaluen@u...
Wed Jun 30 02:08:15 CDT 2010
Hello,
I'm helping build a cross-platform custom tab completer for a Python research project, and I'm using Pyreadline to substitute for the the lack of readline on Windows. However, upon installation, despite trying to set-up the custom tab completion through the use of readline's set_completer function, pyreadline automatically uses the completer under basemode.py, shown when it printed out a list of files in the directory when I tabbed despite changing the custom tab complete function to raise an exception instead. When I ran through the code using the Python Debugger, I saw that set_completer(completer.complete) was clearly called under rlmain.py, yet the custom tab complete function wasn't implemented in the readline somehow.
I'm using version 1.5 of Pyreadline, installed under a custom directory of the research project that essentially uses Python 2.5. I'm testing all this through Windows command prompt. I might have overlooked some details since I'm still fairly new to Python, but any help would be much appreciated.
For reference, I didn't write the TabCompleter code, and it works when used in a Unix system with their GNU Readline.
Thanks,
Alan Loh
This is the code for the custom tab completion part of the project:
tabcompletion = True
try:
import readline
except ImportError:
print "Auto tab completion is off, because it is not available on your operating system."
tabcompletion = False
.
.
.
# Set up the tab completion environment
if tabcompletion:
completer = TabCompleter()
readline.parse_and_bind("tab: complete")
readline.set_completer_delims(" ")
readline.set_completer(completer.complete)
...and this is the TabCompleter class I'm trying to help implement.
class TabCompleter:
# Constructor that initializes all the private variables
def __init__(self):
# list of files that match the directory of the given prefix
self._words = []
# list of files that match the given prefix
self._matching_words = []
self._prefix = None
# Returns the path from a given prefix, by extracting the string up to the
# last forward slash in the prefix. If no forward slash is found, returns an
# empty string.
def _getpath(self, prefix):
slashpos = prefix.rfind("/")
currentpath = ""
if slashpos > -1:
currentpath = prefix[0 : slashpos+1]
return currentpath
# Returns the file name, or a part of the file name, from a given prefix, by
# extracting the string after the last forward slash in the prefix. If no
# forward slash is found, returns an empty string.
def _getfilename(self, prefix):
# Find the last occurrence of the slash (if any), as it separates the path
# and the file name.
slashpos = prefix.rfind("/")
filename = ""
# If slash exists and there are characters after the last slash, then the
# file name is whatever that follows the last slash.
if slashpos > -1 and slashpos+1 <= len(prefix)-1:
filename = prefix[slashpos+1:]
# If no slash is found, then we assume that the entire user input is the
# prefix of a file name because it does not contain a directory
elif slashpos == -1:
filename = prefix
# If both cases fail, then the entire user input is the name of a
# directory. Thus, we return the file name as an empty string.
return filename
# Returns a list of file names that start with the given prefix.
def _listfiles(self, prefix):
# Find the directory specified by the prefix
currentpath = self._getpath(prefix)
if not currentpath:
currentpath = "./"
filelist = []
# Attempt to list files from the directory
try:
currentpath = os.path.expanduser(currentpath)
filelist = os.listdir(currentpath)
except:
# We are silently dropping all exceptions because the directory specified
# by the prefix may be incorrect. In this case, we're returning an empty
# list, similar to what you would get when you TAB a wrong name in the
# Unix shell.
pass
finally:
return filelist
# The completer function required as a callback by the readline module. See
# also http://docs.python.org/library/readline.html#readline.set_completer
def complete(self, prefix, index):
# If the user updates the prefix, then we list files that start with the
# prefix.
if prefix != self._prefix:
self._words = self._listfiles(prefix)
fn = self._getfilename(prefix)
# Find the files that match the prefix
self._matching_words = []
for word in self._words:
if word.startswith(fn):
self._matching_words.append(word)
self._prefix = prefix
try:
return self._getpath(prefix) + self._matching_words[index]
except IndexError:
return None
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.scipy.org/pipermail/ipython-user/attachments/20100630/59c95abf/attachment.html
More information about the IPython-User
mailing list