def path_completer(self, text, line, begidx, endidx): if len(self.pathCompletionItems) == 0: tree = json.loads(self.getMetaData("*")) if 'metadata' in tree: self.vssTree = tree['metadata'] self.pathCompletionItems = [] childTree = self.get_childtree(text) prefix = "" if "." in text: prefix = text[:text.rfind(".")] + "." for key in childTree: child = childTree[key] if isinstance(child, dict): description = "" if 'description' in child: description = "(" + child['description'] + ")" self.pathCompletionItems.append( CompletionItem(prefix + key, description)) if 'children' in child: self.pathCompletionItems.append( CompletionItem(prefix + key + ".", "(children...)")) return basic_complete(text, line, begidx, endidx, self.pathCompletionItems)
def completion_item_method(self) -> List[CompletionItem]: """Choices method that returns CompletionItems""" items = [] for i in range(0, 10): main_str = 'main_str{}'.format(i) items.append(CompletionItem(main_str, desc='blah blah')) return items
def choices_completion_item() -> List[CompletionItem]: """Return CompletionItem instead of strings. These give more context to what's being tab completed.""" items = \ { 1: "My item", 2: "Another item", 3: "Yet another item" } return [CompletionItem(item_id, description) for item_id, description in items.items()]
def other_open_graphs(self, only_open=False): items = [] for graph_idx, graph in enumerate(self._graphs): if graph_idx == self._graph_idx: continue if graph['G'] is None: if only_open: continue name = "No Graph" else: name = graph['G'].name items.append(CompletionItem(graph_idx, name)) return items
def instance_query_movie_ids(self) -> List[str]: """Demonstrates showing tabular hinting of tab completion information""" completions_with_desc = [] # Sort the movie id strings with a natural sort since they contain numbers for movie_id in utils.natural_sort(self.MOVIE_DATABASE_IDS): if movie_id in self.MOVIE_DATABASE: movie_entry = self.MOVIE_DATABASE[movie_id] completions_with_desc.append( CompletionItem(movie_id, movie_entry['title'])) # Mark that we already sorted the matches self.matches_sorted = True return completions_with_desc
def choices_completion_item(self) -> List[CompletionItem]: """Return CompletionItem instead of strings. These give more context to what's being tab completed.""" fancy_item = "These things can\ncontain newlines and\n" fancy_item += ansi.style("styled text!!", fg=ansi.fg.bright_yellow, underline=True) items = { 1: "My item", 2: "Another item", 3: "Yet another item", 4: fancy_item } return [ CompletionItem(item_id, description) for item_id, description in items.items() ]
class ArgparseCompleterTester(cmd2.Cmd): """Cmd2 app that exercises ArgparseCompleter class""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) ############################################################################################################ # Begin code related to help and command name completion ############################################################################################################ # Top level parser for music command music_parser = Cmd2ArgumentParser(description='Manage music') # Add subcommands to music music_subparsers = music_parser.add_subparsers() music_create_parser = music_subparsers.add_parser('create', help='create music') # Add subcommands to music -> create music_create_subparsers = music_create_parser.add_subparsers() music_create_jazz_parser = music_create_subparsers.add_parser( 'jazz', help='create jazz') music_create_rock_parser = music_create_subparsers.add_parser( 'rock', help='create rocks') @with_argparser(music_parser) def do_music(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to flag completion ############################################################################################################ # Uses default flag prefix value (-) flag_parser = Cmd2ArgumentParser() flag_parser.add_argument('-n', '--normal_flag', help='a normal flag', action='store_true') flag_parser.add_argument('-a', '--append_flag', help='append flag', action='append') flag_parser.add_argument('-o', '--append_const_flag', help='append const flag', action='append_const', const=True) flag_parser.add_argument('-c', '--count_flag', help='count flag', action='count') flag_parser.add_argument('-s', '--suppressed_flag', help=argparse.SUPPRESS, action='store_true') flag_parser.add_argument('-r', '--remainder_flag', nargs=argparse.REMAINDER, help='a remainder flag') flag_parser.add_argument('-q', '--required_flag', required=True, help='a required flag', action='store_true') @with_argparser(flag_parser) def do_flag(self, args: argparse.Namespace) -> None: pass # Uses non-default flag prefix value (+) plus_flag_parser = Cmd2ArgumentParser(prefix_chars='+') plus_flag_parser.add_argument('+n', '++normal_flag', help='a normal flag', action='store_true') plus_flag_parser.add_argument('+q', '++required_flag', required=True, help='a required flag', action='store_true') @with_argparser(plus_flag_parser) def do_plus_flag(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to testing choices and choices_provider parameters ############################################################################################################ STR_METAVAR = "HEADLESS" TUPLE_METAVAR = ('arg1', 'others') CUSTOM_DESC_HEADER = "Custom Header" # Lists used in our tests (there is a mix of sorted and unsorted on purpose) non_negative_int_choices = [1, 2, 3, 0, 22] int_choices = [-1, 1, -2, 2, 0, -12] static_choices_list = ['static', 'choices', 'stop', 'here'] choices_from_provider = ['choices', 'provider', 'probably', 'improved'] completion_item_choices = [ CompletionItem('choice_1', 'A description'), CompletionItem('choice_2', 'Another description') ] def choices_provider(self) -> List[str]: """Method that provides choices""" return self.choices_from_provider def completion_item_method(self) -> List[CompletionItem]: """Choices method that returns CompletionItems""" items = [] for i in range(0, 10): main_str = 'main_str{}'.format(i) items.append(CompletionItem(main_str, desc='blah blah')) return items choices_parser = Cmd2ArgumentParser() # Flag args for choices command. Include string and non-string arg types. choices_parser.add_argument("-l", "--list", help="a flag populated with a choices list", choices=static_choices_list) choices_parser.add_argument( "-p", "--provider", help="a flag populated with a choices provider", choices_provider=choices_provider) choices_parser.add_argument( '-d', "--desc_header", help='this arg has a descriptive header', choices_provider=completion_item_method, descriptive_header=CUSTOM_DESC_HEADER, ) choices_parser.add_argument( '-n', "--no_header", help='this arg has no descriptive header', choices_provider=completion_item_method, metavar=STR_METAVAR, ) choices_parser.add_argument( '-t', "--tuple_metavar", help='this arg has tuple for a metavar', choices_provider=completion_item_method, metavar=TUPLE_METAVAR, nargs=argparse.ONE_OR_MORE, ) choices_parser.add_argument('-i', '--int', type=int, help='a flag with an int type', choices=int_choices) choices_parser.add_argument('--completion_items', help='choices are CompletionItems', choices=completion_item_choices) # Positional args for choices command choices_parser.add_argument( "list_pos", help="a positional populated with a choices list", choices=static_choices_list) choices_parser.add_argument( "method_pos", help="a positional populated with a choices provider", choices_provider=choices_provider) choices_parser.add_argument( 'non_negative_int', type=int, help='a positional with non-negative int choices', choices=non_negative_int_choices) choices_parser.add_argument('empty_choices', help='a positional with empty choices', choices=[]) @with_argparser(choices_parser) def do_choices(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to testing completer parameter ############################################################################################################ completions_for_flag = ['completions', 'flag', 'fairly', 'complete'] completions_for_pos_1 = [ 'completions', 'positional_1', 'probably', 'missed', 'spot' ] completions_for_pos_2 = [ 'completions', 'positional_2', 'probably', 'missed', 'me' ] def flag_completer(self, text: str, line: str, begidx: int, endidx: int) -> List[str]: return self.basic_complete(text, line, begidx, endidx, self.completions_for_flag) def pos_1_completer(self, text: str, line: str, begidx: int, endidx: int) -> List[str]: return self.basic_complete(text, line, begidx, endidx, self.completions_for_pos_1) def pos_2_completer(self, text: str, line: str, begidx: int, endidx: int) -> List[str]: return self.basic_complete(text, line, begidx, endidx, self.completions_for_pos_2) completer_parser = Cmd2ArgumentParser() # Flag args for completer command completer_parser.add_argument("-c", "--completer", help="a flag using a completer", completer=flag_completer) # Positional args for completer command completer_parser.add_argument("pos_1", help="a positional using a completer method", completer=pos_1_completer) completer_parser.add_argument("pos_2", help="a positional using a completer method", completer=pos_2_completer) @with_argparser(completer_parser) def do_completer(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to nargs ############################################################################################################ set_value_choices = ['set', 'value', 'choices'] one_or_more_choices = ['one', 'or', 'more', 'choices'] optional_choices = ['a', 'few', 'optional', 'choices'] range_choices = ['some', 'range', 'choices'] remainder_choices = ['remainder', 'choices'] positional_choices = ['the', 'positional', 'choices'] nargs_parser = Cmd2ArgumentParser() # Flag args for nargs command nargs_parser.add_argument("--set_value", help="a flag with a set value for nargs", nargs=2, choices=set_value_choices) nargs_parser.add_argument("--one_or_more", help="a flag wanting one or more args", nargs=argparse.ONE_OR_MORE, choices=one_or_more_choices) nargs_parser.add_argument("--optional", help="a flag with an optional value", nargs=argparse.OPTIONAL, choices=optional_choices) # noinspection PyTypeChecker nargs_parser.add_argument("--range", help="a flag with nargs range", nargs=(1, 2), choices=range_choices) nargs_parser.add_argument("--remainder", help="a flag wanting remaining", nargs=argparse.REMAINDER, choices=remainder_choices) nargs_parser.add_argument("normal_pos", help="a remainder positional", nargs=2, choices=positional_choices) nargs_parser.add_argument("remainder_pos", help="a remainder positional", nargs=argparse.REMAINDER, choices=remainder_choices) @with_argparser(nargs_parser) def do_nargs(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to testing tab hints ############################################################################################################ hint_parser = Cmd2ArgumentParser() hint_parser.add_argument('-f', '--flag', help='a flag arg') hint_parser.add_argument('-s', '--suppressed_help', help=argparse.SUPPRESS) hint_parser.add_argument('-t', '--suppressed_hint', help='a flag arg', suppress_tab_hint=True) hint_parser.add_argument('hint_pos', help='here is a hint\nwith new lines') hint_parser.add_argument('no_help_pos') @with_argparser(hint_parser) def do_hint(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to CompletionError ############################################################################################################ def completer_raise_error(self, text: str, line: str, begidx: int, endidx: int) -> List[str]: """Raises CompletionError""" raise CompletionError('completer broke something') def choice_raise_error(self) -> List[str]: """Raises CompletionError""" raise CompletionError('choice broke something') comp_error_parser = Cmd2ArgumentParser() comp_error_parser.add_argument('completer_pos', help='positional arg', completer=completer_raise_error) comp_error_parser.add_argument('--choice', help='flag arg', choices_provider=choice_raise_error) @with_argparser(comp_error_parser) def do_raise_completion_error(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to receiving arg_tokens ############################################################################################################ def choices_takes_arg_tokens(self, arg_tokens: argparse.Namespace) -> List[str]: """Choices function that receives arg_tokens from ArgparseCompleter""" return [arg_tokens['parent_arg'][0], arg_tokens['subcommand'][0]] def completer_takes_arg_tokens( self, text: str, line: str, begidx: int, endidx: int, arg_tokens: argparse.Namespace) -> List[str]: """Completer function that receives arg_tokens from ArgparseCompleter""" match_against = [ arg_tokens['parent_arg'][0], arg_tokens['subcommand'][0] ] return self.basic_complete(text, line, begidx, endidx, match_against) arg_tokens_parser = Cmd2ArgumentParser() arg_tokens_parser.add_argument('parent_arg', help='arg from a parent parser') # Create a subcommand for to exercise receiving parent_tokens and subcommand name in arg_tokens arg_tokens_subparser = arg_tokens_parser.add_subparsers(dest='subcommand') arg_tokens_subcmd_parser = arg_tokens_subparser.add_parser('subcmd') arg_tokens_subcmd_parser.add_argument( 'choices_pos', choices_provider=choices_takes_arg_tokens) arg_tokens_subcmd_parser.add_argument('completer_pos', completer=completer_takes_arg_tokens) # Used to override parent_arg in arg_tokens_parser arg_tokens_subcmd_parser.add_argument('--parent_arg') @with_argparser(arg_tokens_parser) def do_arg_tokens(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to mutually exclusive groups ############################################################################################################ mutex_parser = Cmd2ArgumentParser() mutex_group = mutex_parser.add_mutually_exclusive_group(required=True) mutex_group.add_argument('optional_pos', help='the optional positional', nargs=argparse.OPTIONAL) mutex_group.add_argument('-f', '--flag', help='the flag arg') mutex_group.add_argument('-o', '--other_flag', help='the other flag arg') mutex_parser.add_argument('last_arg', help='the last arg') @with_argparser(mutex_parser) def do_mutex(self, args: argparse.Namespace) -> None: pass ############################################################################################################ # Begin code related to standalone functions ############################################################################################################ standalone_parser = Cmd2ArgumentParser() standalone_parser.add_argument('--provider', help='standalone provider', choices_provider=standalone_choice_provider) standalone_parser.add_argument('--completer', help='standalone completer', completer=standalone_completer) @with_argparser(standalone_parser) def do_standalone(self, args: argparse.Namespace) -> None: pass