Repository: xonsh/xonsh

Issue:
[Regression] 0.9.11: ExecAlias detected for aliases that are not code blocks
In the recently released version 0.9.11, there was a change that expanded the scope of which aliases are identified as `ExecAlias` aliases. This expanded scope has caused a change that requires me to press CTRL-C to exit some kind of hanging state after such aliases are executed.

The specific change was made in e4fada56b0e9b543ae5764b44caeff6b39635d60, with this regex change, from this:

```
@lazyobject
def SUB_EXEC_ALIAS_RE():
    return re.compile(r"@\(|\$\(|!\(|\$\[|!\[")
```
to this:
```
@lazyobject
def SUB_EXEC_ALIAS_RE():
    return re.compile(r"@\(|\$\(|!\(|\$\[|!\[|\&\&|\|\||and|or")
```

The consequence of this change is that alias commands can now be detected as `ExecAlias` commands simply because they contain the substrings `and` or `or`.  The following two aliases of mine are causing these problems:

```
aliases['gl'] = 'git log --oneline --decorate --all --graph --abbrev-commit'
aliases['gpo'] = "git push --tags origin master"
```

The word "decorate" contains **or**, and in the second example the word "origin" contains **or**.

More details are given in the _how to reproduce_ section further down.

## xonfig

```
$ xonfig
+------------------+-------------------------------------------------------+
| xonsh            | 0.9.11                                                |
| Git SHA          | dd16d59d                                              |
| Commit Date      | Aug 25 13:21:16 2019                                  |
| Python           | 3.7.4                                                 |
| PLY              | 3.11                                                  |
| have readline    | False                                                 |
| prompt toolkit   | 2.0.9                                                 |
| shell type       | prompt_toolkit2                                       |
| pygments         | 2.3.1                                                 |
| on posix         | False                                                 |
| on linux         | False                                                 |
| on darwin        | False                                                 |
| on windows       | True                                                  |
| on cygwin        | <xonsh.lazyasd.LazyBool object at 0x000002CB1A86D288> |
| on msys2         | <xonsh.lazyasd.LazyBool object at 0x000002CB1A86D5C8> |
| is superuser     | False                                                 |
| default encoding | utf-8                                                 |
| xonsh encoding   | utf-8                                                 |
| encoding errors  | surrogateescape                                       |
+------------------+-------------------------------------------------------+
```

## Expected Behavior

The alias just executes as normal.

## Current Behavior

After the alias is executed, execution hangs until CTRL-C is pressed.  This happens because `ExecAlias` is used for aliases so affected.

## Steps to Reproduce

Here are two aliases that cause the problem for me:

```
aliases['gl'] = 'git log --oneline --decorate --all --graph --abbrev-commit'
aliases['gpo'] = "git push --tags origin master"
```

Each of them **contains the substring `or`**, which leads to them being detected as `ExecAlias` aliases:

```
$ aliases['gl']
ExecAlias('git log --oneline --decorate --all --graph --abbrev-commit\n', filename='<exec-alias:gl>')
```

To reproduce the problematic behaviour:

1. Run xonsh 0.9.11 in a Windows cmd prompt
2. `cd` into a git cloned repo
3. type `$ gl` to trigger the alias.
4. The git log displays. To exit the interactive log view, press `q`
5. You should see that you do not return to the xonsh prompt.
6. Hit CTRL-C to return to the xonsh prompt.

To work around the problem, split the string when setting up the alias:

```
aliases['gl'] = 'git log --oneline --decorate --all --graph --abbrev-commit'.split()
```
This way it does not become an `ExecAlias`:

```
$ aliases['gl']
['git',
 'log',
 '--oneline',
 '--decorate',
 '--all',
 '--graph',
 '--abbrev-commit']
```

Now, if you repeat the reproducer steps given above, there will be no "hang" stage after exiting the command with `q`.


Discussion:
Thanks for reporting @cjrh!
That's definitely my fault. We can adjust the regex to only pick up the `and` / `or` when surrounded by whitespace

Resolving patch:
diff --git a/xonsh/aliases.py b/xonsh/aliases.py
--- a/xonsh/aliases.py
+++ b/xonsh/aliases.py
@@ -44,7 +44,7 @@
 
 @lazyobject
 def SUB_EXEC_ALIAS_RE():
-    return re.compile(r"@\(|\$\(|!\(|\$\[|!\[|\&\&|\|\||and|or")
+    return re.compile(r"@\(|\$\(|!\(|\$\[|!\[|\&\&|\|\||\s+and\s+|\s+or\s+")
 
 
 class Aliases(cabc.MutableMapping):


Test patch:
diff --git a/tests/test_integrations.py b/tests/test_integrations.py
--- a/tests/test_integrations.py
+++ b/tests/test_integrations.py
@@ -347,6 +347,22 @@ def completions(pref, *args):
         "",
         0,
     ),
+    #
+    # test single check_output
+    #
+    (
+        """
+def _echo(args):
+    print(' '.join(args))
+aliases['echo'] = _echo
+
+from xonsh.lib.subprocess import check_output
+
+print(check_output(["echo", "hello"]).decode("utf8"))
+""",
+        "hello\n\n",
+        0,
+    ),
 ]