Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions cmd2/argparse_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ def __init__(self,
token_start_index: int = 1,
arg_choices: Dict[str, Union[List, Tuple, Callable]] = None,
subcmd_args_lookup: dict = None,
tab_for_arg_help: bool = True):
tab_for_arg_help: bool = True,
cmd2_app=None):
"""
Create an AutoCompleter

Expand All @@ -199,6 +200,8 @@ def __init__(self,
:param arg_choices: dictionary mapping from argparse argument 'dest' name to list of choices
:param subcmd_args_lookup: mapping a sub-command group name to a tuple to fill the child\
AutoCompleter's arg_choices and subcmd_args_lookup parameters
:param tab_for_arg_help: Enable of disable argument help when there's no completion result
:param cmd2_app: reference to the Cmd2 application. Enables argparse argument completion with class methods
"""
if not subcmd_args_lookup:
subcmd_args_lookup = {}
Expand All @@ -209,6 +212,7 @@ def __init__(self,
self._arg_choices = arg_choices.copy() if arg_choices is not None else {}
self._token_start_index = token_start_index
self._tab_for_arg_help = tab_for_arg_help
self._cmd2_app = cmd2_app

self._flags = [] # all flags in this command
self._flags_without_args = [] # all flags that don't take arguments
Expand Down Expand Up @@ -252,7 +256,8 @@ def __init__(self,
subcmd_start = token_start_index + len(self._positional_actions)
sub_completers[subcmd] = AutoCompleter(action.choices[subcmd], subcmd_start,
arg_choices=subcmd_args,
subcmd_args_lookup=subcmd_lookup)
subcmd_args_lookup=subcmd_lookup,
cmd2_app=cmd2_app)
sub_commands.append(subcmd)
self._positional_completers[action.dest] = sub_completers
self._arg_choices[action.dest] = sub_commands
Expand Down Expand Up @@ -492,7 +497,16 @@ def _resolve_choices_for_arg(self, action: argparse.Action, used_values=()) -> L
args = self._arg_choices[action.dest]

if callable(args):
args = args()
try:
if self._cmd2_app is not None:
try:
args = args(self._cmd2_app)
except TypeError:
args = args()
else:
args = args()
except TypeError:
return []

try:
iter(args)
Expand Down
4 changes: 2 additions & 2 deletions cmd2/cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1838,7 +1838,7 @@ def complete(self, text, state):
def _autocomplete_default(self, text: str, line: str, begidx: int, endidx: int,
argparser: argparse.ArgumentParser) -> List[str]:
"""Default completion function for argparse commands."""
completer = AutoCompleter(argparser)
completer = AutoCompleter(argparser, cmd2_app=self)

tokens, _ = self.tokens_for_completion(line, begidx, endidx)
results = completer.complete_command(tokens, text, line, begidx, endidx)
Expand Down Expand Up @@ -2070,7 +2070,7 @@ def onecmd_plus_hooks(self, line):
:param line: str - line of text read from input
:return: bool - True if cmdloop() should exit, False otherwise
"""
stop = 0
stop = False
try:
statement = self._complete_statement(line)
(stop, statement) = self.postparsing_precmd(statement)
Expand Down
6 changes: 5 additions & 1 deletion examples/tab_autocompletion.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ def __init__(self):
},
}

def instance_query_actors(self) -> List[str]:
"""Simulating a function that queries and returns a completion values"""
return actors

# This demonstrates a number of customizations of the AutoCompleter version of ArgumentParser
# - The help output will separately group required vs optional flags
# - The help output for arguments with multiple flags or with append=True is more concise
Expand Down Expand Up @@ -222,7 +226,7 @@ def _do_vid_media_shows(self, args) -> None:

# tag the action objects with completion providers. This can be a collection or a callable
setattr(director_action, argparse_completer.ACTION_ARG_CHOICES, static_list_directors)
setattr(actor_action, argparse_completer.ACTION_ARG_CHOICES, query_actors)
setattr(actor_action, argparse_completer.ACTION_ARG_CHOICES, instance_query_actors)

vid_movies_delete_parser = vid_movies_commands_subparsers.add_parser('delete')

Expand Down