From 315f2f4aaa71601c15d626a2089a221527ff0814 Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Tue, 30 Aug 2022 23:26:23 -0400 Subject: [PATCH] introduce interactive select for menus --- setup.py | 1 + tockloader/helpers.py | 39 ++++++++++++++++++++++++++++++++++++++- tockloader/main.py | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 4a7f9f4..c7dca62 100644 --- a/setup.py +++ b/setup.py @@ -35,5 +35,6 @@ "pyserial >= 3.0.1", "toml >= 0.10.2", "tqdm >= 4.45.0 ", + "questionary >= 1.10.0", ], ) diff --git a/tockloader/helpers.py b/tockloader/helpers.py index 6170e23..0533694 100644 --- a/tockloader/helpers.py +++ b/tockloader/helpers.py @@ -7,6 +7,7 @@ import sys import colorama +import questionary def set_terminal_title(title): @@ -27,7 +28,7 @@ def set_terminal_title_from_port_info(info): if info.description and info.description != "n/a": extras.append(info.description) # if info.hwid and info.hwid != 'n/a': - # extras.append(info.hwid) + # extras.append(info.hwid) if info.product and info.product != "n/a": if info.product != info.description: extras.append(info.product) @@ -43,6 +44,42 @@ def set_terminal_title_from_port(port): set_terminal_title("Tockloader : {}".format(port)) +def menu_new(options, *, return_type, default_index=None, prompt="", title=""): + """ + Present an interactive menu of choices to a user. + + `options` should be a like-list object whose iterated objects can be coerced + into strings. + + `return_type` must be set to one of: + - "index" - for the index into the options array + - "value" - for the option value chosen + + `default_index` is the index to present as the default value (what happens + if the user simply presses enter). Passing `None` disables default + selection. + """ + + prompt_to_show = prompt + if len(title) > len(prompt_to_show): + prompt_to_show = title + + default = None + if default_index: + default = options[default_index] + + response = questionary.select( + prompt_to_show, choices=options, default=default, qmark="" + ).ask() + + if return_type == "index": + return options.index(response) + elif return_type == "value": + return response + else: + raise NotImplementedError("Menu caller asked for bad return_type") + + def menu(options, *, return_type, default_index=0, prompt="Which option? ", title=""): """ Present a menu of choices to a user diff --git a/tockloader/main.py b/tockloader/main.py index c27ef40..ec9a503 100644 --- a/tockloader/main.py +++ b/tockloader/main.py @@ -327,7 +327,7 @@ def command_inspect_tab(args): # Ask the user if they want to see more detail about a certain TBF. tbf_names = tab.get_tbf_names() - index = helpers.menu( + index = helpers.menu_new( tbf_names + ["None"], return_type="index", title="Which TBF to inspect further?",