bhauman / rebel-readline

Terminal readline library for Clojure dialects
Eclipse Public License 1.0
680 stars 37 forks source link

Option to pprint results #151

Open elzibubble opened 6 years ago

elzibubble commented 6 years ago

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.

bhauman commented 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.

SevereOverfl0w commented 5 years ago

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?

bhurlow commented 4 years ago

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

onetom commented 3 years ago

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)