summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Müller <marcus@hostalia.de>2017-11-20 13:42:30 +0100
committerMartin Braun <martin.braun@ettus.com>2018-02-03 14:11:31 +0100
commitb0912d31f1a2cfea93a5588898cae0c652cd89d4 (patch)
tree09a24e4bdd2f8673e2d13813101f60750b4c4314
parent27de5bf4a4493e74b7b052104a1ed6b4494065b5 (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.py19
-rw-r--r--gr-utils/python/modtool/modtool_rm.py5
-rw-r--r--gr-utils/python/modtool/util_functions.py27
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)