commit 7b58a20d69150d3628b758ddef7c014b740cb5de Author: Damian Johnson atagar@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
tor-commits@lists.torproject.org