diff options
-rw-r--r-- | cmd2/cmd2.py | 28 | ||||
-rw-r--r-- | tests/test_completion.py | 19 |
2 files changed, 25 insertions, 22 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 7b7db87b..d1173bdb 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -2892,14 +2892,20 @@ class Cmd(cmd.Cmd): if onchange_hook is not None: onchange_hook(old=current_value, new=value) - def do_shell(self, statement: Statement) -> None: - """Execute a command as if at the OS prompt + shell_parser = ACArgumentParser() + setattr(shell_parser.add_argument('command', help='the command to run'), + ACTION_ARG_CHOICES, ('shell_cmd_complete',)) + setattr(shell_parser.add_argument('command_args', nargs=argparse.REMAINDER, + help='arguments being passed to command'), + ACTION_ARG_CHOICES, ('path_complete',)) - Usage: shell <command> [arguments]""" + @with_argparser(shell_parser, preserve_quotes=True) + def do_shell(self, args: argparse.Namespace) -> None: + """Execute a command as if at the OS prompt""" import subprocess - # Get list of arguments to shell with quotes preserved - tokens = statement.arg_list + # Create a list of arguments to shell + tokens = [args.command] + args.command_args # Support expanding ~ in quoted paths for index, _ in enumerate(tokens): @@ -2920,18 +2926,6 @@ class Cmd(cmd.Cmd): proc = subprocess.Popen(expanded_command, stdout=self.stdout, shell=True) proc.communicate() - def complete_shell(self, text: str, line: str, begidx: int, endidx: int) -> List[str]: - """Handles tab completion of executable commands and local file system paths for the shell command - - :param text: the string prefix we are attempting to match (all returned matches must begin with it) - :param line: the current input line with leading whitespace removed - :param begidx: the beginning index of the prefix text - :param endidx: the ending index of the prefix text - :return: a list of possible tab completions - """ - index_dict = {1: self.shell_cmd_complete} - return self.index_based_complete(text, line, begidx, endidx, index_dict, self.path_complete) - @staticmethod def _reset_py_display() -> None: """ diff --git a/tests/test_completion.py b/tests/test_completion.py index bb2e6703..7179d2f5 100644 --- a/tests/test_completion.py +++ b/tests/test_completion.py @@ -191,7 +191,9 @@ def test_shell_command_completion_doesnt_match_wildcards(cmd2_app): line = 'shell {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert cmd2_app.complete_shell(text, line, begidx, endidx) == [] + + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is None def test_shell_command_completion_multiple(cmd2_app): if sys.platform == "win32": @@ -204,21 +206,27 @@ def test_shell_command_completion_multiple(cmd2_app): line = 'shell {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert expected in cmd2_app.complete_shell(text, line, begidx, endidx) + + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is not None and expected in cmd2_app.completion_matches def test_shell_command_completion_nomatch(cmd2_app): text = 'zzzz' line = 'shell {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert cmd2_app.complete_shell(text, line, begidx, endidx) == [] + + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is None def test_shell_command_completion_doesnt_complete_when_just_shell(cmd2_app): text = '' line = 'shell {}'.format(text) endidx = len(line) begidx = endidx - len(text) - assert cmd2_app.complete_shell(text, line, begidx, endidx) == [] + + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is None def test_shell_command_completion_does_path_completion_when_after_command(cmd2_app, request): test_dir = os.path.dirname(request.module.__file__) @@ -229,7 +237,8 @@ def test_shell_command_completion_does_path_completion_when_after_command(cmd2_a endidx = len(line) begidx = endidx - len(text) - assert cmd2_app.complete_shell(text, line, begidx, endidx) == [text + '.py'] + first_match = complete_tester(text, line, begidx, endidx, cmd2_app) + assert first_match is not None and cmd2_app.completion_matches == [text + '.py '] def test_path_completion_single_end(cmd2_app, request): |