Open elzibubble opened 6 years ago
As rebel readline is a readline library to build excellent repls with. That said pprinting results has been on my mind. The best default formatting for results is provided by fipp and I'm thinking that this would provide an optimal solution for printing in general as it solves the wrapping problem quite well.
I took a stab at this today. This was a little more boilerplate than expected, but actually didn't turn out so bad.
(defn syntax-highlight-pprint
"Print a syntax highlighted clojure value.
This printer respects the current color settings set in the
service.
The `rebel-readline.jline-api/*line-reader*` and
`rebel-readline.jline-api/*service*` dynamic vars have to be set for
this to work."
[x]
(binding [*out* (.. api/*line-reader* getTerminal writer)]
(try
(print (api/->ansi (clj-line-reader/highlight-clj-str (with-out-str (pp/pprint x)))))
(catch java.lang.StackOverflowError e
(pp/pprint x)))))
Most of that is copy-paste from rebel itself, all I have really done is change prn-str
to (with-out-str (pp/pprint x))
. This does make me wonder whether this should be a Rebel default. Is there any reason it isn't already?
seems like replacing pr-str
with a dynamic var here: https://github.com/bhauman/rebel-readline/blob/master/rebel-readline/src/rebel_readline/clojure/main.clj#L24 might do the trick. Consumers could bind the var as needed
More specifically, given some startup namespace (ran via :main-opts ["-i" "dev/some_repl.clj"]
) in dev/some_repl.clj
:
(ns some-repl
(:require
[clojure.repl :refer :all]
[clojure.pprint :as pp]
[rebel-readline.main]
[rebel-readline.clojure.main] ; so we can implement pretty-printed results
[datomic.tools.ops :as dt])
;; Requires copied from the `rebel-readline.clojure.main` NS, so Cursive can resolve symbols
(:require
[rebel-readline.core :as core]
[rebel-readline.clojure.line-reader :as clj-line-reader]
[rebel-readline.jline-api :as api]
[rebel-readline.tools :as tools]
[rebel-readline.clojure.service.local :as clj-service]
[clojure.main]))
(in-ns 'rebel-readline.clojure.main)
(require '[clojure.pprint :as pp])
(defn syntax-highlight-prn
"Print a syntax highlighted clojure value.
This printer respects the current color settings set in the
service.
The `rebel-readline.jline-api/*line-reader*` and
`rebel-readline.jline-api/*service*` dynamic vars have to be set for
this to work.
See `rebel-readline.main` for an example of how this function is normally used"
[x]
(binding [*out* (.. api/*line-reader* getTerminal writer)]
(try
(println (api/->ansi (clj-line-reader/highlight-clj-str
(with-out-str (pp/pprint x)))))
(catch java.lang.StackOverflowError e
(println (pr-str x))))))
(in-ns 'some-repl) ;; switch back to the namespace of this file
(rebel-readline.main/-main)
I like the syntax colouring rebel does on results, but I also sometimes would like a pretty-printed output. Maybe if the command ends with a "|" you could pprint the results? Or offer your own pprint that includes syntax highlighting? Or a chord like
<alt-enter>
submits and pprints.