From 12414fd8be79e12fe831127657206057a6d198c8 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Fri, 13 Mar 2015 01:50:21 -0700 Subject: [PATCH] code-completer: re-fetch channelids upon TAB, if necessary This fixes the situation where you start the receiver first, then start the sender, then you hit TAB on the receiver. This somewhat improves the situation where you start the receiver first, hit TAB (getting nothing), then start the sender, then hit TAB on the receiver again. The second TAB will list the channel-ids, but won't insert the only one as it's supposed to. You must type something (which you can erase) and then hit TAB again to get a unique channel-id inserted. But at least you can tell which one to type. The first TAB runs the completer with readline.get_completion_type() equal to 9=TAB=try-to-insert. The second (and subsequent) TABs use 63=?=list-matches, and it won't go back to 9 until you type something. --- src/wormhole/blocking/transcribe.py | 3 +-- src/wormhole/codes.py | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/wormhole/blocking/transcribe.py b/src/wormhole/blocking/transcribe.py index 80dce5b..5e358aa 100644 --- a/src/wormhole/blocking/transcribe.py +++ b/src/wormhole/blocking/transcribe.py @@ -223,8 +223,7 @@ class Receiver(Common): return channel_ids def input_code(self, prompt="Enter wormhole code: "): - channel_ids = self.list_channels() - code = codes.input_code_with_completion(prompt, channel_ids) + code = codes.input_code_with_completion(prompt, self.list_channels) return code def set_code(self, code): diff --git a/src/wormhole/codes.py b/src/wormhole/codes.py index c2b5baa..59388a4 100644 --- a/src/wormhole/codes.py +++ b/src/wormhole/codes.py @@ -16,8 +16,8 @@ import readline #import sys class CodeInputter: - def __init__(self, channel_ids): - self.channel_ids = channel_ids + def __init__(self, get_channel_ids): + self.get_channel_ids = get_channel_ids self.last_text = None # memoize for a speedup self.last_matches = None @@ -31,15 +31,23 @@ class CodeInputter: raise e def completer(self, text, state): - #print("completer:", text, state, file=sys.stderr) + #if state == 0: + # print("", file=sys.stderr) + #print("completer: '%s' %d '%d'" % (text, state, + # readline.get_completion_type()), + # file=sys.stderr) + #sys.stderr.flush() pieces = text.split("-") last = pieces[-1].lower() - if text == self.last_text: + if text == self.last_text and len(pieces) >= 2: + # if len(pieces) == 1, skip the cache, so we can re-fetch the + # channel_id list matches = self.last_matches #print(" old matches", len(matches), file=sys.stderr) else: if len(pieces) < 2: - matches = [str(channel_id) for channel_id in self.channel_ids + channel_ids = self.get_channel_ids() + matches = [str(channel_id) for channel_id in channel_ids if str(channel_id).startswith(last)] else: if len(pieces) % 2 == 0: @@ -57,11 +65,13 @@ class CodeInputter: match = matches[state] if len(pieces) < 3: match += "-" + #print(" match: '%s'" % match, file=sys.stderr) + #sys.stderr.flush() return match -def input_code_with_completion(prompt, channel_ids): - c = CodeInputter(channel_ids) +def input_code_with_completion(prompt, get_channel_ids): + c = CodeInputter(get_channel_ids) readline.parse_and_bind("tab: complete") readline.set_completer(c.wrap_completer) readline.set_completer_delims("") @@ -69,5 +79,5 @@ def input_code_with_completion(prompt, channel_ids): return code if __name__ == "__main__": - code = input_code_with_completion("Enter wormhole code: ", []) + code = input_code_with_completion("Enter wormhole code: ", lambda: []) print("code is:", code)