Skip to content

Commit 25d52d7

Browse files
committed
Added support for using cmd2 application class methods as an argument completion provider. The default completion implementation in Cmd2 automatically passes self to AutoCompleter to be passed to the class method.
1 parent cbb94bf commit 25d52d7

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

cmd2/argparse_completer.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ def __init__(self,
190190
token_start_index: int = 1,
191191
arg_choices: Dict[str, Union[List, Tuple, Callable]] = None,
192192
subcmd_args_lookup: dict = None,
193-
tab_for_arg_help: bool = True):
193+
tab_for_arg_help: bool = True,
194+
cmd2_app=None):
194195
"""
195196
Create an AutoCompleter
196197
@@ -209,6 +210,7 @@ def __init__(self,
209210
self._arg_choices = arg_choices.copy() if arg_choices is not None else {}
210211
self._token_start_index = token_start_index
211212
self._tab_for_arg_help = tab_for_arg_help
213+
self._cmd2_app = cmd2_app
212214

213215
self._flags = [] # all flags in this command
214216
self._flags_without_args = [] # all flags that don't take arguments
@@ -252,7 +254,8 @@ def __init__(self,
252254
subcmd_start = token_start_index + len(self._positional_actions)
253255
sub_completers[subcmd] = AutoCompleter(action.choices[subcmd], subcmd_start,
254256
arg_choices=subcmd_args,
255-
subcmd_args_lookup=subcmd_lookup)
257+
subcmd_args_lookup=subcmd_lookup,
258+
cmd2_app=cmd2_app)
256259
sub_commands.append(subcmd)
257260
self._positional_completers[action.dest] = sub_completers
258261
self._arg_choices[action.dest] = sub_commands
@@ -492,7 +495,16 @@ def _resolve_choices_for_arg(self, action: argparse.Action, used_values=()) -> L
492495
args = self._arg_choices[action.dest]
493496

494497
if callable(args):
495-
args = args()
498+
try:
499+
if self._cmd2_app is not None:
500+
try:
501+
args = args(self._cmd2_app)
502+
except TypeError:
503+
args = args()
504+
else:
505+
args = args()
506+
except TypeError:
507+
return []
496508

497509
try:
498510
iter(args)

cmd2/cmd2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,7 @@ def complete(self, text, state):
18381838
def _autocomplete_default(self, text: str, line: str, begidx: int, endidx: int,
18391839
argparser: argparse.ArgumentParser) -> List[str]:
18401840
"""Default completion function for argparse commands."""
1841-
completer = AutoCompleter(argparser)
1841+
completer = AutoCompleter(argparser, cmd2_app=self)
18421842

18431843
tokens, _ = self.tokens_for_completion(line, begidx, endidx)
18441844
results = completer.complete_command(tokens, text, line, begidx, endidx)

examples/tab_autocompletion.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ def __init__(self):
9595
},
9696
}
9797

98+
def instance_query_actors(self) -> List[str]:
99+
"""Simulating a function that queries and returns a completion values"""
100+
return actors
101+
98102
# This demonstrates a number of customizations of the AutoCompleter version of ArgumentParser
99103
# - The help output will separately group required vs optional flags
100104
# - The help output for arguments with multiple flags or with append=True is more concise
@@ -222,7 +226,7 @@ def _do_vid_media_shows(self, args) -> None:
222226

223227
# tag the action objects with completion providers. This can be a collection or a callable
224228
setattr(director_action, argparse_completer.ACTION_ARG_CHOICES, static_list_directors)
225-
setattr(actor_action, argparse_completer.ACTION_ARG_CHOICES, query_actors)
229+
setattr(actor_action, argparse_completer.ACTION_ARG_CHOICES, instance_query_actors)
226230

227231
vid_movies_delete_parser = vid_movies_commands_subparsers.add_parser('delete')
228232

0 commit comments

Comments
 (0)