Open sitepodmatt opened 10 years ago
Interesting - now when you saw via vim-fireplace, does that mean you spin up a lein repl
and then send commands to it via vim? If so, that makes me think there may be something on the server side of nREPL that does this.
After not-yet-enough digging, I suspect what's happening is this: nREPL sets up session bindings for *out*
, which since we're creating a lazy seq are lost before nREPL goes to print out the seq for transport back to the nREPL client (REPLy, vim-fireplace, etc.).
This experiment would seem to support that theory:
user=> (doall (foo nil))
nil Hello, World!
Hello, Mars
Exception talking to many planets user/foo/fn--668 (NO_SOURCE_FILE:5)
I opened an nREPL ticket in JIRA to track this: http://dev.clojure.org/jira/browse/NREPL-45
Replying here instead of on JIRA, because I cannot replicate this in at least one nREPL environment (cider). There, I get:
user> (foo nil)
nil Hello, World!
Hello, Mars
Exception talking to many planets user/eval7991/foo--7992/fn--7993 (form-init3244858523243413901.clj:5)
This is with Clojure 1.6.0-alpha3, nREPL 0.2.3, cider 0.6.0alpha (basically the current HEAD). FWIW, lein repl
doesn't output the 'Mars' line, so there's definitely something going on there; but, I'm reasonably sure it's not nREPL itself given the results I see via cider.
OK, I don't know much about cider but it does appears to set up some middleware (maybe it changes the forcing behavior?). I'll try and install it sometime soon and see what's happening there.
Can you see why/how any *out*
output forced during the (with-out-str (pr val))
could possibly escape out of the nrepl pr-values middleware? I'm stumped, I thought the test case in my patch proved that it doesn't.
OK, I got cider 0.6.0alpha (from Melpa - I tried Marmalade first but got 0.5.0), nREPL 0.2.3, clojure 1.6.0-alpha3, and I'm still seeing:
user> (foo nil)
nil Hello, World!
Exception talking to many planets user/foo/fn--1208 (form-init8029966451087486244.clj:5)
But! When I turn on cider-repl-toggle-pretty-printing
, that does the trick. It turns out it's actually wrapping the execution in a pprint
instead of using the actual :value
:
https://github.com/clojure-emacs/cider/blob/5d650ba612a3be3fc0de79272ed7525d599d920f/cider-util.el#L74-L76 It would be unfortunate for all clients to have to do something like that, but if that's the path we have to go down I can work on that.
@cemerick let me know what you think.
Gah, you're right. Pretty-printing trolls me again. :-P
Taking a second look at the proposed patch now.
I think this stackoverflow thread sums it up pretty well as behavior is observed via lein repl (and indirectly via vim-fireplace): http://stackoverflow.com/questions/20437767/what-happens-to-second-println-statement-clojure-repl?noredirect=1#comment30532207_20437767
Thanks.
Okay so its look like REPL-y tries captures the result of the whole expression first as this prints nothing for 15 seconds (map (fn [x] Thread/sleep 5000 (println "x") x) [1 2 3])
Should ideally stdout buffer be flushed if an exception occurs like on vanilla clojure repl? Or would this side effect confiict with the idea of printing the result of the expression