summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcmd2/cmd2.py2
-rw-r--r--cmd2/parsing.py15
-rw-r--r--tests/test_cmd2.py2
-rw-r--r--tests/test_shlexparsing.py41
4 files changed, 36 insertions, 24 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index d9cbd2b0..8165f411 100755
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -2181,7 +2181,7 @@ class Cmd(cmd.Cmd):
# raise EmptyStatement()
# statement = self.parser_manager.parsed(line) # deleteme
statement = self.command_parser.parseString(line)
- while statement.multilineCommand and (statement.terminator == ''):
+ while statement.multilineCommand and not statement.terminator:
line = '%s\n%s' % (statement.raw,
self.pseudo_raw_input(self.continuation_prompt))
statement = self.command_parser.parseString(line)
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index f4f9a6a3..2c01fb70 100644
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -7,6 +7,8 @@ import shlex
import cmd2
+BLANK_LINE = '\n\n'
+
class Statement(str):
"""String subclass with additional attributes to store the results of parsing.
@@ -85,13 +87,19 @@ class CommandParser():
line = line.replace(shortcut, expansion, 1)
break
+ # handle the special case/hardcoded terminator of a blank line
+ # we have to do this before we shlex on whitespace because it
+ # destroys all unquoted whitespace in the input
+ terminator = None
+ if line[-2:] == BLANK_LINE:
+ terminator = BLANK_LINE
+
s = shlex.shlex(line, posix=False)
s.whitespace_split = True
tokens = self.split_on_punctuation(list(s))
# of the valid terminators, find the first one to occur in the input
terminator_pos = len(tokens)+1
- terminator = None
for test_terminator in self.terminators:
try:
pos = tokens.index(test_terminator)
@@ -104,7 +112,10 @@ class CommandParser():
pass
if terminator:
- terminator_pos = tokens.index(terminator)
+ if terminator == BLANK_LINE:
+ terminator_pos = len(tokens)+1
+ else:
+ terminator_pos = tokens.index(terminator)
# everything before the first terminator is the command and the args
(command, args) = self._command_and_args(tokens[:terminator_pos])
#terminator = tokens[terminator_pos]
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index f2ee16af..068ea08f 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -1358,7 +1358,7 @@ def test_multiline_complete_statement_without_terminator(multiline_app):
line = '{} {}'.format(command, args)
statement = multiline_app._complete_statement(line)
assert statement == args
- assert statement.parsed.command == command
+ assert statement.command == command
def test_clipboard_failure(capsys):
diff --git a/tests/test_shlexparsing.py b/tests/test_shlexparsing.py
index d0907820..269a5753 100644
--- a/tests/test_shlexparsing.py
+++ b/tests/test_shlexparsing.py
@@ -232,9 +232,10 @@ def test_parse_multiline_command_ignores_redirectors_within_it(parser):
# """A terminator within a comment will be ignored and won't terminate a multiline command.
# Un-closed comments effectively comment out everything after the start."""
# line = 'multiline command /* with comment in progress;'
-# results = parser.parseString(line)
-# assert results.multilineCommand == 'multiline'
-# assert not 'args' in results
+# statement = parser.parseString(line)
+# assert statement.multilineCommand == 'multiline'
+# assert statement.args == 'command'
+# assert not statement.terminator
def test_parse_multiline_with_complete_comment(parser):
line = 'multiline command /* with comment complete */ is done;'
@@ -243,23 +244,23 @@ def test_parse_multiline_with_complete_comment(parser):
assert results.args == 'command is done'
assert results.terminator == ';'
-# def test_parse_multiline_termninated_by_empty_line(parser):
-# line = 'multiline command ends\n\n'
-# results = parser.parseString(line)
-# assert results.multilineCommand == 'multiline'
-# assert results.args == 'command ends'
-# assert len(results.terminator) == 2
-# assert results.terminator[0] == '\n'
-# assert results.terminator[1] == '\n'
-
-# def test_parse_multiline_ignores_terminators_in_comments(parser):
-# line = 'multiline command "with term; ends" now\n\n'
-# results = parser.parseString(line)
-# assert results.multilineCommand == 'multiline'
-# assert results.args == 'command "with term; ends" now'
-# assert len(results.terminator) == 2
-# assert results.terminator[0] == '\n'
-# assert results.terminator[1] == '\n'
+def test_parse_multiline_termninated_by_empty_line(parser):
+ line = 'multiline command ends\n\n'
+ results = parser.parseString(line)
+ assert results.multilineCommand == 'multiline'
+ assert results.args == 'command ends'
+ assert len(results.terminator) == 2
+ assert results.terminator[0] == '\n'
+ assert results.terminator[1] == '\n'
+
+def test_parse_multiline_ignores_terminators_in_comments(parser):
+ line = 'multiline command "with term; ends" now\n\n'
+ results = parser.parseString(line)
+ assert results.multilineCommand == 'multiline'
+ assert results.args == 'command "with term; ends" now'
+ assert len(results.terminator) == 2
+ assert results.terminator[0] == '\n'
+ assert results.terminator[1] == '\n'
def test_parse_command_with_unicode_args(parser):
line = 'drink café'