diff options
author | Marcus Müller <marcus@hostalia.de> | 2017-11-20 13:42:30 +0100 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-02-03 14:11:31 +0100 |
commit | b0912d31f1a2cfea93a5588898cae0c652cd89d4 (patch) | |
tree | 09a24e4bdd2f8673e2d13813101f60750b4c4314 | |
parent | 27de5bf4a4493e74b7b052104a1ed6b4494065b5 (diff) |
Adding readline capabilities to gr_modtool
* main advantage: better line editing
* tab-completion for gr_modtool add
-rw-r--r-- | gr-utils/python/modtool/modtool_add.py | 19 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_rm.py | 5 | ||||
-rw-r--r-- | gr-utils/python/modtool/util_functions.py | 27 |
3 files changed, 42 insertions, 9 deletions
diff --git a/gr-utils/python/modtool/modtool_add.py b/gr-utils/python/modtool/modtool_add.py index b60474740c..21fcd28900 100644 --- a/gr-utils/python/modtool/modtool_add.py +++ b/gr-utils/python/modtool/modtool_add.py @@ -23,8 +23,9 @@ import os import re from optparse import OptionGroup +import readline -from util_functions import append_re_line_sequence, ask_yes_no +from util_functions import append_re_line_sequence, ask_yes_no, SequenceCompleter from cmakefile_editor import CMakeFileEditor from modtool_base import ModTool, ModToolException from templates import Templates @@ -75,15 +76,19 @@ class ModToolAdd(ModTool): if self._info['blocktype'] is None: # Print list out of blocktypes to user for reference print str(self._block_types) - while self._info['blocktype'] not in self._block_types: - self._info['blocktype'] = raw_input("Enter block type: ") - if self._info['blocktype'] not in self._block_types: - print 'Must be one of ' + str(self._block_types) + with SequenceCompleter(sorted(self._block_types)): + while self._info['blocktype'] not in self._block_types: + self._info['blocktype'] = raw_input("Enter block type: ") + if self._info['blocktype'] not in self._block_types: + print 'Must be one of ' + str(self._block_types) + # Allow user to specify language interactively if not set self._info['lang'] = options.lang if self._info['lang'] is None: - while self._info['lang'] not in ['cpp', 'python']: - self._info['lang'] = raw_input("Language (python/cpp): ") + language_candidates = ('cpp', 'python') + with SequenceCompleter(language_candidates): + while self._info['lang'] not in language_candidates: + self._info['lang'] = raw_input("Language (python/cpp): ") if self._info['lang'] == 'c++': self._info['lang'] = 'cpp' diff --git a/gr-utils/python/modtool/modtool_rm.py b/gr-utils/python/modtool/modtool_rm.py index 67de33f044..4fcd79e2b1 100644 --- a/gr-utils/python/modtool/modtool_rm.py +++ b/gr-utils/python/modtool/modtool_rm.py @@ -25,7 +25,7 @@ import re import sys import glob -from util_functions import remove_pattern_from_file +from util_functions import remove_pattern_from_file, SequenceCompleter from modtool_base import ModTool from cmakefile_editor import CMakeFileEditor @@ -46,7 +46,8 @@ class ModToolRemove(ModTool): elif len(args) >= 2: self._info['pattern'] = args[1] else: - self._info['pattern'] = raw_input('Which blocks do you want to delete? (Regex): ') + with SequenceCompleter(): + self._info['pattern'] = raw_input('Which blocks do you want to delete? (Regex): ') if len(self._info['pattern']) == 0: self._info['pattern'] = '.' diff --git a/gr-utils/python/modtool/util_functions.py b/gr-utils/python/modtool/util_functions.py index 47799ac461..6bb95f3d67 100644 --- a/gr-utils/python/modtool/util_functions.py +++ b/gr-utils/python/modtool/util_functions.py @@ -22,6 +22,7 @@ import re import sys +import readline # None of these must depend on other modtool stuff! @@ -144,3 +145,29 @@ def ask_yes_no(question, default): return default else: return not default + +class SequenceCompleter(object): + """ A simple completer function wrapper to be used with readline, e.g. + option_iterable = ("search", "seek", "destroy") + readline.set_completer(SequenceCompleter(option_iterable).completefunc) + """ + + def __init__(self, sequence): + self._seq = sequence + self._tmp_matches = [] + + def completefunc(self, text, state): + if not text and state < len(self._seq): + return self._seq[state] + if not state: + self._tmp_matches = filter(lambda candidate: candidate.startswith(text), self._seq) + if state < len(self._tmp_matches): + return self._tmp_matches[state] + + def __enter__(self): + self._old_completer = readline.get_completer() + readline.set_completer(self.completefunc) + readline.parse_and_bind("tab: complete") + + def __exit__(self): + readline.set_completer(self._old_completer) |