Repository: xonsh/xonsh

Issue:
Syntax errors when using bashisms xontrib
At least making assignment statements and entering function definitions at the prompt is 
broken when using the included `bashisms` xontrib and prompt toolkit.

## xonfig

```
$ xonfig                                                                                         
+------------------+---------------------+
| xonsh            | 0.8.12              |
| Git SHA          | 3edd2df7            |
| Commit Date      | May 9 07:50:20 2019 |
| Python           | 3.7.3               |
| PLY              | 3.11                |
| have readline    | True                |
| prompt toolkit   | 2.0.9               |
| shell type       | prompt_toolkit2     |
| pygments         | 2.3.1               |
| on posix         | True                |
| on linux         | True                |
| distro           | ubuntu              |
| on darwin        | False               |
| on windows       | False               |
| on cygwin        | False               |
| on msys2         | False               |
| is superuser     | False               |
| default encoding | utf-8               |
| xonsh encoding   | utf-8               |
| encoding errors  | surrogateescape     |
+------------------+---------------------+

```

## Expected Behavior
I should be able to create new variables and function definitions, no sweat.

## Current Behavior

Things work fine until I start the shell with the xontrib `bashisms` loaded, or after I start the shell without it and load it later.

Assignment statements appear to go into multiline mode after hitting the return
key, and after a second return key, a stacktrace appears. The assignment
statement does not succeed.

Function definitions at the prompt result in an IndexError and the function is
not defined afterwards.

### Traceback (if applicable)

#### Assignment

```
$ a = 1                                                                                          
$ a                                                                                              
1
$ xontrib load bashisms                                                                          
$ b = 1 
..................................................                                                                                                
Traceback (most recent call last):
  File "/home/eddie/source/xonsh/xonsh/ptk2/shell.py", line 173, in _push
    code = self.execer.compile(src, mode="single", glbs=self.ctx, locs=None)
  File "/home/eddie/source/xonsh/xonsh/execer.py", line 135, in compile
    tree = self.parse(input, ctx, mode=mode, filename=filename, transform=transform)
  File "/home/eddie/source/xonsh/xonsh/execer.py", line 96, in parse
    tree, input = self._parse_ctx_free(input, mode=mode, filename=filename)
  File "/home/eddie/source/xonsh/xonsh/execer.py", line 235, in _parse_ctx_free
    raise original_error from None
  File "/home/eddie/source/xonsh/xonsh/execer.py", line 220, in _parse_ctx_free
    debug_level=(self.debug_level > 2),
  File "/home/eddie/source/xonsh/xonsh/parsers/base.py", line 543, in parse
    tree = self.parser.parse(input=s, lexer=self.lexer, debug=debug_level)
  File "/home/eddie/source/xonsh/xonsh/ply/ply/yacc.py", line 335, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "/home/eddie/source/xonsh/xonsh/ply/ply/yacc.py", line 1203, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "/home/eddie/source/xonsh/xonsh/ply/ply/yacc.py", line 194, in call_errorfunc
    r = errorfunc(token)
  File "/home/eddie/source/xonsh/xonsh/parsers/base.py", line 3285, in p_error
    self._parse_error("no further code", None)
  File "/home/eddie/source/xonsh/xonsh/parsers/base.py", line 676, in _parse_error
    raise err
  File "<string>", line None
SyntaxError: None: no further code
$ b                                                                                              
Traceback (most recent call last):
  File "/home/eddie/source/xonsh/xonsh/built_ins.py", line 560, in _run_binary
    p = self.cls(self.cmd, bufsize=bufsize, **kwargs)
  File "/home/eddie/source/xonsh/xonsh/proc.py", line 583, in __init__
    *args, stdin=stdin, stdout=stdout, stderr=stderr, **kwargs
  File "/home/eddie/.pyenv/versions/3.7.3/lib/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/home/eddie/.pyenv/versions/3.7.3/lib/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'b': 'b'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/eddie/source/xonsh/xonsh/proc.py", line 1856, in __init__
    proc = spec.run(pipeline_group=pipeline_group)
  File "/home/eddie/source/xonsh/xonsh/built_ins.py", line 549, in run
    p = self._run_binary(kwargs)
  File "/home/eddie/source/xonsh/xonsh/built_ins.py", line 571, in _run_binary
    raise XonshError(e)
xonsh.tools.XonshError: xonsh: subprocess mode: command not found: b
Did you mean one of the following?
    bg:  Alias
    e:   Alias
    z:   Alias
    bc:  Command (/usr/bin/bc)
    ab:  Command (/usr/bin/ab)

b: command not found
```

#### Function definition

```
$ def f(): 
..................................................     pass 
..................................................                                                                                                
$ f                                                                                              
<function __main__.f>
$ xontrib load bashisms                                                                          
$ def g(): 
..................................................     pass 
..................................................                                                                                                
Traceback (most recent call last):
  File "/home/eddie/source/xonsh/xonsh/execer.py", line 220, in _parse_ctx_free
    debug_level=(self.debug_level > 2),
  File "/home/eddie/source/xonsh/xonsh/parsers/base.py", line 543, in parse
    tree = self.parser.parse(input=s, lexer=self.lexer, debug=debug_level)
  File "/home/eddie/source/xonsh/xonsh/ply/ply/yacc.py", line 335, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "/home/eddie/source/xonsh/xonsh/ply/ply/yacc.py", line 1203, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "/home/eddie/source/xonsh/xonsh/ply/ply/yacc.py", line 194, in call_errorfunc
    r = errorfunc(token)
  File "/home/eddie/source/xonsh/xonsh/parsers/base.py", line 3295, in p_error
    self._parse_error(msg, self.currloc(lineno=p.lineno, column=p.lexpos))
  File "/home/eddie/source/xonsh/xonsh/parsers/base.py", line 676, in _parse_error
    raise err
  File "<string>", line None
SyntaxError: /home/eddie/source/xonsh/xontrib/prompt_ret_code.xsh:3:0: ('code: ',)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/eddie/source/xonsh/xonsh/ptk2/shell.py", line 173, in _push
    code = self.execer.compile(src, mode="single", glbs=self.ctx, locs=None)
  File "/home/eddie/source/xonsh/xonsh/execer.py", line 135, in compile
    tree = self.parse(input, ctx, mode=mode, filename=filename, transform=transform)
  File "/home/eddie/source/xonsh/xonsh/execer.py", line 96, in parse
    tree, input = self._parse_ctx_free(input, mode=mode, filename=filename)
  File "/home/eddie/source/xonsh/xonsh/execer.py", line 242, in _parse_ctx_free
    line, nlogical, idx = get_logical_line(lines, idx)
  File "/home/eddie/source/xonsh/xonsh/tools.py", line 544, in get_logical_line
    line = lines[idx]
IndexError: list index out of range
$ g                                                                                              
Traceback (most recent call last):
  File "/home/eddie/source/xonsh/xonsh/built_ins.py", line 560, in _run_binary
    p = self.cls(self.cmd, bufsize=bufsize, **kwargs)
  File "/home/eddie/source/xonsh/xonsh/proc.py", line 583, in __init__
    *args, stdin=stdin, stdout=stdout, stderr=stderr, **kwargs
  File "/home/eddie/.pyenv/versions/3.7.3/lib/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/home/eddie/.pyenv/versions/3.7.3/lib/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'g': 'g'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/eddie/source/xonsh/xonsh/proc.py", line 1856, in __init__
    proc = spec.run(pipeline_group=pipeline_group)
  File "/home/eddie/source/xonsh/xonsh/built_ins.py", line 549, in run
    p = self._run_binary(kwargs)
  File "/home/eddie/source/xonsh/xonsh/built_ins.py", line 571, in _run_binary
    raise XonshError(e)
xonsh.tools.XonshError: xonsh: subprocess mode: command not found: g
Did you mean one of the following?
    fg:  Alias
    bg:  Alias
    e:   Alias
    z:   Alias
    ag:  Command (/usr/local/bin/ag)

g: command not found
```

## Steps to Reproduce

```
# start w/o bashisms loaded
$ a = 1                                                                                      
$ xontrib load bashisms                                                                      
$ a = 1 
```

or

```
# start w/o bashisms loaded
$ xontrib load bashisms                                                                      
$ def f(): 
..................................................     pass 
..................................................          
```


Discussion:

Resolving patch:
diff --git a/xontrib/bashisms.py b/xontrib/bashisms.py
--- a/xontrib/bashisms.py
+++ b/xontrib/bashisms.py
@@ -40,7 +40,7 @@ def replace_bang(m):
                 print("xonsh: no previous commands match '!{}'".format(arg))
                 return ""
 
-    return re.sub(r"!([!$^*]|[\w]+)", replace_bang, cmd.strip())
+    return re.sub(r"!([!$^*]|[\w]+)", replace_bang, cmd)
 
 
 @events.on_ptk_create


Test patch: