[IPython-User] Problem: Custom Tab-Completion through Pyreadline

Jörgen Stenarson jorgen.stenarson@bostream...
Thu Jul 1 13:39:58 CDT 2010


If you could provide a complete example that we can test for ourselves, 
i.e. attached .py files, it would be easier to answer your question.

/Jörgen

yaluen@uw.edu skrev 2010-06-30 09:08:
> 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
>
>
>
> _______________________________________________
> IPython-User mailing list
> IPython-User@scipy.org
> http://mail.scipy.org/mailman/listinfo/ipython-user



More information about the IPython-User mailing list