summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2017-05-17 21:23:44 -0400
committerTodd Leonhardt <todd.leonhardt@gmail.com>2017-05-17 21:23:44 -0400
commitd9de55267102f9b5d389e20917edee4b5f5e7097 (patch)
treecb2bc5c4b14d2ffa72500483788587f09b928b2d
parent5ae72515ffaaa37063cdb073d9790f1426e4abcb (diff)
downloadcmd2-git-d9de55267102f9b5d389e20917edee4b5f5e7097.tar.gz
Updated an example, features, and changes based on new support for path and command completion
-rw-r--r--CHANGES.md1
-rwxr-xr-xREADME.md1
-rwxr-xr-xcmd2.py17
-rwxr-xr-xexamples/python_scripting.py15
4 files changed, 16 insertions, 18 deletions
diff --git a/CHANGES.md b/CHANGES.md
index b0063fb7..b7117215 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -22,6 +22,7 @@ News
* Example of how to use regular expressions in a transcript test
* Added CmdResult namedtumple for returning and storing results
* Added local file system path completion for ``edit``, ``load``, ``save``, and ``shell`` commands
+* Add shell command completion for ``shell`` command or ``!`` shortcut
0.7.0
-----
diff --git a/README.md b/README.md
index 01d2850c..cd739773 100755
--- a/README.md
+++ b/README.md
@@ -35,6 +35,7 @@ cmd2 provides the following features, in addition to those already existing in c
- Pipe output to shell commands with `|`
- Simple transcript-based application testing
- Unicode character support (*Python 3 only*)
+- Path completion for ``edit``, ``load``, ``save``, and ``shell`` commands
Instructions for implementing each feature follow.
diff --git a/cmd2.py b/cmd2.py
index 42d1306f..1f65f5a1 100755
--- a/cmd2.py
+++ b/cmd2.py
@@ -82,6 +82,7 @@ except ImportError:
# Try to import readline, but allow failure for convenience in Windows unit testing
# Note: If this actually fails, you should install readline on Linux or Mac or pyreadline on Windows
try:
+ # noinspection PyUnresolvedReferences
import readline
except ImportError:
pass
@@ -479,6 +480,7 @@ class StubbornDict(dict):
Create it with the stubbornDict(arg) factory function.
"""
+ # noinspection PyMethodOverriding
def update(self, arg):
"""Adds dictionary arg's key-values pairs in to dict
@@ -930,11 +932,11 @@ class Cmd(cmd.Cmd):
return statement
def parseline(self, line):
- """Parse the line into a command name and a string containing the arguments.
-
+ """Parse the line into a command name and a string containing the arguments.
+
Used for command tab completion. Returns a tuple containing (command, args, line).
'command' and 'args' may be None if the line couldn't be parsed.
-
+
:param line: str - line read by readline
:return: (str, str, str) - tuple containing (command, args, line)
"""
@@ -1354,7 +1356,7 @@ class Cmd(cmd.Cmd):
Usage: shell cmd"""
self.stdout.write("{}\n".format(help_str))
- def path_complete(self, text, line, begidx, endidx, dir_exe_only=False):
+ def path_complete(self, text, line, begidx, endidx, dir_exe_only=False, dir_only=False):
"""Method called to complete an input line by local file system path completion.
:param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
@@ -1362,6 +1364,7 @@ class Cmd(cmd.Cmd):
:param begidx: int - the beginning indexe of the prefix text
:param endidx: int - the ending index of the prefix text
:param dir_exe_only: bool - only return directories and executables, not non-executable files
+ :param dir_only: bool - only return directories
:return: List[str] - a list of possible tab completions
"""
# Deal with cases like load command and @ key when path completion is immediately after a shortcut
@@ -1413,6 +1416,8 @@ class Cmd(cmd.Cmd):
# If we only want directories and executables, filter everything else out first
if dir_exe_only:
path_completions = [c for c in path_completions if os.path.isdir(c) or os.access(c, os.X_OK)]
+ elif dir_only:
+ path_completions = [c for c in path_completions if os.path.isdir(c)]
# Get the basename of the paths
completions = []
@@ -1446,7 +1451,7 @@ class Cmd(cmd.Cmd):
"""Method called to complete an input line by environment PATH executable completion.
:param search_text: str - the search text used to find a shell command
- :return: List[str] - a list of possible tab completions
+ :return: List[str] - a list of possible tab completions
"""
# Purposely don't match any executable containing wildcards
@@ -1478,7 +1483,7 @@ class Cmd(cmd.Cmd):
def complete_shell(self, text, line, begidx, endidx):
"""Handles tab completion of executable commands and local file system paths.
- :param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
+ :param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
:param line: str - the current input line with leading whitespace removed
:param begidx: int - the beginning index of the prefix text
:param endidx: int - the ending index of the prefix text
diff --git a/examples/python_scripting.py b/examples/python_scripting.py
index cecd7ec7..baa15f3f 100755
--- a/examples/python_scripting.py
+++ b/examples/python_scripting.py
@@ -14,6 +14,7 @@ and the "py run('myscript.py')" syntax comes into play.
This application and the "script_conditional.py" script serve as an example for one way in which this can be done.
"""
+import functools
import os
from cmd2 import Cmd, options, make_option, CmdResult, set_use_arg_list
@@ -35,7 +36,6 @@ class CmdLineApp(Cmd):
def _set_prompt(self):
"""Set prompt so it displays the current working directory."""
self.cwd = os.getcwd()
- self.subdirs = [d for d in os.listdir(self.cwd) if os.path.isdir(d)]
self.prompt = '{!r} $ '.format(self.cwd)
def postcmd(self, stop, line):
@@ -83,17 +83,8 @@ class CmdLineApp(Cmd):
self.perror(err, traceback_war=False)
self._last_result = CmdResult(out, err)
- # noinspection PyUnusedLocal
- def complete_cd(self, text, line, begidx, endidx):
- """Handles completion of arguments for the cd command.
-
- :param text: str - the string prefix we are attempting to match (all returned matches must begin with it)
- :param line: str - the current input line with leading whitespace removed
- :param begidx: str - the beginning indexe of the prefix text
- :param endidx: str - the ending index of the prefix text
- :return: List[str] - a list of possible tab completions
- """
- return [d for d in self.subdirs if d.startswith(text)]
+ # Enable directory completion for cd command by freezing an argument to path_complete() with functools.partialmethod
+ complete_cd = functools.partialmethod(Cmd.path_complete, dir_only=True)
@options([make_option('-l', '--long', action="store_true", help="display in long format with one item per line")],
arg_desc='')