Repository: xonsh/xonsh

Issue:
xonsh hangs on incorrectly indented for loop
```
condamaster%=🐚 for i in range(1):
.............. print(i)
..............

```

Xonsh hangs here. The issue is that the print(i) isn't indented (side-issue, it should indent automatically, just like IPython). 



Discussion:
Also things look unaligned there because the 🐚symbol takes up two characters in GitHub. They are lined up correctly in the shell.

> Xonsh hangs here. 

I think I know what is happening here. 

> side-issue, it should indent automatically, just like IPython

Agreed.

@asmeurer : What special trick did you use to add the unicode character to your prompt. I have tried without much luck. How does your .xonshrc look?

Uhh. Maybe the issue is differences between win and linux. Acording to this stack-overflow question, then stdin on win is cp1252 and utf-8 on linux. That may explain some of the issues. 
http://stackoverflow.com/questions/2737966/how-to-change-the-stdin-encoding-on-python

Is their solutions a good idea? 

``` python
UTF8Reader = codecs.getreader('utf8')
sys.stdin = UTF8Reader(sys.stdin)

UTF8Writer = codecs.getwriter('utf8')
sys.stdout = UTF8Writer(sys.stdout)



```

@melund - I thought that we were already doing something like that.  I could be wrong though, maybe that was another project :)  Unicode on windows should definitely be supported. 

> @asmeurer : What special trick did you use to add the unicode character to your prompt. I have tried without much luck. How does your .xonshrc look?

https://github.com/asmeurer/dotfiles/blob/02c06f872e124fc912e0a6c005dbe1f8c7a2f7f7/.xonshrc#L152

@scopatz : If I add the unicode character directly to .xonshrc file (the editor support utf8) then I get an error when the file is read. If I add the unicode character with escape characters, the error comes later in the cmdloop.

```
  File "C:\Users\Morten\Anaconda3\lib\site-packages\xonsh\environ.py", line 499, in xonshrc_context
    rc = f.read()
  File "C:\Users\Morten\Anaconda3\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 1785: character maps to <undefined>
```

```
  File "C:\Users\Morten\Anaconda3\lib\site-packages\xonsh\readline_shell.py", line 114, in cmdloop
    super().cmdloop(intro=intro)
  File "C:\Users\Morten\Anaconda3\lib\cmd.py", line 126, in cmdloop
    line = input(self.prompt)
  File "C:\Users\Morten\Anaconda3\lib\encodings\cp850.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character '\u03bb' in position 52: character maps to <undefined>
```

Is the solution something like I wrote above. Any pointers to how I can try to solve it. 


Resolving patch:
diff --git a/xonsh/execer.py b/xonsh/execer.py
--- a/xonsh/execer.py
+++ b/xonsh/execer.py
@@ -178,6 +178,12 @@ def _parse_ctx_free(self, input, mode='exec'):
                     last_error_line = last_error_col = -1
                     input = '\n'.join(lines)
                     continue
+                if last_error_line > 1 and lines[idx-1].rstrip()[-1] == ':':
+                    # catch non-indented blocks and raise error.
+                    prev_indent = len(lines[idx-1]) - len(lines[idx-1].lstrip())
+                    curr_indent = len(lines[idx]) - len(lines[idx].lstrip())
+                    if prev_indent == curr_indent:
+                        raise original_error
                 maxcol = self._find_next_break(line, last_error_col)
                 sbpline = subproc_toks(line,
                                        returnline=True,


Test patch:
diff --git a/tests/test_execer.py b/tests/test_execer.py
--- a/tests/test_execer.py
+++ b/tests/test_execer.py
@@ -4,6 +4,8 @@
 import sys
 import ast
 
+from nose.tools import assert_raises
+
 from xonsh.execer import Execer
 from xonsh.tools import ON_WINDOWS
 
@@ -72,6 +74,10 @@ def test_simple_func_broken():
             "       user='me')\n")
     yield check_parse, code
 
+def test_bad_indent():
+    code = ('if True:\n'
+            'x = 1\n')
+    assert_raises(SyntaxError, check_parse, code)