Skip to content

Commit

Permalink
0.2.7, fixes clojure-emacs/cider-nrepl#643, node repl support
Browse files Browse the repository at this point in the history
- nodejs would throw nullpointer exception on first completion due to repl-env
not being initialized
  • Loading branch information
rksm committed Sep 2, 2019
1 parent 99c716d commit 012ca2b
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 18 deletions.
5 changes: 2 additions & 3 deletions Makefile
Expand Up @@ -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 \
Expand All @@ -31,5 +31,4 @@ fig-repl:
clojure -A:fig-repl

nrepl:
clojure -A:dev -R:test

clojure -A:dev -R:test:nrepl
6 changes: 3 additions & 3 deletions README.md
Expand Up @@ -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"]}}
Expand All @@ -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`

Expand All @@ -69,7 +69,7 @@ installation steps are required.
<!-- For usage with `cider-jack-in-cljs` add these two lines to your emacs config: -->

<!-- ```lisp -->
<!-- (cider-add-to-alist 'cider-jack-in-cljs-dependencies "org.rksm/suitable" "0.2.6") -->
<!-- (cider-add-to-alist 'cider-jack-in-cljs-dependencies "org.rksm/suitable" "0.2.7") -->
<!-- (add-to-list 'cider-jack-in-cljs-nrepl-middlewares "suitable.middleware/wrap-complete") -->
<!-- ``` -->

Expand Down
6 changes: 4 additions & 2 deletions deps.edn
Expand Up @@ -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"}
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.rksm</groupId>
<artifactId>suitable</artifactId>
<version>0.2.6</version>
<version>0.2.7</version>
<name>suitable</name>
<description>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.</description>
<url>http://github.com/rksm/clj-suitable</url>
Expand Down
43 changes: 34 additions & 9 deletions src/main/suitable/complete_for_nrepl.clj
Expand Up @@ -18,6 +18,8 @@

;; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

(def debug? false)

(defonce ^{:private true} resolved-vars (atom nil))

(defn- resolve-vars!
Expand Down Expand Up @@ -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)})]
Expand Down Expand Up @@ -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
Expand All @@ -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 "<suitable>" 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
Expand All @@ -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 "<suitable>" 1 (format "goog.require(\"%s\"); console.log(\"suitable loaded\"); "
munged-js-introspection-js-name))
(cljs-evaluate-fn renv "<suitable>" 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.
Expand Down Expand Up @@ -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))

Expand All @@ -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]
Expand Down

0 comments on commit 012ca2b

Please sign in to comment.