Skip to content

Instantly share code, notes, and snippets.

@bhb
Last active May 15, 2023 01:28
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save bhb/2686b023d074ac052dbc21f12f324f18 to your computer and use it in GitHub Desktop.
Save bhb/2686b023d074ac052dbc21f12f324f18 to your computer and use it in GitHub Desktop.
Clojure friendly mode, inspired by https://github.com/slipset/friendly

Friendly

A beginner-friendly REPL that combines

Usage

JVM 8:

clojure -Sdeps '{:deps {friendly {:git/url "https://gist.github.com/bhb/2686b023d074ac052dbc21f12f324f18" :sha "d532662414376900c13bed9c920181651e1efeff"}}}' -X friendly/run

JVM 9 or newer:

clojure -Sdeps '{:deps {friendly {:git/url "https://gist.github.com/bhb/2686b023d074ac052dbc21f12f324f18" :sha "d532662414376900c13bed9c920181651e1efeff"}}}' -X friendly/run

Credits

Inspired by https://github.com/slipset/friendly

I learned the technique of loading code via a gist from https://gist.github.com/athos/b68b15b08efedffaf14d8c020b125202

{:paths ["."]
:deps {com.bhauman/rebel-readline {:mvn/version "0.1.4"}
expound/expound {:mvn/version "0.9.0"}
org.clojure/core.specs.alpha {:mvn/version "0.2.62"}
speculative/speculative {:git/url "https://github.com/borkdude/speculative.git"
:sha "4e773794a4065a84bdadd997516e52c76ab51b1f"}}}
(ns friendly
(:require [rebel-readline.clojure.main]
[expound.alpha :as expound]
[clojure.spec.alpha :as s]
[clojure.stacktrace]
[clojure.main]
;; for specs
[speculative.instrument :as speculative]))
(expound/defmsg :speculative.specs/ifn "should be a function (or a value that can be *treated* like a function e.g. a set or keyword)")
(def printer (expound/custom-printer {:print-specs? false
:show-valid-values? true
:theme :figwheel-theme}))
(defn repl-caught [e]
(let [ex (clojure.main/repl-exception e)
tr (.getStackTrace ex)
el (when-not (zero? (count tr)) (aget tr 0))
ex-m (Throwable->map ex)]
(binding [*out* *err*]
(cond
;; If the output is a clojure spec issue...
(::s/problems (:data ex-m))
;; print expound output
(do
(println (str (re-find #"Call to .* did not conform to spec\:" (.getMessage ex))
"\n"
(with-out-str (printer (:data ex-m))))))
(instance? clojure.lang.LispReader$ReaderException e)
(println (:cause (Throwable->map e)))
:else
;; otherwise print exception
(println (str (if (instance? clojure.lang.Compiler$CompilerException ex)
(str
(-> ex class .getSimpleName)
" " (.getMessage ex) " ")
(str " " (if el
(clojure.stacktrace/print-stack-trace ex)
"[trace missing]")))))))))
(speculative/instrument)
(set! s/*explain-out* printer)
(defn run [_opts]
(rebel-readline.clojure.main/repl :caught repl-caught))
@andnils
Copy link

andnils commented Jul 10, 2018

This should work:
clj -J--add-modules=java.xml.bind -Sdeps '{:deps {friendly {:git/url "https://gist.github.com/bhb/2686b023d074ac052dbc21f12f324f18" :sha "418bf66fd96851cc55398b55d5a8aff65692f565"}}}' -m friendly

@bhb
Copy link
Author

bhb commented Sep 7, 2018

Thanks @andnils for the fix!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment