Skip to content

Commit d9de552

Browse files
committed
Updated an example, features, and changes based on new support for path and command completion
1 parent 5ae7251 commit d9de552

File tree

4 files changed

+16
-18
lines changed

4 files changed

+16
-18
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ News
2222
* Example of how to use regular expressions in a transcript test
2323
* Added CmdResult namedtumple for returning and storing results
2424
* Added local file system path completion for ``edit``, ``load``, ``save``, and ``shell`` commands
25+
* Add shell command completion for ``shell`` command or ``!`` shortcut
2526

2627
0.7.0
2728
-----

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ cmd2 provides the following features, in addition to those already existing in c
3535
- Pipe output to shell commands with `|`
3636
- Simple transcript-based application testing
3737
- Unicode character support (*Python 3 only*)
38+
- Path completion for ``edit``, ``load``, ``save``, and ``shell`` commands
3839

3940
Instructions for implementing each feature follow.
4041

cmd2.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
# Try to import readline, but allow failure for convenience in Windows unit testing
8383
# Note: If this actually fails, you should install readline on Linux or Mac or pyreadline on Windows
8484
try:
85+
# noinspection PyUnresolvedReferences
8586
import readline
8687
except ImportError:
8788
pass
@@ -479,6 +480,7 @@ class StubbornDict(dict):
479480
480481
Create it with the stubbornDict(arg) factory function.
481482
"""
483+
# noinspection PyMethodOverriding
482484
def update(self, arg):
483485
"""Adds dictionary arg's key-values pairs in to dict
484486
@@ -930,11 +932,11 @@ def precmd(self, statement):
930932
return statement
931933

932934
def parseline(self, line):
933-
"""Parse the line into a command name and a string containing the arguments.
934-
935+
"""Parse the line into a command name and a string containing the arguments.
936+
935937
Used for command tab completion. Returns a tuple containing (command, args, line).
936938
'command' and 'args' may be None if the line couldn't be parsed.
937-
939+
938940
:param line: str - line read by readline
939941
:return: (str, str, str) - tuple containing (command, args, line)
940942
"""
@@ -1354,14 +1356,15 @@ def help_shell(self):
13541356
Usage: shell cmd"""
13551357
self.stdout.write("{}\n".format(help_str))
13561358

1357-
def path_complete(self, text, line, begidx, endidx, dir_exe_only=False):
1359+
def path_complete(self, text, line, begidx, endidx, dir_exe_only=False, dir_only=False):
13581360
"""Method called to complete an input line by local file system path completion.
13591361
13601362
:param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
13611363
:param line: str - the current input line with leading whitespace removed
13621364
:param begidx: int - the beginning indexe of the prefix text
13631365
:param endidx: int - the ending index of the prefix text
13641366
:param dir_exe_only: bool - only return directories and executables, not non-executable files
1367+
:param dir_only: bool - only return directories
13651368
:return: List[str] - a list of possible tab completions
13661369
"""
13671370
# Deal with cases like load command and @ key when path completion is immediately after a shortcut
@@ -1413,6 +1416,8 @@ def path_complete(self, text, line, begidx, endidx, dir_exe_only=False):
14131416
# If we only want directories and executables, filter everything else out first
14141417
if dir_exe_only:
14151418
path_completions = [c for c in path_completions if os.path.isdir(c) or os.access(c, os.X_OK)]
1419+
elif dir_only:
1420+
path_completions = [c for c in path_completions if os.path.isdir(c)]
14161421

14171422
# Get the basename of the paths
14181423
completions = []
@@ -1446,7 +1451,7 @@ def _shell_command_complete(search_text):
14461451
"""Method called to complete an input line by environment PATH executable completion.
14471452
14481453
:param search_text: str - the search text used to find a shell command
1449-
:return: List[str] - a list of possible tab completions
1454+
:return: List[str] - a list of possible tab completions
14501455
"""
14511456

14521457
# Purposely don't match any executable containing wildcards
@@ -1478,7 +1483,7 @@ def _shell_command_complete(search_text):
14781483
def complete_shell(self, text, line, begidx, endidx):
14791484
"""Handles tab completion of executable commands and local file system paths.
14801485
1481-
:param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
1486+
:param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
14821487
:param line: str - the current input line with leading whitespace removed
14831488
:param begidx: int - the beginning index of the prefix text
14841489
:param endidx: int - the ending index of the prefix text

examples/python_scripting.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
1515
This application and the "script_conditional.py" script serve as an example for one way in which this can be done.
1616
"""
17+
import functools
1718
import os
1819

1920
from cmd2 import Cmd, options, make_option, CmdResult, set_use_arg_list
@@ -35,7 +36,6 @@ def __init__(self):
3536
def _set_prompt(self):
3637
"""Set prompt so it displays the current working directory."""
3738
self.cwd = os.getcwd()
38-
self.subdirs = [d for d in os.listdir(self.cwd) if os.path.isdir(d)]
3939
self.prompt = '{!r} $ '.format(self.cwd)
4040

4141
def postcmd(self, stop, line):
@@ -83,17 +83,8 @@ def do_cd(self, arg, opts=None):
8383
self.perror(err, traceback_war=False)
8484
self._last_result = CmdResult(out, err)
8585

86-
# noinspection PyUnusedLocal
87-
def complete_cd(self, text, line, begidx, endidx):
88-
"""Handles completion of arguments for the cd command.
89-
90-
:param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
91-
:param line: str - the current input line with leading whitespace removed
92-
:param begidx: str - the beginning indexe of the prefix text
93-
:param endidx: str - the ending index of the prefix text
94-
:return: List[str] - a list of possible tab completions
95-
"""
96-
return [d for d in self.subdirs if d.startswith(text)]
86+
# Enable directory completion for cd command by freezing an argument to path_complete() with functools.partialmethod
87+
complete_cd = functools.partialmethod(Cmd.path_complete, dir_only=True)
9788

9889
@options([make_option('-l', '--long', action="store_true", help="display in long format with one item per line")],
9990
arg_desc='')

0 commit comments

Comments
 (0)