From 012ca2b5f3e0d14476307c31cd8b00c519e6047d Mon Sep 17 00:00:00 2001 From: Robert Krahn Date: Sun, 1 Sep 2019 19:11:43 +0200 Subject: [PATCH] 0.2.7, fixes clojure-emacs/cider-nrepl#643, node repl support - nodejs would throw nullpointer exception on first completion due to repl-env not being initialized --- Makefile | 5 ++- README.md | 6 ++-- deps.edn | 6 ++-- pom.xml | 2 +- src/main/suitable/complete_for_nrepl.clj | 43 +++++++++++++++++++----- 5 files changed, 44 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 245b66e..3d88583 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ clean: rm -rf target/public/cljs-out suitable.jar .cpcache test: - clojure -Atest -d src/test + clojure -A:test -d src/test suitable.jar: deps.edn src/**/* clojure -A:pack \ @@ -31,5 +31,4 @@ fig-repl: clojure -A:fig-repl nrepl: - clojure -A:dev -R:test - + clojure -A:dev -R:test:nrepl diff --git a/README.md b/README.md index 3a57323..d67c6f6 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Then modify your `deps.edn` so that org.rksm/suitable and it's setup code are included: ```clojure -:aliases {:suitable {:extra-deps {org.rksm/suitable {:mvn/version "0.2.6"}} +:aliases {:suitable {:extra-deps {org.rksm/suitable {:mvn/version "0.2.7"}} :main-opts ["-e" "(require,'suitable.hijack-rebel-readline-complete)" "-m" "figwheel.main" "--build" "dev" "--repl"]}} @@ -57,7 +57,7 @@ Finally start a figwheel repl via `clj -A:suitable`. First make sure that the [normal leiningen setup](https://figwheel.org/#setting-up-a-build-with-leiningen) works. -Add `[org.rksm/suitable "0.2.6"]` to your dependencies vector. +Add `[org.rksm/suitable "0.2.7"]` to your dependencies vector. Then you can start a repl with `lein trampoline run -m suitable.figwheel.main -- -b dev -r` @@ -69,7 +69,7 @@ installation steps are required. - + diff --git a/deps.edn b/deps.edn index 152ed86..ae0f545 100644 --- a/deps.edn +++ b/deps.edn @@ -2,7 +2,7 @@ :paths ["src/main"] - :aliases { ;; for starting nrepl clj & cljs servers for live development + :aliases {;; for starting nrepl clj & cljs servers for live development :dev {:extra-paths ["src/dev" "resources" "target"] :extra-deps {cider/piggieback {:mvn/version "RELEASE"} com.bhauman/figwheel-main {:mvn/version "RELEASE"} @@ -23,7 +23,9 @@ ;; tests :test {:extra-paths ["src/test"] :extra-deps {com.cognitect/test-runner {:git/url "https://github.com/cognitect-labs/test-runner.git" - :sha "209b64504cb3bd3b99ecfec7937b358a879f55c1"}} + :sha "209b64504cb3bd3b99ecfec7937b358a879f55c1"} + cider/cider-nrepl {:mvn/version "RELEASE"} + cider/piggieback {:mvn/version "RELEASE"}} :main-opts ["-m" "cognitect.test-runner"]} ;; build a jar, https://juxt.pro/blog/posts/pack-maven.html diff --git a/pom.xml b/pom.xml index f9e9b9f..c9a591a 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.rksm suitable - 0.2.6 + 0.2.7 suitable An addon for Figwheel and Emacs Cider to aid live exploratory development. Queries objects in ClojureScript for their properties to use as part of nREPL completion handlers. http://github.com/rksm/clj-suitable diff --git a/src/main/suitable/complete_for_nrepl.clj b/src/main/suitable/complete_for_nrepl.clj index a901645..8d45753 100644 --- a/src/main/suitable/complete_for_nrepl.clj +++ b/src/main/suitable/complete_for_nrepl.clj @@ -18,6 +18,8 @@ ;; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(def debug? false) + (defonce ^{:private true} resolved-vars (atom nil)) (defn- resolve-vars! @@ -45,6 +47,7 @@ (require 'cljs.env) {:cljs-cenv-var (resolve 'cljs.env/*compiler*) :cljs-ns-var (resolve 'cljs.analyzer/*cljs-ns*) + :cljs-repl-setup-fn (resolve 'cljs.repl/setup) :cljs-evaluate-fn (resolve 'cljs.repl/evaluate) :cljs-eval-cljs-fn (resolve 'cljs.repl/eval-cljs) :cljs-load-namespace-fn (resolve 'cljs.repl/load-namespace)})] @@ -81,7 +84,6 @@ `(~sym ((keyword '~sym) ~vars))))) ~@body))))) - (defn- cljs-eval "Grabs the necessary compiler and repl envs from the message and uses the plain cljs.repl interface for evaluation. Returns a map with :value and :error. Note @@ -101,16 +103,40 @@ {:value result}) (catch Exception e {:error e}))))) +(defn node-env? + "Returns true iff RENV is a NodeEnv or more precisely a piggiebacked delegating + NodeEnv. Since the renv is wrapped we can't just compare the type but have to + do some string munging according to + `cider.piggieback/generate-delegating-repl-env`." + [renv] + (= (some-> 'cljs.repl.node.NodeEnv + resolve + .getName + (string/replace "." "_")) + (-> renv + class + .getName + (string/replace #".*Delegating" "")))) + (defn ensure-suitable-cljs-is-loaded [session] (let [{:keys [cenv renv opts]} (extract-cljs-state session)] (with-cljs-env cenv 'cljs.user - [cljs-load-namespace-fn cljs-evaluate-fn] - (when (not= "true" (:value (cljs-evaluate-fn + [cljs-repl-setup-fn cljs-load-namespace-fn cljs-evaluate-fn] + + (when (node-env? renv) + ;; rk 2019-09-02 FIXME + ;; Due to this issue: + ;; https://github.com/clojure-emacs/cider-nrepl/pull/644#issuecomment-526953982 + ;; we can't just eval with a node env but have to make sure that it's + ;; local buffer is initialized for this thread. + (cljs-repl-setup-fn renv opts)) + + (when (not= "true" (some-> (cljs-evaluate-fn renv "" 1 ;; see above, would be suitable.js_introspection - (format "!!goog.getObjectByName('%s')" munged-js-introspection-js-name)))) - ;; see above, would be suitable.js-introspection + (format "!!goog.getObjectByName('%s')" munged-js-introspection-js-name)) :value)) (try + ;; see above, would be suitable.js-introspection (cljs-load-namespace-fn renv (read-string munged-js-introspection-ns) opts) (catch Exception e ;; when run with mranderson, cljs does not seem to handle the ns @@ -119,8 +145,9 @@ (when-not (and (string/includes? munged-js-introspection-ns "inlined-deps") (string/includes? (string/lower-case (str e)) "does not provide a namespace")) (throw e)))) - (cljs-evaluate-fn renv "" 1 (format "goog.require(\"%s\"); console.log(\"suitable loaded\"); " - munged-js-introspection-js-name)) + (cljs-evaluate-fn renv "" 1 (format "goog.require(\"%s\");%s" + (if debug? " console.log(\"suitable loaded\");" "") + munged-js-introspection-js-name)) ;; wait as depending on the implemention of goog.require provide by the ;; cljs repl might be async. See ;; https://github.com/rksm/clj-suitable/issues/1 for more details. @@ -168,7 +195,6 @@ ensure-loaded-fn ensure-suitable-cljs-is-loaded] (handle-completion-msg! msg cljs-eval-fn ensure-loaded-fn))) - (defn- shadow-cljs? [msg] (:shadow.cljs.devtools.server.nrepl-impl/build-id msg)) @@ -192,7 +218,6 @@ ensure-loaded-fn (fn [_session] (cljs-eval-fn 'cljs.user (str "(require '" munged-js-introspection-ns ")")))] (handle-completion-msg! msg cljs-eval-fn ensure-loaded-fn))) - (defn complete-for-nrepl "Computes the completions using the cljs environment found in msg." [msg]