Shadow-cljs: Pretty printing not working in cider

Created on 18 Jun 2019  路  8Comments  路  Source: thheller/shadow-cljs

Pretty printing of edn values is not working in cider specifically with shadow-cljs.

Bozhidar pointed me to some changes that were made to nrepl piggieback.clj in this commit.
https://github.com/nrepl/piggieback/commit/8e0ff8911a1a7ad012dba19d3be6d7c0515d418d , saying that maybe that made shadow-cljs incompatible due to shadow-cljs having its own implementation of that. (?)

thheller later narrowed this down to this part :
https://github.com/nrepl/piggieback/blob/master/src/cider/piggieback.clj#L215-L218

help wanted

All 8 comments

I don't know how cider does anything. I also cannot figure it out by looking through the code.

If someone can explain to what should be happening (ideally based off a nrepl message flow) I can maybe look into it further but otherwise I'm clueless how this is all supposed to work. The result value is printed on the CLJS side and the printed string is just returned as the :value via nREPL.

I can't find where the pprint is supposedly happening since as far as I can tell it is not happening on the CLJS side.

Symptom: When I invoke a REPL function that returns a Clojure map it gets returned all on one-line.

{:northstar.model.common/id #uuid "d1dcee36-6497-497d-af69-1c519c2bb5d1", :northstar.model.common/created #inst "2019-08-21T20:13:25.705-00:00", :northstar.model.commands/action "create-todo", :northstar.model.commands/data {:name nil}}

I'm having no luck fixing this myself, but I'll try recap a timeline of events.

Back in January 2019, Piggieback was using do-eval that had a simple (.flush ^Writer *out*). The definition of out was taken from (@session #'*out*) though I don't know how this was populated. [1] old piggieback source

Jan 18: nrepl.nrepl added nrepl.middleware.print including replying-PrintWriter [2] in this diff

Jan 22: Piggieback switched from clojure.tools.nrepl to nrepl.nrepl in [3] this diff.

Feb 5: [4] Piggieback released 0.4.0. This version is the one my Emacs setup currently uses when I run M-x cider-jack-in-cljs

Feb 22: Piggieback adds (defn- output-bindings) using nrepl.nrepl (replying-PrintWriter) [5] in this diff on Feb 22.

The current nrepl.nrepl implementation of replying-PrintWriter is here, but this wasn't actually being used at time of Piggieback 0.4.0.

==================

From above,you would think the breakage was indeed introduced in Piggieback's move from clojure.tools.nrepl to nrepl.nrepl in [3]. However, I dropped CIDER's src back to Piggieback 0.3.3 (May 2018) and there was still no pretty-printing, so I can't prove that this ever worked. (Piggieback 0.4.1 also had no effect.)

The invocation my Emacs runs with M-x cider-jack-in-cljs is:

shadow-cljs - running: lein update-in :dependencies conj [nrepl "0.6.0"] -- update-in :dependencies conj [cider/piggieback "0.4.0"] -- update-in :dependencies conj [cider/cider-nrepl "0.21.1"] -- run -m shadow.cljs.devtools.cli --npm -d nrepl:0.6.0 -d cider/piggieback:0.4.0 -d cider/cider-nrepl:0.21.1 server

@cark in the Slack archive reported that pprinting was working with plain Figwheel -- I'm not sure what it's doing differently, but it's a start.

You can tell shadow-cljs to pretty-print itself via :devtools {:repl-pprint true} in the build config.

I can try adding the print middleware but that doesn't seem to pprint itself? Maybe cider is setting the ::print-fn somewhere to pprint?

I did find this in the CHANGELOG.md for CIDER:

* **(Breaking)** Remove `cider.nrepl.middleware.pprint`. All functionality has been replaced by the built-in printing support in nREPL 0.6.
* Option `cider-repl-scroll-on-output` is now obsolete, and the default REPL behaviour has changed to _not_ recenter the window. The built-in variable `scroll-conservatively` can be set to 101 (either globally or locally in the REPL buffer) to restore the old behaviour. This change has a dramatic positive effect on REPL performance.
* `cider-pprint-fn` and `cider-pprint-options` are now obsolete, replaced by `cider-print-fn` and `cider-print-options`.
* `cider-debug-print-options`, `cider-stacktrace-print-options`, and `cider-repl-pretty-print-width` are now all obsolete, replaced by `cider-print-options`.

There's these snippets in cider-client.el:

(defcustom cider-print-options nil
  "A map of options that will be passed to `cider-print-fn'.
Here's an example for `pprint':
  '((\"length\" 50) (\"right-margin\" 70))"
  :type 'list
  :group 'cider
  :package-version '(cider . "0.21.0"))

(make-obsolete-variable 'cider-pprint-fn 'cider-print-fn "0.21")
(make-obsolete-variable 'cider-pprint-options 'cider-print-options "0.21")

Looking at Figwheel, it seems to have its own pprint implementation. I note this interesting (defn set-repl-pprint), which leads to repl-result-pr-str, which uses util/pprint-to-string.

So it isn't controlled by cider after all? Then just setting the shadow-cljs config should do the trick?

@thheller That works! Got the below nicely formatted EDN at the CIDER REPL. 馃帀

{:northstar.model.common/id
 #uuid "a3a2bb14-b2f5-4cb3-91d8-0537bbf67e24",
 :northstar.model.common/created #inst "2019-08-21T23:39:03.234-00:00",
 :northstar.model.commands/action "create-todo",
 :northstar.model.commands/data {:name "foo"}}

In case anyone else views this thread, you should set the following path in shadow-cljs.edn (assuming your build is named app):

[:builds :app :devtools :repl-pprint] true

I updated the page at https://github.com/thheller/shadow-cljs/wiki/Cider to document this detail -- thanks @thheller and I believe this can now be closed.

Also added it to the docs. I always presumed that cider expected to do something on its side since it does for CLJ.

works here as well, thanks !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nikolap picture nikolap  路  3Comments

jiyinyiyong picture jiyinyiyong  路  6Comments

darwin picture darwin  路  6Comments

endenwer picture endenwer  路  3Comments

jiyinyiyong picture jiyinyiyong  路  8Comments