~severeoverfl0w/wedge-mise

11a944988e4888f5ea94f387a863c3900044b199 — Dominic Monroe 3 years ago 4bbaa31
Add initial version
A .gitignore => .gitignore +2 -0
@@ 0,0 1,2 @@
.cpcache
.rebel_readline_history

A README.adoc => README.adoc +45 -0
@@ 0,0 1,45 @@
= Mise

A development environment for beginners to Clojure.
Dynamically loads functionality on the fly using tools.deps.alpha, so keeps it's dependency list very light.
Suitable for loading during development for beginners and experienced alike.

== Rationale

Getting started with Clojure can be overwhelming.
Over time, developers tend to craft themselves a "mise" of utilities to aid their development in Clojure.
By providing a mise to beginners, they have a starting point for developing their own mise later.

Additionally Mise should not interrupt experienced Clojure developers, so they will bring Mise into their projects regardless creating a jumping-off point for beginners to join their projects.

== Starting

=== Already started a REPL

[source]
----
=> (load "mise")
----

Usage information will be printed for you!

=== Don't have a REPL

Start a REPL from your terminal by typing:

// [source,shell]
// ----
// # clojure -M:wedge rebel
// ----
// 
// Or if you aren't using wedge

[source,shell]
----
# clojure -M -m io.dominic.wedge.mise.rebel
----

== SLF4J Warnings

This should only happen if you don't have SLF4J loaded.
You can just add `org.slf4j/slf4j-nop {:mvn/version "1.7.30"}` during dev if you aren't using SLF4J.

A deps.edn => deps.edn +4 -0
@@ 0,0 1,4 @@
{:paths ["src"]
 :deps
 {org.clojure/tools.deps.alpha {:git/url "https://github.com/clojure/tools.deps.alpha.git"
                                :sha "d77476f3d5f624249462e275ae62d26da89f320b"}}}

A src/io/dominic/wedge/mise.clj => src/io/dominic/wedge/mise.clj +51 -0
@@ 0,0 1,51 @@
(ns io.dominic.wedge.mise
  (:require
    [clojure.tools.deps.alpha.repl :as tda.repl]))

(defn load-libs
  []
  (binding [;; Suppress missing S3Transport warning
            *err* (java.io.StringWriter.)]
    (tda.repl/add-libs
      '{com.gfredericks/dot-slash-2 {:mvn/version "0.1.5"}
        vvvvalvalval/scope-capture {:mvn/version "0.3.2"}
        hashp {:mvn/version "0.2.0"}
        riverford/datagrep {:mvn/version "0.1.0"}}))
  :loaded)

(defn setup
  []
  (set! *data-readers* (#'clojure.core/load-data-readers))
  (require 'hashp.core)

  ((requiring-resolve 'com.gfredericks.dot-slash-2/!)
   '{. [clojure.repl/doc
        clojure.repl/source
        clojure.repl/apropos
        clojure.repl/pst
        clojure.repl/dir
        clojure.test/run-tests
        io.dominic.wedge.dev/reset
        sc.api/spy
        sc.api/letsc
        sc.api/defsc
        sc.repl/ep-repl
        sc.api/ep-info
        sc.api/cs-info
        sc.api/brk
        sc.api/undefsc
        riverford.datagrep.core/grep
        riverford.datagrep.core/vargrep]}))

(defn print-usage
  []
  (println
"    Use `#p` to spy on values.  Learn more at https://github.com/weavejester/hashp

    Mise utilities are available in any namespace.  Here's some examples to get
    you started:
    => (./doc +)\t\tShow docs for a function.
    => (./dir clojure.repl)\tList functions in a namespace.
    => (./dir .)\t\tGet full list of functions in `.`.
    => (./reset)\t\tReset from any namespace.
    => #p {:a 10}\t\tSpy on a value (useful inside functions!)"))

A src/io/dominic/wedge/mise/rebel.clj => src/io/dominic/wedge/mise/rebel.clj +23 -0
@@ 0,0 1,23 @@
(ns io.dominic.wedge.mise.rebel
  (:require
    [clojure.tools.deps.alpha.repl :as tda.repl]
    [io.dominic.wedge.mise :as mise]))

(defn- add-libs
  []
  (binding [;; Suppress missing S3Transport warning
            *err* (java.io.StringWriter.)]
    (tda.repl/add-libs
      '{com.bhauman/rebel-readline {:mvn/version "0.1.4"}
        mvxcvi/puget {:mvn/version "1.3.1"}}))
  :loaded)

(defn -main
  [& args]
  (let [cl (.getContextClassLoader (Thread/currentThread))]
    (.setContextClassLoader (Thread/currentThread) (clojure.lang.DynamicClassLoader. cl)))
  (mise/load-libs)
  (mise/setup)
  (add-libs)
  (load "io/dominic/wedge/mise/rebel/impl")
  ((resolve 'main*)))

A src/io/dominic/wedge/mise/rebel/impl.clj => src/io/dominic/wedge/mise/rebel/impl.clj +49 -0
@@ 0,0 1,49 @@
(require
  '[fipp.edn :as fipp]
  '[io.dominic.wedge.mise :as mise]
  'rebel-readline.clojure.main
  'rebel-readline.core
  '[rebel-readline.jline-api :as api]
  '[rebel-readline.clojure.line-reader :as clj-line-reader])

(defn syntax-highlight-fipp
  "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 (fipp/pprint x)))))
      (catch java.lang.StackOverflowError _
        (try
          (fipp/pprint x)
          ;; Just in case of
          ;; https://github.com/brandonbloom/fipp/issues/28
          (catch java.lang.StackOverflowError _
            (prn x)))))))

(defn- main*
  []
  (alter-var-root #'clj-line-reader/default-config
                  update-in
                  [:key-bindings :emacs]
                  (fnil conj [])
                  ;; These are the enter key, and forces acceptance.  This is
                  ;; easier for beginners, can be overriden in user-config.
                  [(org.jline.keymap.KeyMap/translate "^M") :clojure-force-accept-line]
                  [(org.jline.keymap.KeyMap/translate "^J") :clojure-force-accept-line])
  (rebel-readline.core/ensure-terminal
    (rebel-readline.clojure.main/repl
      :init (fn []
              (mise/print-usage)
              (println "\n    For Rebel help type :repl/help\n    To change colour theme use :repl/set-color-theme :light-screen-theme"))
      :print syntax-highlight-fipp)
    ;; When the REPL stops, stop:
    (System/exit 0)))

A src/mise.clj => src/mise.clj +6 -0
@@ 0,0 1,6 @@
(do
  (require 'io.dominic.wedge.mise)
  (io.dominic.wedge.mise/load-libs)
  (io.dominic.wedge.mise/setup)
  (io.dominic.wedge.mise/print-usage)
  :done)