Olical / conjure

Interactive evaluation for Neovim (Clojure, Fennel, Janet, Racket, Hy, MIT Scheme, Guile, Python and more!)
https://conjure.oli.me.uk
The Unlicense
1.79k stars 110 forks source link

Pretty printing in babashka #406

Open frankitox opened 2 years ago

frankitox commented 2 years ago

Pretty printing in babashka doesn't work, if I try to print something it ends up using pr-str, so in the log buffer you'll see something like:

{:hello "world", :some "other", :stuff "that's", :pretty "printed"}

Thanks to @borkdude I found that babashka's nrepl server uses clojure.pprint/pprint for some values of :nrepl.middleware.print/print.

https://github.com/babashka/babashka.nrepl/blob/c8c8a766e026d5f87e0968a179dad70e13aa13ee/src/babashka/nrepl/impl/server.clj#L25-L28

Once I added "conjure.internal/pprint" to this list, I still got everything printed in one line. Then I realized babashka also has a custom "right-margin" key for :nrepl.middleware.print/options.

https://github.com/babashka/babashka.nrepl/blob/c8c8a766e026d5f87e0968a179dad70e13aa13ee/src/babashka/nrepl/impl/server.clj#L66-L70

For this I ended up modifying conjure like this:

https://github.com/frankitox/conjure/commit/3dad8c013abedadb1bfa2cd4e125ddb39184200d

But it may make more sense to add a default value to babashka, Clojure's code base uses 72

https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/pprint_base.clj#L40-L45

oryband commented 1 year ago

Is there a way to configure conjure without modifying the code? I'm using babashka on a daily basis with large chunks of hashmaps and really missing formatting. It's hard to debug when everything is one-lined.

Olical commented 1 year ago

I'll take a look at this on my day off tomorrow. Noting it down now. Sorry it slipped the net before!

Olical commented 1 year ago

For this I ended up modifying conjure like this:

https://github.com/frankitox/conjure/commit/3dad8c013abedadb1bfa2cd4e125ddb39184200d

Sadly this link is a 404 now 😭 I'll try and work out what was done, I guess an option was set?

Olical commented 1 year ago

I set the pretty printer to clojure.pprint/pprint and I've set the right-margin to 72 but it doesn't do anything still, I'm on an up to date babashka, I just can't get it to pretty print anything. Is there a magic option to babashka I'm missing? I can't see anything in the docs on it or the source.

We also can't set the pretty printer to clojure.pprint/pprint in JVM Clojure, that throws errors. And we can't set it to the Conjure one in babashka land. So that means I'll have to sniff the type of the REPL (JVM or babashka) and then override the pprint function if I spot babashka, I think. It's a shame these are incompatible, or maybe I'm just missing something.

You can use the develop branch to get right-margin support but I am keeping the print fn as conjure.internal/pprint for now since that's what works in JVM Clojure.

If anyone has managed to get this working and knows how, please let me know!

agorgl commented 1 year ago

Just bumped into this problem on Windows environments too that use clojure by installing clj-deps through scoop (it seems that it has babashka as the backend implementation?)

borkdude commented 1 year ago

Babashka is not involved in clj-deps.

Olical commented 1 year ago

Hey, @borkdude! I was going to come and ask for your advice on this eventually. Did you happen to have any examples / test scripts you use to enable and check the pretty printing for babashka's nREPL support?

I have a feeling it's working fine, I'm just missing a required parameter. As I mentioned above, I set the printer and a right margin (just in case that's required) and I'm sending the properties that work for JVM nREPL. The list of pretty print functions are hard coded in babashka too I think? Pretty sure that's the conclusion I came to reading the source.

If you have a working example anywhere or in tests I'd love to see it so I can copy it exactly.

Olical commented 1 year ago

Conjure actually auto loads it's own pprint function on connection but I think we can't use that with bb because of the list of pre-approved printers?

borkdude commented 1 year ago

Did you happen to have any examples / test scripts you use to enable and check the pretty printing for babashka's nREPL support?

There are some tests here: https://github.com/babashka/babashka.nrepl/blob/c6c3553404f424ff5c591cffe24254f01cc2f92a/test/babashka/nrepl/server_test.clj#L150

Olical commented 10 months ago

Interestingly the preamble Conjure sends was failing on babashka REPLs! Apparently capturing the original ns with (resolve *ns*) then in-ns-ing back to it later makes bb REPLs unhappy. I've replaced it with capturing the symbol form of the current *ns* then giving that symbol to in-ns which works great everywhere.

So my pprint nREPL printer function I was defining was probably never actually getting defined in babashka nREPL environments. Now that's fixed and Conjure's pre-amble definitely makes it across the wire buuuut it still doesn't pretty print. I'm sure this is one step closer to fixing it though!