Skip to content

Commit f11b063

Browse files
authored
Merge pull request #367 from python-cmd2/autocompleter
Autocompleter updates
2 parents c9b676a + 4bc454f commit f11b063

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

cmd2/argparse_completer.py

Lines changed: 17 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
@@ -199,6 +200,8 @@ def __init__(self,
199200
:param arg_choices: dictionary mapping from argparse argument 'dest' name to list of choices
200201
:param subcmd_args_lookup: mapping a sub-command group name to a tuple to fill the child\
201202
AutoCompleter's arg_choices and subcmd_args_lookup parameters
203+
:param tab_for_arg_help: Enable of disable argument help when there's no completion result
204+
:param cmd2_app: reference to the Cmd2 application. Enables argparse argument completion with class methods
202205
"""
203206
if not subcmd_args_lookup:
204207
subcmd_args_lookup = {}
@@ -209,6 +212,7 @@ def __init__(self,
209212
self._arg_choices = arg_choices.copy() if arg_choices is not None else {}
210213
self._token_start_index = token_start_index
211214
self._tab_for_arg_help = tab_for_arg_help
215+
self._cmd2_app = cmd2_app
212216

213217
self._flags = [] # all flags in this command
214218
self._flags_without_args = [] # all flags that don't take arguments
@@ -252,7 +256,8 @@ def __init__(self,
252256
subcmd_start = token_start_index + len(self._positional_actions)
253257
sub_completers[subcmd] = AutoCompleter(action.choices[subcmd], subcmd_start,
254258
arg_choices=subcmd_args,
255-
subcmd_args_lookup=subcmd_lookup)
259+
subcmd_args_lookup=subcmd_lookup,
260+
cmd2_app=cmd2_app)
256261
sub_commands.append(subcmd)
257262
self._positional_completers[action.dest] = sub_completers
258263
self._arg_choices[action.dest] = sub_commands
@@ -492,7 +497,16 @@ def _resolve_choices_for_arg(self, action: argparse.Action, used_values=()) -> L
492497
args = self._arg_choices[action.dest]
493498

494499
if callable(args):
495-
args = args()
500+
try:
501+
if self._cmd2_app is not None:
502+
try:
503+
args = args(self._cmd2_app)
504+
except TypeError:
505+
args = args()
506+
else:
507+
args = args()
508+
except TypeError:
509+
return []
496510

497511
try:
498512
iter(args)

cmd2/cmd2.py

Lines changed: 2 additions & 2 deletions
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)
@@ -2070,7 +2070,7 @@ def onecmd_plus_hooks(self, line):
20702070
:param line: str - line of text read from input
20712071
:return: bool - True if cmdloop() should exit, False otherwise
20722072
"""
2073-
stop = 0
2073+
stop = False
20742074
try:
20752075
statement = self._complete_statement(line)
20762076
(stop, statement) = self.postparsing_precmd(statement)

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)