diff options
author | kotfu <kotfu@kotfu.net> | 2018-05-23 20:59:26 -0600 |
---|---|---|
committer | kotfu <kotfu@kotfu.net> | 2018-05-23 20:59:26 -0600 |
commit | 1a70b90f375997751bc7df16b5e3f58c6194c71b (patch) | |
tree | 1abe43d088060e24bb889e3db19fc5a1a4a82562 /cmd2/argparse_completer.py | |
parent | b1516f4b09518bb6d33abfeb14e1459ed03f34d8 (diff) | |
parent | 5d64ebee348aeffb02fc385f903c9af431e3721b (diff) | |
download | cmd2-git-1a70b90f375997751bc7df16b5e3f58c6194c71b.tar.gz |
Merge branch 'master' into speedup_import
# Conflicts:
# cmd2/cmd2.py
# tests/test_completion.py
# tests/test_submenu.py
Diffstat (limited to 'cmd2/argparse_completer.py')
-rwxr-xr-x | cmd2/argparse_completer.py | 68 |
1 files changed, 57 insertions, 11 deletions
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py index a8a0f24a..d98a6eac 100755 --- a/cmd2/argparse_completer.py +++ b/cmd2/argparse_completer.py @@ -75,6 +75,7 @@ from .rl_utils import rl_force_redisplay # attribute that can optionally added to an argparse argument (called an Action) to # define the completion choices for the argument. You may provide a Collection or a Function. ACTION_ARG_CHOICES = 'arg_choices' +ACTION_SUPPRESS_HINT = 'suppress_hint' class _RangeAction(object): @@ -261,6 +262,7 @@ class AutoCompleter(object): sub_completers[subcmd] = AutoCompleter(action.choices[subcmd], subcmd_start, arg_choices=subcmd_args, subcmd_args_lookup=subcmd_lookup, + tab_for_arg_help=tab_for_arg_help, cmd2_app=cmd2_app) sub_commands.append(subcmd) self._positional_completers[action.dest] = sub_completers @@ -472,8 +474,23 @@ class AutoCompleter(object): if action.dest in self._arg_choices: arg_choices = self._arg_choices[action.dest] - if isinstance(arg_choices, tuple) and len(arg_choices) > 0 and callable(arg_choices[0]): - completer = arg_choices[0] + # if arg_choices is a tuple + # Let's see if it's a custom completion function. If it is, return what it provides + # To do this, we make sure the first element is either a callable + # or it's the name of a callable in the application + if isinstance(arg_choices, tuple) and len(arg_choices) > 0 and \ + (callable(arg_choices[0]) or + (isinstance(arg_choices[0], str) and hasattr(self._cmd2_app, arg_choices[0]) and + callable(getattr(self._cmd2_app, arg_choices[0])) + ) + ): + + if callable(arg_choices[0]): + completer = arg_choices[0] + elif isinstance(arg_choices[0], str) and callable(getattr(self._cmd2_app, arg_choices[0])): + completer = getattr(self._cmd2_app, arg_choices[0]) + + # extract the positional and keyword arguments from the tuple list_args = None kw_args = None for index in range(1, len(arg_choices)): @@ -481,14 +498,19 @@ class AutoCompleter(object): list_args = arg_choices[index] elif isinstance(arg_choices[index], dict): kw_args = arg_choices[index] - if list_args is not None and kw_args is not None: - return completer(text, line, begidx, endidx, *list_args, **kw_args) - elif list_args is not None: - return completer(text, line, begidx, endidx, *list_args) - elif kw_args is not None: - return completer(text, line, begidx, endidx, **kw_args) - else: - return completer(text, line, begidx, endidx) + try: + # call the provided function differently depending on the provided positional and keyword arguments + if list_args is not None and kw_args is not None: + return completer(text, line, begidx, endidx, *list_args, **kw_args) + elif list_args is not None: + return completer(text, line, begidx, endidx, *list_args) + elif kw_args is not None: + return completer(text, line, begidx, endidx, **kw_args) + else: + return completer(text, line, begidx, endidx) + except TypeError: + # assume this is due to an incorrect function signature, return nothing. + return [] else: return AutoCompleter.basic_complete(text, line, begidx, endidx, self._resolve_choices_for_arg(action, used_values)) @@ -499,6 +521,16 @@ class AutoCompleter(object): if action.dest in self._arg_choices: args = self._arg_choices[action.dest] + # is the argument a string? If so, see if we can find an attribute in the + # application matching the string. + if isinstance(args, str): + try: + args = getattr(self._cmd2_app, args) + except AttributeError: + # Couldn't find anything matching the name + return [] + + # is the provided argument a callable. If so, call it if callable(args): try: if self._cmd2_app is not None: @@ -525,8 +557,19 @@ class AutoCompleter(object): return [] def _print_action_help(self, action: argparse.Action) -> None: + # is parameter hinting disabled globally? if not self._tab_for_arg_help: return + + # is parameter hinting disabled for this parameter? + try: + suppress_hint = getattr(action, ACTION_SUPPRESS_HINT) + except AttributeError: + pass + else: + if suppress_hint: + return + if action.option_strings: flags = ', '.join(action.option_strings) param = '' @@ -535,7 +578,10 @@ class AutoCompleter(object): prefix = '{}{}'.format(flags, param) else: - prefix = '{}'.format(str(action.dest).upper()) + if action.dest != SUPPRESS: + prefix = '{}'.format(str(action.dest).upper()) + else: + prefix = '' prefix = ' {0: <{width}} '.format(prefix, width=20) pref_len = len(prefix) |