Repository: hylang/hy

Issue:
Delimit python "--spy" output.
I've implemented highlighting python code outputted from `--spy` in `inferior-hy-mode`.

However I need to be able to distinguish where the python block ends.

I can't take the last line to be the limit as:

```
=> (defn x [])
def x():
    pass
;; nothing

=> (+ 1 2)
(1 + 2)
3
;; standard

=> x
x
Traceback (most recent call last):
  File "my-file-path", line 198, in hy_eval
    return eval(ast_compile(expr, "<eval>", "eval"), namespace)
  File "<eval>", line 1, in <module>
NameError: name 'x' is not defined
;; many extra lines

=> (})
  File "<stdin>", line 1, column 2

  (})
   ^
LexException: Ran into a RCURLY where it wasn't expected.
;; no --spy output at all
```

A delimiter would do it unless you all know a better solution. 


Discussion:
> I've implemented highlighting python code

...huh? I mean, I'm not sure what exactly this would have to do with --spy...is your code available for viewing anywhere? (FWIW roll-your-own syntax highlighting is a bit trickier than it sounds...)
The problem with delimiters is that they may appear in the output.

A long, random delimiter, like a UUID, is unlikely to cause conflicts, but we probably don't want that to appear in the terminal. If emacs can hide this, maybe it could be enabled via a command-line option.

You can already distinguish stdout from stderr, right? Maybe we should open a third pipe just for the --spy output. If emacs can create one, it could be a command-line argument to the hy executable, like `--spy-to mypipe` or something. I'm not sure how complicated this is to set up in a cross-platform way.


@kirbyfan64, we're talking about seting up highlighting for hy-mode in emacs, see hylang/hy-mode#46.
>  roll-your-own syntax highlighting

@kirbyfan64 It doesn't, it takes highlighting from `python-mode` and takes results from applying `font-lock-mode`.

> If emacs can hide this

Emacs can, I'm processing the raw string and transforming it to whatever I want, not just applying face properties. A command-line flag might be reasonable in this case, like `--spy-emacs` that uses specified UUID to start and end a python block.

> You can already distinguish stdin from stderr

That sounds complicated, an emacs flag would be much easier.
Ah, that added context would have been really helpful in the issue description...
@kirbyfan64 My apologies. If you work in emacs, feel free to suggest features or things you would like improved. I'm working on improving hy's tooling.
Apart from the Emacs issues that motivated this issue originally, it would be more visually intelligible to have some kind of delimiter. With something like

```
=> (+ 1 2 3)
1 + 2 + 3
6
```

it's annoying to have to think about which parts of the output are the Python equivalent and which are the result, which are fundamentally pretty different things.

Resolving patch:
diff --git a/hy/repl.py b/hy/repl.py
--- a/hy/repl.py
+++ b/hy/repl.py
@@ -240,7 +240,7 @@ class REPL(code.InteractiveConsole):
     Note that as with :func:`code.interact`, changes to ``(locals)`` inside the REPL are
     not propagated back to the original scope."""
 
-    def __init__(self, spy=False, output_fn=None, locals=None, filename="<stdin>", allow_incomplete=True):
+    def __init__(self, spy=False, spy_delimiter=('-' * 30), output_fn=None, locals=None, filename="<stdin>", allow_incomplete=True):
 
         # Create a proper module for this REPL so that we can obtain it easily
         # (e.g. using `importlib.import_module`).
@@ -293,6 +293,7 @@ def __init__(self, spy=False, output_fn=None, locals=None, filename="<stdin>", a
         )
 
         self.spy = spy
+        self.spy_delimiter = spy_delimiter
         self.last_value = None
         self.print_last_value = True
 
@@ -332,6 +333,7 @@ def ast_callback(self, exec_ast, eval_ast):
                     type_ignores=[],
                 )
                 print(ast.unparse(new_ast))
+                print(self.spy_delimiter)
             except Exception:
                 msg = "Exception in AST callback:\n{}\n".format(traceback.format_exc())
                 self.write(msg)


Test patch: