From ce1a92768ab19fd70f226d57679a7ab64867f0c7 Mon Sep 17 00:00:00 2001 From: Pallab Pain Date: Thu, 23 May 2024 17:58:09 +0530 Subject: [PATCH] feat(utils): extends show_selection helper This commit updates the show_selection helper in selector.py to accept additional arguments and extend its capabilities to show better selection prompts to the user. This change specifically adds two arguments, show_keys and highlight_item. If show_keys is set to true then for dict type inputs, the keys will be presented to the user in the prompt. If highlighter_item is passed in the args, then item matching the value will be displayed in bold and italics. --- riocli/utils/selector.py | 82 +++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/riocli/utils/selector.py b/riocli/utils/selector.py index 942638ab..fbf1bb9b 100644 --- a/riocli/utils/selector.py +++ b/riocli/utils/selector.py @@ -1,4 +1,4 @@ -# Copyright 2021 Rapyuta Robotics +# Copyright 2024 Rapyuta Robotics # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,36 +11,84 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from typing import Any from typing import Union import click from click import types +from riocli.constants import Colors -def show_selection(ranger: Union[list, dict], header: str = '', prompt: str = 'Select the option'): + +def show_selection( + ranger: Union[list, dict], + header: str = '', + prompt: str = 'Select the option', + show_keys: bool = True, + highlight_item: str = None, +) -> Any: + """ + Show a selection prompt to the user. + + :param ranger: List or dictionary of options + :param header: Header to show before the options + :param prompt: Prompt to show after the options + :param show_keys: Show keys in the dictionary (not applicable for lists) + :param highlight_item: Highlight the selected item in the list (key in case of dict) + + :return: Selected option + """ if isinstance(ranger, dict): - return _show_selection_dict(ranger, header, prompt) - elif isinstance(ranger, list): - return _show_selection_list(ranger, header, prompt) + return _show_selection_dict(ranger, header, prompt, show_keys, highlight_item) + if isinstance(ranger, list): + return _show_selection_list(ranger, header, prompt, highlight_item) + + +def _show_selection_list( + ranger: list, + header: str, + prompt: str, + highlight_item: Any = None, +) -> Any: + click.secho(header, fg=Colors.YELLOW) -def _show_selection_list(ranger: list, header: str, prompt: str): - fmt = header for idx, opt in enumerate(ranger): - fmt = '{}\n{}) {}'.format(fmt, idx + 1, opt) + fmt = '{}) {}'.format(idx + 1, opt) + if highlight_item is not None and opt == highlight_item: + fmt = click.style(fmt, bold=True, italic=True) + + click.secho(fmt) + + prompt = click.style(prompt, fg=Colors.BLUE) + choice = click.prompt(prompt, type=types.IntParamType()) - fmt = '{}\n{}'.format(fmt, prompt) - choice = click.prompt(fmt, type=types.IntParamType()) return ranger[choice - 1] -def _show_selection_dict(ranger: dict, header: str, prompt: str): - options = [] - fmt = click.style(header, fg='yellow') +def _show_selection_dict( + ranger: dict, + header: str, + prompt: str, + show_keys: bool = True, + highlight_item: Any = None, +) -> Any: + click.secho(header, fg=Colors.YELLOW) + for idx, key in enumerate(ranger): - options.append(key) - fmt = '{}\n{}) {} - {}'.format(fmt, idx + 1, key, ranger[key]) + if show_keys: + fmt = '{}) {} - {}'.format(idx + 1, key, ranger[key]) + else: + fmt = '{}) {}'.format(idx + 1, ranger[key]) + + if highlight_item is not None and key == highlight_item: + fmt = click.style(fmt, bold=True, italic=True) + + click.secho(fmt) + + prompt = click.style(prompt, fg=Colors.BLUE) + choice = click.prompt(prompt, type=types.IntParamType()) + + options = list(ranger.keys()) - fmt = '{}\n{}'.format(fmt, click.style(prompt, fg='blue')) - choice = click.prompt(fmt, type=types.IntParamType()) return options[choice - 1]