[tor-commits] [stem/master] Moving autocompletion to its own module

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


commit 278994377919bef35dcf6fef604d7bf5ef3be6da
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Apr 19 16:23:01 2014 -0700

    Moving autocompletion to its own module
    
    I bundled autocompletion with commands.py because it used one of its globals.
    However, we've since dropped those bits so this can be nicely moved back to its
    own file.
---
 stem/interpretor/__init__.py     |    7 +--
 stem/interpretor/autocomplete.py |   98 ++++++++++++++++++++++++++++++++++++++
 stem/interpretor/commands.py     |   93 ------------------------------------
 3 files changed, 102 insertions(+), 96 deletions(-)

diff --git a/stem/interpretor/__init__.py b/stem/interpretor/__init__.py
index 59c89c8..5e03c2c 100644
--- a/stem/interpretor/__init__.py
+++ b/stem/interpretor/__init__.py
@@ -6,7 +6,7 @@ Interactive interpretor for interacting with Tor directly. This adds usability
 features such as tab completion, history, and IRC-style functions (like /help).
 """
 
-__all__ = ['arguments', 'commands', 'msg']
+__all__ = ['arguments', 'autocomplete', 'commands', 'msg']
 
 import os
 import sys
@@ -39,6 +39,7 @@ def main():
   import readline
 
   import stem.interpretor.arguments
+  import stem.interpretor.autocomplete
   import stem.interpretor.commands
 
   try:
@@ -64,9 +65,9 @@ def main():
     sys.exit(1)
 
   with controller:
-    autocomplete = stem.interpretor.commands.Autocomplete(controller)
+    autocompleter = stem.interpretor.autocomplete.Autocompleter(controller)
     readline.parse_and_bind('tab: complete')
-    readline.set_completer(autocomplete.complete)
+    readline.set_completer(autocompleter.complete)
     readline.set_completer_delims('\n')
 
     interpretor = stem.interpretor.commands.ControlInterpretor(controller)
diff --git a/stem/interpretor/autocomplete.py b/stem/interpretor/autocomplete.py
new file mode 100644
index 0000000..09c5365
--- /dev/null
+++ b/stem/interpretor/autocomplete.py
@@ -0,0 +1,98 @@
+"""
+Tab completion for our interpretor prompt.
+"""
+
+from stem.interpretor import uses_settings
+
+
+ at uses_settings
+def _get_commands(config, controller):
+  """
+  Provides commands recognized by tor.
+  """
+
+  commands = config.get('autocomplete', [])
+
+  # GETINFO commands
+
+  getinfo_options = controller.get_info('info/names', None)
+
+  if getinfo_options:
+    # Lines are of the form '[option] -- [description]'. This strips '*' from
+    # options that accept values.
+
+    options = [line.split(' ', 1)[0].rstrip('*') for line in getinfo_options.splitlines()]
+
+    commands += ['GETINFO %s' % opt for opt in options]
+  else:
+    commands.append('GETINFO ')
+
+  # GETCONF, SETCONF, and RESETCONF commands
+
+  config_options = controller.get_info('config/names', None)
+
+  if config_options:
+    # individual options are '[option] [type]' pairs
+
+    entries = [opt.split(' ', 1)[0] for opt in config_options.splitlines()]
+
+    commands += ['GETCONF %s' % opt for opt in entries]
+    commands += ['SETCONF %s ' % opt for opt in entries]
+    commands += ['RESETCONF %s' % opt for opt in entries]
+  else:
+    commands += ['GETCONF ', 'SETCONF ', 'RESETCONF ']
+
+  # SETEVENT commands
+
+  events = controller.get_info('events/names', None)
+
+  if events:
+    commands += ['SETEVENTS %s' % event for event in events.split(' ')]
+  else:
+    commands.append('SETEVENTS ')
+
+  # USEFEATURE commands
+
+  features = controller.get_info('features/names', None)
+
+  if features:
+    commands += ['USEFEATURE %s' % feature for feature in features.split(' ')]
+  else:
+    commands.append('USEFEATURE ')
+
+  # SIGNAL commands
+
+  signals = controller.get_info('signal/names', None)
+
+  if signals:
+    commands += ['SIGNAL %s' % signal for signal in signals.split(' ')]
+  else:
+    commands.append('SIGNAL ')
+
+  # adds help options for the previous commands
+
+  base_cmd = set([cmd.split(' ')[0].replace('+', '').replace('/', '') for cmd in commands])
+
+  for cmd in base_cmd:
+    commands.append('/help ' + cmd)
+
+  return commands
+
+
+class Autocompleter(object):
+  def __init__(self, controller):
+    self._commands = _get_commands(controller)
+
+  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)]
+
+    if state < len(prefix_matches):
+      return prefix_matches[state]
+    else:
+      return None
diff --git a/stem/interpretor/commands.py b/stem/interpretor/commands.py
index 833918f..e5b3e97 100644
--- a/stem/interpretor/commands.py
+++ b/stem/interpretor/commands.py
@@ -16,99 +16,6 @@ BOLD_OUTPUT_FORMAT = (Color.BLUE, Attr.BOLD)
 ERROR_FORMAT = (Attr.BOLD, Color.RED)
 
 
- at uses_settings
-def _get_commands(config, controller):
-  """
-  Provides commands recognized by tor.
-  """
-
-  commands = config.get('autocomplete', [])
-
-  # GETINFO commands
-
-  getinfo_options = controller.get_info('info/names', None)
-
-  if getinfo_options:
-    # Lines are of the form '[option] -- [description]'. This strips '*' from
-    # options that accept values.
-
-    options = [line.split(' ', 1)[0].rstrip('*') for line in getinfo_options.splitlines()]
-
-    commands += ['GETINFO %s' % opt for opt in options]
-  else:
-    commands.append('GETINFO ')
-
-  # GETCONF, SETCONF, and RESETCONF commands
-
-  config_options = controller.get_info('config/names', None)
-
-  if config_options:
-    # individual options are '[option] [type]' pairs
-
-    entries = [opt.split(' ', 1)[0] for opt in config_options.splitlines()]
-
-    commands += ['GETCONF %s' % opt for opt in entries]
-    commands += ['SETCONF %s ' % opt for opt in entries]
-    commands += ['RESETCONF %s' % opt for opt in entries]
-  else:
-    commands += ['GETCONF ', 'SETCONF ', 'RESETCONF ']
-
-  # SETEVENT commands
-
-  events = controller.get_info('events/names', None)
-
-  if events:
-    commands += ['SETEVENTS %s' % event for event in events.split(' ')]
-  else:
-    commands.append('SETEVENTS ')
-
-  # USEFEATURE commands
-
-  features = controller.get_info('features/names', None)
-
-  if features:
-    commands += ['USEFEATURE %s' % feature for feature in features.split(' ')]
-  else:
-    commands.append('USEFEATURE ')
-
-  # SIGNAL commands
-
-  signals = controller.get_info('signal/names', None)
-
-  if signals:
-    commands += ['SIGNAL %s' % signal for signal in signals.split(' ')]
-  else:
-    commands.append('SIGNAL ')
-
-  # adds help options for the previous commands
-
-  base_cmd = set([cmd.split(' ')[0].replace('+', '').replace('/', '') for cmd in commands])
-
-  for cmd in base_cmd:
-    commands.append('/help ' + cmd)
-
-  return commands
-
-
-class Autocomplete(object):
-  def __init__(self, controller):
-    self._commands = _get_commands(controller)
-
-  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)]
-
-    if state < len(prefix_matches):
-      return prefix_matches[state]
-    else:
-      return None
-
-
 class ControlInterpretor(object):
   """
   Handles issuing requests and providing nicely formed responses, with support





More information about the tor-commits mailing list