Skip to content
Snippets Groups Projects
Commit 75052e8d authored by Damian Johnson's avatar Damian Johnson
Browse files

Line wrap interpreter content

When lines exceed our terminal width we cropped the content. Clearly this sucks
since it makes that content impossible to... well, get.

Wrapping lines that exceed our panel width with a two space indentation.

  https://trac.torproject.org/projects/tor/ticket/28297
parent 6492a3a1
Branches
Tags
No related merge requests found
......@@ -7,6 +7,7 @@ information, tab completion, and other usability features.
"""
import curses
import threading
import nyx.curses
import nyx.panel
......@@ -53,6 +54,12 @@ class InterpreterPanel(nyx.panel.Panel):
self._lines = []
self._user_inputs = [] # previous user inputs
# cache for the line wrapped content we display
self._wrapped_lines = []
self._wrapped_line_lock = threading.RLock()
self._wrapped_line_width = 80
controller = tor_controller()
self._autocompleter = stem.interpreter.autocomplete.Autocompleter(controller)
self._interpreter = stem.interpreter.commands.ControlInterpreter(controller)
......@@ -60,7 +67,7 @@ class InterpreterPanel(nyx.panel.Panel):
def key_handlers(self):
def _scroll(key):
page_height = self.get_height() - 1
is_changed = self._scroller.handle_key(key, len(self._lines) + 1, page_height)
is_changed = self._scroller.handle_key(key, len(self._get_lines()) + 1, page_height)
if is_changed:
self.redraw()
......@@ -71,7 +78,7 @@ class InterpreterPanel(nyx.panel.Panel):
return nyx.curses.str_input(
4 + self._x_offset,
self.get_top() + max(1, min(len(self._lines) + 1, self.get_height() - 1)),
self.get_top() + max(1, min(len(self._get_lines()) + 1, self.get_height() - 1)),
backlog = self._user_inputs,
tab_completion = self._autocompleter.matches
)
......@@ -98,11 +105,11 @@ class InterpreterPanel(nyx.panel.Panel):
self._is_input_mode = False
break
self._lines.append(_format_prompt_input(user_input, prompt))
self._add_line(_format_prompt_input(user_input, prompt))
if response:
for line in response.split('\n'):
self._lines.append([(text, attr) for text, attr in nyx.curses.asci_to_curses(line)])
self._add_line([(text, attr) for text, attr in nyx.curses.asci_to_curses(line)])
self.redraw()
......@@ -111,13 +118,49 @@ class InterpreterPanel(nyx.panel.Panel):
nyx.panel.KeyHandler('arrows', 'scroll up and down', _scroll, key_func = lambda key: key.is_scroll()),
)
def _add_line(self, line):
with self._wrapped_line_lock:
self._lines.append(line)
wrapped_line = []
for text, attr in line:
while text:
wrapped_line.append((text[:self._wrapped_line_width], attr))
text = text[self._wrapped_line_width:]
if text:
text = ' ' + text # indent wrapped lines
self._wrapped_lines.append(wrapped_line)
wrapped_line = []
self._wrapped_lines.append(wrapped_line)
def _get_lines(self, width = None):
with self._wrapped_line_lock:
if width and width != self._wrapped_line_width:
# Our panel size has changed. As such, line wrapping needs to be re-cached.
lines = self._lines
self._lines = []
self._wrapped_lines = []
self._wrapped_line_width = width
for line in lines:
self._add_line(line)
return self._wrapped_lines
def _draw(self, subwindow):
if self._is_input_mode:
subwindow.addstr(0, 0, 'Control Interpreter (enter "/help" for usage or a blank line to stop):', HIGHLIGHT)
else:
subwindow.addstr(0, 0, 'Control Interpreter:', HIGHLIGHT)
scroll = self._scroller.location(len(self._lines) + 1, subwindow.height - 1)
lines = self._get_lines(subwindow.width - self._x_offset)
scroll = self._scroller.location(len(lines) + 1, subwindow.height - 1)
if self._interpreter.is_multiline_context:
prompt = [MULTILINE_PROMPT]
......@@ -126,11 +169,11 @@ class InterpreterPanel(nyx.panel.Panel):
else:
prompt = [PROMPT, PROMPT_USAGE]
if len(self._lines) > subwindow.height - 2:
if len(lines) > subwindow.height - 2:
self._x_offset = 2
subwindow.scrollbar(1, scroll, len(self._lines) + 1)
subwindow.scrollbar(1, scroll, len(lines) + 1)
visible_lines = self._lines[scroll:scroll + subwindow.height - 1]
visible_lines = lines[scroll:scroll + subwindow.height - 1]
if len(visible_lines) < subwindow.height - 1:
visible_lines.append(prompt)
......
......@@ -96,6 +96,7 @@
<ul>
<li>Geoip information unavailable for inbound connections</li>
<li>Dialog showing exit statistics crashed when no data was available (<a href="https://trac.torproject.org/projects/tor/ticket/25801">ticket</a>)</li>
<li>More strictly scrub sensitive connection information (<a href="https://trac.torproject.org/projects/tor/ticket/27475">ticket</a>)</li>
</ul>
</li>
......@@ -114,6 +115,7 @@
<li><span class="component">Interpreter</span>
<ul>
<li>Line wrap content (<b><a href="https://trac.torproject.org/projects/tor/ticket/28297">ticket</a></b>)</li>
<li>Large amounts of content made panel sluggish (<b><a href="https://trac.torproject.org/projects/tor/ticket/28902">ticket</a></b>)</li>
</ul>
</li>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment