[tor-commits] [nyx/master] Tidy up interpreter panel

atagar at torproject.org atagar at torproject.org
Sun Jul 31 23:32:41 UTC 2016


commit d774e22d492416a0725c0f915d5ac5001cf73c37
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Jul 30 10:29:09 2016 -0700

    Tidy up interpreter panel
    
    Now that this is a lot simpler we can rearrange things to make
    _execute_command() simpler.
---
 nyx/panel/interpreter.py  | 92 +++++++++++++++++++++++++----------------------
 test/panel/interpreter.py | 10 +++---
 2 files changed, 54 insertions(+), 48 deletions(-)

diff --git a/nyx/panel/interpreter.py b/nyx/panel/interpreter.py
index cf0f261..5a08796 100644
--- a/nyx/panel/interpreter.py
+++ b/nyx/panel/interpreter.py
@@ -1,3 +1,6 @@
+# Copyright 2016, Damian Johnson and The Tor Project
+# See LICENSE for licensing information
+
 """
 Panel providing raw control port access with syntax hilighting, usage
 information, tab completion, and other usability features.
@@ -6,45 +9,43 @@ information, tab completion, and other usability features.
 import curses
 import nyx.controller
 import nyx.curses
-
-from nyx.curses import GREEN, MAGENTA, CYAN, BOLD, HIGHLIGHT
-from nyx import tor_controller, panel
+import nyx.panel
 
 import stem
 import stem.interpreter.autocomplete
 import stem.interpreter.commands
 
+from nyx import tor_controller
+from nyx.curses import GREEN, MAGENTA, CYAN, BOLD, HIGHLIGHT
 
 USER_INPUT_BACKLOG_LIMIT = 100
-PROMPT = [('>>> ', (GREEN, BOLD)), ('to use this panel press enter', (CYAN, BOLD))]
 
+PROMPT = ('>>> ', (GREEN, BOLD))
+PROMPT_USAGE = ('to use this panel press enter', (CYAN, BOLD))
 
-def format_input(user_input):
-  output = [('>>> ', (GREEN, BOLD))]
 
-  if ' ' in user_input:
-    cmd, arg = user_input.split(' ', 1)
-  else:
-    cmd, arg = user_input, ''
+def _format_prompt_input(user_input):
+  line = [PROMPT]
+  cmd, arg = user_input.split(' ', 1) if ' ' in user_input else (user_input, '')
 
   if cmd.startswith('/'):
-    output.append((user_input, (MAGENTA, BOLD)))
+    line.append((user_input, (MAGENTA, BOLD)))
   else:
-    output.append((cmd + ' ', (GREEN, BOLD)))
+    line.append((cmd + ' ', (GREEN, BOLD)))
+
     if arg:
-      output.append((arg, (CYAN, BOLD)))
+      line.append((arg, (CYAN, BOLD)))
 
-  return output
+  return line
 
 
-class InterpreterPanel(panel.Panel):
+class InterpreterPanel(nyx.panel.Panel):
   """
-  Renders the interpreter panel with a prompt providing raw control port
-  access.
+  Prompt with raw control port access.
   """
 
   def __init__(self):
-    panel.Panel.__init__(self)
+    nyx.panel.Panel.__init__(self)
 
     self._is_input_mode = False
     self._x_offset = 0
@@ -65,44 +66,48 @@ class InterpreterPanel(panel.Panel):
       if is_changed:
         self.redraw()
 
-    def _execute_command():
+    def _prompt_input():
+      _scroll(nyx.curses.KeyInput(curses.KEY_END))  # scroll to bottom
+      self.redraw()
+
+      return nyx.curses.str_input(
+        4 + self._x_offset,
+        self.get_top() + max(1, min(len(self._lines) + 1, self.get_height() - 1)),
+        backlog = self._user_inputs,
+        tab_completion = self._autocompleter.matches
+      ).strip()
+
+    def _start_input_mode():
       self._is_input_mode = True
 
       while self._is_input_mode:
-        self.redraw()
-        _scroll(nyx.curses.KeyInput(curses.KEY_END))
-        page_height = self.get_height() - 1
-
-        user_input = nyx.curses.str_input(
-          4 + self._x_offset,
-          self.get_top() + max(len(self._lines[-page_height:]), 1),
-          backlog = self._user_inputs,
-          tab_completion = self._autocompleter.matches
-        ).strip()
+        user_input = _prompt_input()
 
         if not user_input:
           self._is_input_mode = False
-        else:
-          self._user_inputs.append(user_input)
+          break
+
+        self._user_inputs.append(user_input)
 
-          if len(self._user_inputs) > USER_INPUT_BACKLOG_LIMIT:
-            self._user_inputs = self._user_inputs[-USER_INPUT_BACKLOG_LIMIT:]
+        if len(self._user_inputs) > USER_INPUT_BACKLOG_LIMIT:
+          self._user_inputs = self._user_inputs[-USER_INPUT_BACKLOG_LIMIT:]
 
-          try:
-            response = self._interpreter.run_command(user_input)
+        try:
+          response = self._interpreter.run_command(user_input)
+        except stem.SocketClosed:
+          self._is_input_mode = False
+          break
 
-            if response:
-              self._lines.append(format_input(user_input))
+        self._lines.append(_format_prompt_input(user_input))
 
-              for line in response.split('\n'):
-                self._lines.append([(text, attr) for text, attr in nyx.curses.asci_to_curses(line)])
-          except stem.SocketClosed:
-            self._is_input_mode = False
+        if response:
+          for line in response.split('\n'):
+            self._lines.append([(text, attr) for text, attr in nyx.curses.asci_to_curses(line)])
 
       self.redraw()
 
     return (
-      nyx.panel.KeyHandler('enter', 'execute a command', _execute_command, key_func = lambda key: key.is_selection()),
+      nyx.panel.KeyHandler('enter', 'execute a command', _start_input_mode, key_func = lambda key: key.is_selection()),
       nyx.panel.KeyHandler('arrows', 'scroll up and down', _scroll, key_func = lambda key: key.is_scroll()),
     )
 
@@ -113,12 +118,13 @@ class InterpreterPanel(panel.Panel):
       subwindow.addstr(0, 0, 'Control Interpreter:', HIGHLIGHT)
 
     scroll = self._scroller.location(len(self._lines) + 1, subwindow.height - 1)
+    prompt = [PROMPT] if self._is_input_mode else [PROMPT, PROMPT_USAGE]
 
     if len(self._lines) > subwindow.height - 2:
       self._x_offset = 2
       subwindow.scrollbar(1, scroll, len(self._lines))
 
-    for i, line in enumerate(self._lines + [PROMPT]):
+    for i, line in enumerate(self._lines + [prompt]):
       x, y = self._x_offset, i + 1 - scroll
 
       if y > 0:
diff --git a/test/panel/interpreter.py b/test/panel/interpreter.py
index 4686fed..fda70f3 100644
--- a/test/panel/interpreter.py
+++ b/test/panel/interpreter.py
@@ -17,7 +17,7 @@ Control Interpreter:
 
 EXPECTED_PANEL_INPUT_MODE = """
 Control Interpreter (enter "/help" for usage or a blank line to stop):
->>> to use this panel press enter
+>>>
 """.strip()
 
 EXPECTED_MULTILINE_PANEL = """
@@ -29,22 +29,22 @@ Control Interpreter:
 
 
 class TestInterpreter(unittest.TestCase):
-  def test_format_input(self):
+  def test_format_prompt_input(self):
     user_input = 'getinfo'
-    output = nyx.panel.interpreter.format_input(user_input)
+    output = nyx.panel.interpreter._format_prompt_input(user_input)
     self.assertEqual(2, len(output))
     self.assertEqual(('>>> ', ('Green', 'Bold')), output[0])
     self.assertEqual(('getinfo ', ('Green', 'Bold')), output[1])
 
     user_input = 'getinfo version'
-    output = nyx.panel.interpreter.format_input(user_input)
+    output = nyx.panel.interpreter._format_prompt_input(user_input)
     self.assertEqual(3, len(output))
     self.assertEqual(('>>> ', ('Green', 'Bold')), output[0])
     self.assertEqual(('getinfo ', ('Green', 'Bold')), output[1])
     self.assertEqual(('version', ('Cyan', 'Bold')), output[2])
 
     user_input = '/help'
-    output = nyx.panel.interpreter.format_input(user_input)
+    output = nyx.panel.interpreter._format_prompt_input(user_input)
     self.assertEqual(2, len(output))
     self.assertEqual(('>>> ', ('Green', 'Bold')), output[0])
     self.assertEqual(('/help', ('Magenta', 'Bold')), output[1])





More information about the tor-commits mailing list