diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ae0bf209..cad769083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * [#605](https://github.com/clojure-emacs/cider-nrepl/pull/605): Added a option for filtering vars to the ns-vars middleware. * Added `xref` middleware providing `fn-deps` and `fn-refs` ops. * [#628](https://github.com/clojure-emacs/cider-nrepl/pull/628): Added `clojuredocs` middleware providing `clojuredocs-lookup` and `clojuredocs-refresh-cache` ops. +* [#633](https://github.com/clojure-emacs/cider-nrepl/pull/633) Added runtime code completion for ClojureScript via [suitable](https://github.com/rksm/clj-suitable). ### Bugs fixed diff --git a/README.md b/README.md index 9368b25c4..6a0b06e83 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,7 @@ Let's also acknowledge some of the projects leveraged by cider-nrepl: * [orchard][] - extracted from `cider-nrepl`, so that non-nREPL clients can leverage the generic tooling functionality (like `inspect`, `apropos`, `var-info`, etc * [compliment][] - for Clojure code completion * [cljs-tooling][] - for ClojureScript code completion +* [suitable][] - for ClojureScript code completion using runtime inspection * [tools.trace][] - for tracing * [tools.namespace][] - for namespace reloading * [cljfmt][] - for code formatting @@ -402,6 +403,7 @@ Distributed under the Eclipse Public License, the same as Clojure. [orchard]: https://github.com/clojure-emacs/orchard [compliment]: https://github.com/alexander-yakushev/compliment [cljs-tooling]: https://github.com/clojure-emacs/cljs-tooling +[suitable]: https://github.com/rksm/clj-suitable [tools.trace]: https://github.com/clojure/tools.trace [tools.namespace]: https://github.com/clojure/tools.namespace [cljfmt]: https://github.com/weavejester/cljfmt diff --git a/project.clj b/project.clj index 7e7145bff..75a0bc53e 100644 --- a/project.clj +++ b/project.clj @@ -11,6 +11,7 @@ ^:inline-dep [fipp "0.6.18"] ; can be removed in unresolved-tree mode ^:inline-dep [compliment "0.3.9"] ^:inline-dep [cljs-tooling "0.3.1"] + ^:inline-dep [org.rksm/suitable "0.2.1" :exclusions [org.clojure/clojurescript]] ^:inline-dep [cljfmt "0.6.4" :exclusions [org.clojure/clojurescript]] ^:inline-dep [org.clojure/tools.namespace "0.3.1"] ^:inline-dep [org.clojure/tools.trace "0.7.10"] diff --git a/src/cider/nrepl/middleware/complete.clj b/src/cider/nrepl/middleware/complete.clj index 2a9e73356..f8b58145c 100644 --- a/src/cider/nrepl/middleware/complete.clj +++ b/src/cider/nrepl/middleware/complete.clj @@ -5,7 +5,14 @@ [cljs-tooling.complete :as cljs-complete] [compliment.core :as jvm-complete] [compliment.utils :as jvm-complete-utils] - [orchard.misc :as u])) + [orchard.misc :as u] + [suitable.complete-for-nrepl :as suitable])) + +(defn- cljs-complete + [msg cljs-env ns prefix extra-metadata] + (concat (cljs-complete/completions cljs-env prefix {:context-ns ns + :extra-metadata extra-metadata}) + (suitable/complete-for-nrepl msg))) (defn complete [{:keys [ns symbol context extra-metadata] :as msg}] @@ -13,8 +20,7 @@ prefix (str symbol) extra-metadata (set (map keyword extra-metadata))] (if-let [cljs-env (cljs/grab-cljs-env msg)] - (cljs-complete/completions cljs-env prefix {:context-ns ns - :extra-metadata extra-metadata}) + (cljs-complete msg cljs-env ns prefix extra-metadata) (jvm-complete/completions prefix {:ns ns :context context :extra-metadata extra-metadata})))) diff --git a/test/cljs/cider/nrepl/middleware/cljs_complete_test.clj b/test/cljs/cider/nrepl/middleware/cljs_complete_test.clj index e8fab168f..6e2028b2d 100644 --- a/test/cljs/cider/nrepl/middleware/cljs_complete_test.clj +++ b/test/cljs/cider/nrepl/middleware/cljs_complete_test.clj @@ -40,6 +40,26 @@ (is (= '("[psym & doc+methods]") (:arglists candidate))) (is (string? (:doc candidate)))))) +(deftest cljs-complete-with-suitable-test + (testing "js global completion" + (let [response (session/message {:op "complete" + :ns "cljs.user" + :symbol "js/Ob"}) + candidates (:completions response)] + (is (= [{:candidate "js/Object", :ns "js", :type "function"}] candidates)))) + + (testing "manages context state" + (session/message {:op "complete" + :ns "cljs.user" + :symbol ".xxxx" + :context "(__prefix__ js/Object)"}) + (let [response (session/message {:op "complete" + :ns "cljs.user" + :symbol ".key" + :context ":same"}) + candidates (:completions response)] + (is (= [{:ns "js/Object", :candidate ".keys" :type "function"}] candidates))))) + (deftest cljs-complete-doc-test (let [response (session/message {:op "complete-doc" :symbol "tru"})] (is (= (:status response) #{"done"}))