[tor-commits] [arm/release] Basic tab completion for interpretor panel

atagar at torproject.org atagar at torproject.org
Sun Sep 25 21:38:27 UTC 2011


commit 7b58a20d69150d3628b758ddef7c014b740cb5de
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Aug 28 18:27:16 2011 -0700

    Basic tab completion for interpretor panel
    
    This performs tab completion in the interpretor panel when there's a single
    match. This does not, however, provide suggestions or common prefix completion
    yet. The suggestions in particular are gonna be a pita...
---
 src/cli/interpretorPanel.py |    3 +++
 src/util/textInput.py       |   34 ++++++++++++++++++++++++++++++++++
 src/util/torInterpretor.py  |   16 +++++++++++++++-
 3 files changed, 52 insertions(+), 1 deletions(-)

diff --git a/src/cli/interpretorPanel.py b/src/cli/interpretorPanel.py
index 162fd19..95866db 100644
--- a/src/cli/interpretorPanel.py
+++ b/src/cli/interpretorPanel.py
@@ -61,8 +61,11 @@ class InterpretorPanel(panel.Panel):
       self.redraw(True)
       
       # intercepts input so user can cycle through the history
+      torCommands = torInterpretor.TorCommandOptions()
+      
       validator = textInput.BasicValidator()
       validator = textInput.HistoryValidator(self.previousCommands, validator)
+      validator = textInput.TabCompleter(torCommands.getMatches, validator)
       
       xOffset = len(torInterpretor.PROMPT)
       if len(self.contents) > self.maxY - 1:
diff --git a/src/util/textInput.py b/src/util/textInput.py
index c3c229f..31a5305 100644
--- a/src/util/textInput.py
+++ b/src/util/textInput.py
@@ -148,3 +148,37 @@ class HistoryValidator(TextInputValidator):
     
     return PASS
 
+class TabCompleter(TextInputValidator):
+  """
+  Provides tab completion based on the current input, finishing if there's only
+  a single match. This expects a functor that accepts the current input and
+  provides matches.
+  """
+  
+  def __init__(self, completer, nextValidator = None):
+    TextInputValidator.__init__(self, nextValidator)
+    
+    # functor that accepts a string and gives a list of matches
+    self.completer = completer
+  
+  def handleKey(self, key, textbox):
+    # Matches against the tab key. The ord('\t') is nine, though strangely none
+    # of the curses.KEY_*TAB constants match this...
+    if key == 9:
+      matches = self.completer(textbox.gather().strip())
+      
+      if len(matches) == 1:
+        # only a single match, fill it in
+        newInput = matches[0]
+        y, _ = textbox.win.getyx()
+        _, maxX = textbox.win.getmaxyx()
+        textbox.win.clear()
+        textbox.win.addstr(y, 0, newInput[:maxX - 1])
+        textbox.win.move(y, min(len(newInput), maxX - 1))
+      elif len(matches) > 1:
+        pass # TODO: somehow display matches... this is not gonna be fun
+      
+      return None
+    
+    return PASS
+
diff --git a/src/util/torInterpretor.py b/src/util/torInterpretor.py
index fecc2ac..cffe200 100644
--- a/src/util/torInterpretor.py
+++ b/src/util/torInterpretor.py
@@ -148,8 +148,22 @@ class TorCommandOptions:
     self.commands.append("TAKEOWNERSHIP")
     self.commands.append("QUIT") # TODO: give a confirmation when the user does this?
   
+  def getMatches(self, text):
+    """
+    Provides all options that match the given input.
+    
+    Arguments:
+      text - user input text to be matched against
+    """
+    
+    return [cmd for cmd in self.commands if cmd.lower().startswith(text.lower())]
+  
   def complete(self, text, state):
-    # provides case insensetive autocompletion options based on self.commands
+    """
+    Provides case insensetive autocompletion options, acting as a functor for
+    the readlines set_completer function.
+    """
+    
     for cmd in self.commands:
       if cmd.lower().startswith(text.lower()):
         if not state: return cmd





More information about the tor-commits mailing list