Skip to content

Instantly share code, notes, and snippets.

@pmonks
Forked from johan-carlsson/README.md
Last active October 12, 2022 22:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmonks/6bc2a37fd3f159b46fa3b2ad77f07204 to your computer and use it in GitHub Desktop.
Save pmonks/6bc2a37fd3f159b46fa3b2ad77f07204 to your computer and use it in GitHub Desktop.
Clojure friendly mode with nrepl starting on port 7888, inspired by https://github.com/slipset/friendly

Friendly

A beginner-friendly REPL that combines:

Usage

clojure -Sdeps '{:deps {pmonks/friendly {:git/url "https://gist.github.com/pmonks/6bc2a37fd3f159b46fa3b2ad77f07204" :sha "daae6e8ddf18496431cf22af0b267813bf9e7826"}}}' -m friendly

Differences from parent fork

  • Updates out of date dependencies
  • Requires Java 11+ (earlier forks don't work on Java 11+)
  • Adds socket-based REPL (port 5555)

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 {org.clojure/clojure {:mvn/version "1.11.1"}
com.bhauman/rebel-readline {:mvn/version "0.1.4"}
venantius/pyro {:mvn/version "0.1.2"}
expound/expound {:mvn/version "0.9.0"}
nrepl/nrepl {:mvn/version "1.0.0"}
javax.xml.bind/jaxb-api {:mvn/version "2.4.0-b180830.0359"}
org.glassfish.jaxb/jaxb-runtime {:mvn/version "4.0.1"}}}
(ns friendly
(:require [pyro.printer :as pyro]
[rebel-readline.clojure.main]
[expound.alpha :as expound]
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as st]
[clojure.stacktrace]
[clojure.core.server :as srv]
[nrepl.server :as n]
[clojure.main]))
(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]")))))))))
(defn -main []
(set! s/*explain-out* printer)
(st/instrument)
(pyro/swap-stacktrace-engine!)
(defonce socket-server (srv/start-server {:name "Clojure Socket REPL" :port 5555 :accept clojure.core.server/repl}))
(defonce nrepl-server (n/start-server :port 7888))
(rebel-readline.clojure.main/repl :caught repl-caught))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment