diff options
-rwxr-xr-x | interface/input/tabcomp.py | 61 | ||||
-rw-r--r-- | interface/interface.py | 42 |
2 files changed, 81 insertions, 22 deletions
diff --git a/interface/input/tabcomp.py b/interface/input/tabcomp.py index 330c948..4cce602 100755 --- a/interface/input/tabcomp.py +++ b/interface/input/tabcomp.py @@ -7,6 +7,15 @@ from .parsers import PARSE_MAP, parse_null, make_parse_letter from ..globals import CURSES_LOCK class _Node: + def iter_possible(self): + if None in self.children: + yield self + if [i for i in self.children if i is not None]: + for c in self.children: + if c is None: + continue + yield from c.iter_possible() + def __repr__(self): return self.path @@ -31,25 +40,8 @@ class _Node: #} # #root = parse_options([(o.split(' '), f) for o, f in options_list]) -#def iter_possible(start): -# if None in start.children: -# yield start -# if [i for i in start.children if i is not None]: -# for c in start.children: -# if c is None: -# continue -# yield from iter_possible(c) -# + #help_map = {} -#for s in root.children: -# if s is None: -# continue -# help_map[s.path] = list(iter_possible(s)) -# print("===", s.path.upper()) -# print((options_help[s.path] if s.path in options_help else "No help given")) -# for p in help_map[s.path]: -# -# print('-', p) options_list = ( ("test potato $value one two", lambda *args: ('1')), @@ -63,15 +55,17 @@ options_list = ( class Input: @staticmethod - def parse_context(ctx, parent=None): + def parse_context(ctx, help_map=None, help_f=None, parent=None): if parent is None: - parent = _Node(None, parse_null, None) + parent = _Node(None, parse_null) start = {} for i, f in ctx: if isinstance(i, str): i = i.split(' ') if i[0] not in start: + if parent.parent is None and i[0][0] == 'h': + raise ValueError("No base command may start with h") start[i[0]] = [] start[i[0]].append((i, f)) @@ -88,6 +82,33 @@ class Input: if ols: Input.parse_context(ols, parent=n) + if parent.parent is None and help_f is not None: + if help_map is None: + help_map = {} + + root_commands = tuple((i.name for i in parent.children if i is not None)) + + help_node = _Node(parent, make_parse_letter('h', "help"), path="help") + help_node.children.append(None) + + if None in help_map: + help_node.f = lambda: help_f(None, root_commands, help_map[None]) + else: + help_node.f = lambda: help_f(None, root_commands, "No help available!") + + for s in parent.children: + if s is None or s.name == "help": + continue + + options = tuple(s.iter_possible()) + hn = _Node(help_node, make_parse_letter(s.name[0], s.name), path=s.name) + hn.children.append(None) + + if s.name in help_map: + hn.f = lambda options=options, name=s.name: help_f(name, (o.path for o in options), help_map[name]) + else: + hn.f = lambda options=options, name=s.name: help_f(name, (o.path for o in options), "No help available!") + return parent def set_dim(self, height, width): diff --git a/interface/interface.py b/interface/interface.py index c9f2a6e..b838b08 100644 --- a/interface/interface.py +++ b/interface/interface.py @@ -173,6 +173,26 @@ class Interface: def page_clear(self): self.pager.clear() + def help(self, name, commands, help_): + if name is None: + dname = "MODE HELP:" + else: + dname = name.upper() + " COMMAND:" + + todisp = [dname, ""] + if commands: + if name is None: + todisp.append("Available commands:") + else: + todisp.append("Available forms:") + todisp.extend(("- "+i for i in commands)) + todisp.append("") + + todisp.extend(help_.split('\n')) + + self.pager.display_many(todisp, split=True) + + def __init__(self, path): ## Have to do most of the actual initialization in the main method, as curses isn't ## ready yet. @@ -208,7 +228,17 @@ class Interface: ("page", self.page), ("clrpage", self.page_clear), ("quit", self.base_quit), - )) + ), { + None: "This is the base edit mode for editing functions.", + "edit": "Edit the specified function.", + "delete": "Delete the specified function.", + "new": "Create a new function of the given type.", + "save": "Save the workspace. The path is implicitly the one loaded from if not given.", + "list": "List available fixtures or functions.", + "page": "Page through the output window. Arrow keys, page up/down, home/end, and j/k can be used to scroll, q exits.", + "clrpage": "Clear the output window.", + "quit": "Exit BLC." + }, self.help) self.context_scene = Input.parse_context(( ("set $channel_range to $value", self.scene_set), @@ -220,4 +250,12 @@ class Interface: ("page", self.page), ("clrpage", self.page_clear), ("quit", self.scene_exit), - )) + ), { + None: "This mode is for editing scene primitives for fixed lighting.", + "set": "Set the given channel range to the given value (0 <= value <= 255).", + "reset": "Remove the given channel range from the scene", + "list": "List available fixtures or functions.", + "page": "Page through the output window. Arrow keys, page up/down, home/end, and j/k can be used to scroll, q exits.", + "clrpage": "Clear the output window.", + "quit": "Return to the previous mode." + }, self.help) |