[tor-commits] [stem/master] Caching autocompletion matches

atagar at torproject.org atagar at torproject.org
Tue May 6 01:21:13 UTC 2014


commit 71028da33515673c7f5df55b46e2235833741352
Author: Damian Johnson <atagar at 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





More information about the tor-commits mailing list