summaryrefslogtreecommitdiff
path: root/cmd2/argparse_completer.py
diff options
context:
space:
mode:
authoranselor <anselor@gmail.com>2020-08-01 16:26:11 -0400
committeranselor <anselor@gmail.com>2020-08-04 13:38:08 -0400
commit9d309939286f4944cb083dfd4f320c442bc99d76 (patch)
treedbfc6c82ede0c146bade33f12016ac072c90b5d3 /cmd2/argparse_completer.py
parentc854ba817fb3e69931990a7c2f79ce3863dbb596 (diff)
downloadcmd2-git-9d309939286f4944cb083dfd4f320c442bc99d76.tar.gz
Now maintains a command->CommandSet mapping and passes the CommandSet
through to the ArgparseCompleter if one is registered. For subcommands, the registered argparse instance for the subcommand is now tagged with the CommandSet from which it originated. If a CommandSet is detected, it's now passed in as 'self' for the completion functions. Fixes some issue found with removing a subcommand. Adds additional tests. Added a check to prevent removal of a CommandSet if it has commands with sub-commands from another CommandSet bound to it. Documentation improvements. Standardized around using CommandSetRegistrationException during commandset install/uninstall related errors. Added support for nested sub-command injection.
Diffstat (limited to 'cmd2/argparse_completer.py')
-rw-r--r--cmd2/argparse_completer.py22
1 files changed, 17 insertions, 5 deletions
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py
index 6acb5abc..0225d22f 100644
--- a/cmd2/argparse_completer.py
+++ b/cmd2/argparse_completer.py
@@ -23,6 +23,7 @@ from .argparse_custom import (
CompletionItem,
generate_range_error,
)
+from .command_definition import CommandSet
from .table_creator import Column, SimpleTable
from .utils import CompletionError, basic_complete
@@ -181,7 +182,8 @@ class ArgparseCompleter:
if isinstance(action, argparse._SubParsersAction):
self._subcommand_action = action
- def complete_command(self, tokens: List[str], text: str, line: str, begidx: int, endidx: int) -> List[str]:
+ def complete_command(self, tokens: List[str], text: str, line: str, begidx: int, endidx: int, *,
+ cmd_set: Optional[CommandSet] = None) -> List[str]:
"""
Complete the command using the argparse metadata and provided argument dictionary
:raises: CompletionError for various types of tab completion errors
@@ -358,7 +360,8 @@ class ArgparseCompleter:
completer = ArgparseCompleter(self._subcommand_action.choices[token], self._cmd2_app,
parent_tokens=parent_tokens)
- return completer.complete_command(tokens[token_index:], text, line, begidx, endidx)
+ return completer.complete_command(tokens[token_index:], text, line, begidx, endidx,
+ cmd_set=cmd_set)
else:
# Invalid subcommand entered, so no way to complete remaining tokens
return []
@@ -403,7 +406,8 @@ class ArgparseCompleter:
# Check if we are completing a flag's argument
if flag_arg_state is not None:
completion_results = self._complete_for_arg(flag_arg_state.action, text, line,
- begidx, endidx, consumed_arg_values)
+ begidx, endidx, consumed_arg_values,
+ cmd_set=cmd_set)
# If we have results, then return them
if completion_results:
@@ -423,7 +427,8 @@ class ArgparseCompleter:
pos_arg_state = _ArgumentState(action)
completion_results = self._complete_for_arg(pos_arg_state.action, text, line,
- begidx, endidx, consumed_arg_values)
+ begidx, endidx, consumed_arg_values,
+ cmd_set=cmd_set)
# If we have results, then return them
if completion_results:
@@ -543,7 +548,8 @@ class ArgparseCompleter:
def _complete_for_arg(self, arg_action: argparse.Action,
text: str, line: str, begidx: int, endidx: int,
- consumed_arg_values: Dict[str, List[str]]) -> List[str]:
+ consumed_arg_values: Dict[str, List[str]], *,
+ cmd_set: Optional[CommandSet] = None) -> List[str]:
"""
Tab completion routine for an argparse argument
:return: list of completions
@@ -563,6 +569,12 @@ class ArgparseCompleter:
kwargs = {}
if isinstance(arg_choices, ChoicesCallable):
if arg_choices.is_method:
+ cmd_set = getattr(self._parser, constants.PARSER_ATTR_COMMANDSET, cmd_set)
+ if cmd_set is not None:
+ if isinstance(cmd_set, CommandSet):
+ # If command is part of a CommandSet, `self` should be the CommandSet and Cmd will be next
+ if cmd_set is not None:
+ args.append(cmd_set)
args.append(self._cmd2_app)
# Check if arg_choices.to_call expects arg_tokens