commit 71028da33515673c7f5df55b46e2235833741352 Author: Damian Johnson atagar@torproject.org Date: Sat Apr 19 17:00:16 2014 -0700
Caching autocompletion matches
Readline's autocompletion is kinda weird. It uses a function of the form...
matches(text, state)
... where the state is the index of the match to be returned. This is probably to match the underlying C readline funcion (ahhh, the world before dynamically allocated lists).
Considering that we're calling the match function N+1 times where N is the number of autocompletion matches we might as well cache the results. The autocompleter should have a match function that returns a list of matches anyway. --- stem/interpretor/autocomplete.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/stem/interpretor/autocomplete.py b/stem/interpretor/autocomplete.py index 09c5365..ff61941 100644 --- a/stem/interpretor/autocomplete.py +++ b/stem/interpretor/autocomplete.py @@ -4,6 +4,12 @@ Tab completion for our interpretor prompt.
from stem.interpretor import uses_settings
+try: + # added in python 3.2 + from functools import lru_cache +except ImportError: + from stem.util.lru_cache import lru_cache +
@uses_settings def _get_commands(config, controller): @@ -83,16 +89,33 @@ class Autocompleter(object): def __init__(self, controller): self._commands = _get_commands(controller)
+ @lru_cache() + def matches(self, text): + """ + Provides autocompletion matches for the given text. + + :param str text: text to check for autocompletion matches with + + :returns: **list** with possible matches + """ + + lowercase_text = text.lower() + return [cmd for cmd in self._commands if cmd.lower().startswith(lowercase_text)] + def complete(self, text, state): """ Provides case insensetive autocompletion options, acting as a functor for the readlines set_completer function. - """
- lowercase_text = text.lower() - prefix_matches = [cmd for cmd in self._commands if cmd.lower().startswith(lowercase_text)] + :param str text: text to check for autocompletion matches with + :param int state: index of result to be provided, readline fetches matches + until this function provides None + + :returns: **str** with the autocompletion match, **None** if eithe none + exists or state is higher than our number of matches + """
- if state < len(prefix_matches): - return prefix_matches[state] - else: + try: + return self.matches(text)[state] + except IndexError: return None
tor-commits@lists.torproject.org