summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd2/cmd2.py28
-rw-r--r--tests/test_completion.py19
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):