From 30e1758478dd287ccddb64ba85655c098bcaf586 Mon Sep 17 00:00:00 2001 From: Anthony Scopatz Date: Tue, 24 May 2016 23:55:07 -0400 Subject: [PATCH] added comma literals to subproc mode --- CHANGELOG.rst | 1 + tests/test_execer.py | 12 ++++++++++++ tests/test_parser.py | 6 ++++++ xonsh/ast.py | 6 +++++- xonsh/lexer.py | 2 +- xonsh/parsers/base.py | 1 + 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5667dd8f4..2152ca398 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,7 @@ Current Developments * When a subprocess exits with a signal (e.g. SIGSEGV), a message is printed, similar to Bash. +* Added comma literals to subproc mode. * ``@$(cmd)`` has been added as a subprocess-mode operator, which replaces in the subprocess command itself with the result of running ``cmd``. diff --git a/tests/test_execer.py b/tests/test_execer.py index dc083571f..1adc8ad0e 100644 --- a/tests/test_execer.py +++ b/tests/test_execer.py @@ -113,6 +113,18 @@ def test_pyeval_redirect(): code = 'echo @("foo") > bar\n' yield check_parse, code +def test_echo_comma(): + code = 'echo ,\n' + yield check_parse, code + +def test_echo_comma_val(): + code = 'echo ,1\n' + yield check_parse, code + +def test_echo_comma_2val(): + code = 'echo 1,2\n' + yield check_parse, code + if __name__ == '__main__': diff --git a/tests/test_parser.py b/tests/test_parser.py index 2cdfd22a4..517037684 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1743,6 +1743,12 @@ def test_git_two_quotes_space_space(): def test_ls_quotes_3_space(): yield check_xonsh_ast, {}, '$[ls "wakka jawaka baraka"]', False +def test_echo_comma(): + yield check_xonsh_ast, {}, '![echo ,]', False + +def test_echo_internal_comma(): + yield check_xonsh_ast, {}, '![echo 1,2]', False + def test_comment_only(): yield check_xonsh_ast, {}, '# hello' diff --git a/xonsh/ast.py b/xonsh/ast.py index ea617ee7f..f84ada291 100644 --- a/xonsh/ast.py +++ b/xonsh/ast.py @@ -52,6 +52,9 @@ def leftmostname(node): elif isinstance(node, (Str, Bytes)): # handles case of "./my executable" rtn = leftmostname(node.s) + elif isinstance(node, Tuple) and len(node.elts) > 0: + # handles case of echo ,1,2,3 + rtn = leftmostname(node.elts[0]) else: rtn = None return rtn @@ -149,7 +152,8 @@ class CtxAwareTransformer(NodeTransformer): maxcol = None else: mincol = min_col(node) - maxcol = max_col(node) + 1 + maxcol = max_col(node) + maxcol = None if maxcol == mincol else maxcol + 1 spline = subproc_toks(line, mincol=mincol, maxcol=maxcol, diff --git a/xonsh/lexer.py b/xonsh/lexer.py index 45b91b8aa..b3efb8a95 100644 --- a/xonsh/lexer.py +++ b/xonsh/lexer.py @@ -42,7 +42,7 @@ _op_map = { '&=': 'AMPERSANDEQUAL', '^=': 'XOREQUAL', '|=': 'PIPEEQUAL', '//=': 'DOUBLEDIVEQUAL', # extra xonsh operators - '?': 'QUESTION', '??': 'DOUBLE_QUESTION', '@$': 'ATDOLLAR', '!': 'BANG', + '?': 'QUESTION', '??': 'DOUBLE_QUESTION', '@$': 'ATDOLLAR', '&': 'AMPERSAND', } for (op, type) in _op_map.items(): diff --git a/xonsh/parsers/base.py b/xonsh/parsers/base.py index 76beae062..da9920aa3 100644 --- a/xonsh/parsers/base.py +++ b/xonsh/parsers/base.py @@ -2285,6 +2285,7 @@ class BaseParser(object): | FALSE | NUMBER | STRING + | COMMA """ # Many tokens cannot be part of this list, such as $, ', ", () # Use a string atom instead.