summaryrefslogtreecommitdiff
path: root/cmd2/parsing.py
diff options
context:
space:
mode:
authorkotfu <kotfu@kotfu.net>2018-04-23 18:34:08 -0600
committerkotfu <kotfu@kotfu.net>2018-04-23 18:34:08 -0600
commit7ac59187ffbc14e2eb14a00866231c8b18e1a087 (patch)
tree1d8013987fc9612387cc89b4ba34ff5da9c97263 /cmd2/parsing.py
parent65bf06a6e9712c87802bf8c319442a8b4cb00e6f (diff)
downloadcmd2-git-7ac59187ffbc14e2eb14a00866231c8b18e1a087.tar.gz
Shortcut and alias processing added to CommandParser()
Diffstat (limited to 'cmd2/parsing.py')
-rw-r--r--cmd2/parsing.py44
1 files changed, 41 insertions, 3 deletions
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index 5bb8d654..dece2b5e 100644
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -31,7 +31,10 @@ class Statement(str):
self.outputTo = None
class CommandParser():
- """Parse raw text into command components."""
+ """Parse raw text into command components.
+
+ Shortcuts is a list of tuples with each tuple containing the shortcut and the expansion.
+ """
def __init__(
self,
quotes=['"', "'"],
@@ -39,14 +42,18 @@ class CommandParser():
redirection_chars=['|', '<', '>'],
terminators=[';'],
multilineCommands = [],
+ aliases = {},
+ shortcuts = [],
):
self.quotes = quotes
self.allow_redirection = allow_redirection
self.redirection_chars = redirection_chars
self.terminators = terminators
self.multilineCommands = multilineCommands
+ self.aliases = aliases
+ self.shortcuts = shortcuts
- def parseString(self, rawinput):
+ def parseString(self, line):
# strip C-style comments
# shlex will handle the python/shell style comments for us
def replacer(match):
@@ -61,7 +68,22 @@ class CommandParser():
r'/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE
)
- rawinput = re.sub(pattern, replacer, rawinput)
+ line = re.sub(pattern, replacer, line)
+ rawinput = line
+
+ # expand shortcuts, have to do this first because
+ # a shortcut can expand into multiple tokens, ie '!ls' becomes
+ # 'shell ls'
+ for (shortcut, expansion) in self.shortcuts:
+ if rawinput.startswith(shortcut):
+ # If the next character after the shortcut isn't a space, then insert one
+ shortcut_len = len(shortcut)
+ if len(rawinput) == shortcut_len or rawinput[shortcut_len] != ' ':
+ expansion += ' '
+
+ # Expand the shortcut
+ rawinput = rawinput.replace(shortcut, expansion, 1)
+ break
s = shlex.shlex(rawinput, posix=False)
s.whitespace_split = True
@@ -140,11 +162,27 @@ class CommandParser():
suffix = None
(command, args) = self._command_and_args(tokens)
+ # expand aliases
+ # make a copy of aliases so we can edit it
+ tmp_aliases = list(self.aliases.keys())
+ keep_expanding = len(tmp_aliases) > 0
+
+ while keep_expanding:
+ for cur_alias in tmp_aliases:
+ keep_expanding = False
+ if command == cur_alias:
+ command = self.aliases[cur_alias]
+ tmp_aliases.remove(cur_alias)
+ keep_expanding = len(tmp_aliases) > 0
+ break
+
+ # set multiline
if command in self.multilineCommands:
multilineCommand = command
else:
multilineCommand = None
+ # build Statement object
result = Statement(args)
result.raw = rawinput
result.command = command