diff --git a/CHANGELOG.md b/CHANGELOG.md index 70a4ae0ae..d960bfc19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## master (unreleased) +### New features + +* [#605](https://github.com/clojure-emacs/cider-nrepl/pull/605): Added a option for filtering vars to the ns-vars middleware. + +### Bugs fixed + +* [#605](https://github.com/clojure-emacs/cider-nrepl/pull/605): Fix `ns-vars-with-meta` to return public vars. + ## 0.21.1 (2019-02-15) ### New features diff --git a/src/cider/nrepl.clj b/src/cider/nrepl.clj index dcafe752b..87c8f17be 100644 --- a/src/cider/nrepl.clj +++ b/src/cider/nrepl.clj @@ -266,13 +266,15 @@ :requires {"name" "The name to use."} :returns {"status" "done" "var-list" "The list obtained."}} "ns-vars" - {:doc "Returns a sorted list of all vars in a namespace." + {:doc "Returns a sorted list of publicvars in a namespace." :requires {"ns" "The namespace to browse."} - :returns {"status" "done" "ns-vars" "The sorted list of all vars in a namespace."}} + :optional {"var-query" "The search query for vars. Only \"private?\" is supported for ClojureScript."} + :returns {"status" "done" "ns-vars" "The sorted list of public vars in a namespace."}} "ns-vars-with-meta" - {:doc "Returns a map of [var-name] to [var-metadata] for all vars in a namespace." + {:doc "Returns a map of [var-name] to [var-metadata] for public vars in a namespace." :requires {"ns" "The namespace to use."} - :returns {"status" "done" "ns-vars-with-meta" "The map of [var-name] to [var-metadata] for all vars in a namespace."}} + :optional {"var-query" "The search query for vars. Only \"private?\" is supported for ClojureScript."} + :returns {"status" "done" "ns-vars-with-meta" "The map of [var-name] to [var-metadata] for public vars in a namespace."}} "ns-path" {:doc "Returns the path to the file containing ns." :requires {"ns" "The namespace to find."} diff --git a/src/cider/nrepl/middleware/ns.clj b/src/cider/nrepl/middleware/ns.clj index f4669c8c1..79dba1aa8 100644 --- a/src/cider/nrepl/middleware/ns.clj +++ b/src/cider/nrepl/middleware/ns.clj @@ -2,12 +2,14 @@ (:refer-clojure :exclude [ns-aliases]) (:require [cider.nrepl.middleware.util.cljs :as cljs] + [cider.nrepl.middleware.util.coerce :as util.coerce] [cider.nrepl.middleware.util.error-handling :refer [with-safe-transport]] [cider.nrepl.middleware.util.meta :as um] [cljs-tooling.info :as cljs-info] [cljs-tooling.util.analysis :as cljs-analysis] [orchard.misc :as u] - [orchard.namespace :as ns])) + [orchard.namespace :as ns] + [orchard.query :as query])) (defn ns-list-vars-by-name "Return a list of vars named `name` amongst all namespaces. @@ -17,18 +19,21 @@ (filter #(= (first %) name)) (map second))) -(defn ns-vars-clj [ns] - (->> (symbol ns) - ns-publics - keys - (map name) +(defn ns-vars-clj [ns & [var-query]] + (->> {:ns-query {:exactly [ns]}} + (merge var-query) + util.coerce/var-query + query/vars + (map (comp str :name meta)) sort)) -(defn ns-vars-with-meta-clj [ns] - (->> (symbol ns) - ns-interns - (u/update-vals (comp um/relevant-meta meta)) - (u/update-keys name) +(defn ns-vars-with-meta-clj [ns & [var-query]] + (->> {:ns-query {:exactly [ns]}} + (merge var-query) + util.coerce/var-query + query/vars + (map meta) + (map (juxt (comp str :name) um/relevant-meta)) (into (sorted-map)))) (defn ns-list-cljs [env] @@ -37,19 +42,25 @@ (map name) sort)) -(defn ns-vars-cljs [env ns] - (->> (symbol ns) - (cljs-analysis/public-vars env) - keys - (map name) - sort)) - -(defn ns-vars-with-meta-cljs [env ns] - (->> (symbol ns) - (cljs-analysis/public-vars env) - (u/update-vals (comp um/relevant-meta :meta)) - (u/update-keys name) - (into (sorted-map)))) +(defn ns-vars-cljs [env ns & [var-query]] + (let [fetch-vars (if (:private? var-query) + (partial cljs-analysis/ns-interns-from-env env) + (partial cljs-analysis/public-vars env))] + (->> (symbol ns) + fetch-vars + keys + (map name) + sort))) + +(defn ns-vars-with-meta-cljs [env ns & [var-query]] + (let [fetch-vars (if (:private? var-query) + (partial cljs-analysis/ns-interns-from-env env) + (partial cljs-analysis/public-vars env))] + (->> (symbol ns) + fetch-vars + (u/update-vals (comp um/relevant-meta :meta)) + (u/update-keys name) + (into (sorted-map))))) (defn ns-path-cljs [env ns] (->> (symbol ns) @@ -61,15 +72,15 @@ (ns-list-cljs cljs-env) (ns/loaded-namespaces filter-regexps))) -(defn ns-vars [{:keys [ns] :as msg}] +(defn ns-vars [{:keys [ns var-query] :as msg}] (if-let [cljs-env (cljs/grab-cljs-env msg)] - (ns-vars-cljs cljs-env ns) - (ns-vars-clj ns))) + (ns-vars-cljs cljs-env ns var-query) + (ns-vars-clj ns var-query))) -(defn ns-vars-with-meta [{:keys [ns] :as msg}] +(defn ns-vars-with-meta [{:keys [ns var-query] :as msg}] (if-let [cljs-env (cljs/grab-cljs-env msg)] - (ns-vars-with-meta-cljs cljs-env ns) - (ns-vars-with-meta-clj ns))) + (ns-vars-with-meta-cljs cljs-env ns var-query) + (ns-vars-with-meta-clj ns var-query))) (defn ns-path [{:keys [ns] :as msg}] (if-let [cljs-env (cljs/grab-cljs-env msg)] diff --git a/test/clj/cider/nrepl/middleware/ns_test.clj b/test/clj/cider/nrepl/middleware/ns_test.clj index 9eb168cd1..40d96e60e 100644 --- a/test/clj/cider/nrepl/middleware/ns_test.clj +++ b/test/clj/cider/nrepl/middleware/ns_test.clj @@ -47,6 +47,22 @@ (is (sequential? ns-vars)) (is (every? string? ns-vars)))) +(deftest ns-vars-including-privates-test + (testing "Without private vars" + (let [ns-vars (:ns-vars (session/message {:op "ns-vars" + :ns "clojure.core"}))] + (is (sequential? ns-vars)) + (is (every? string? ns-vars)) + (is (nil? (some #(= "is-annotation?" %) ns-vars))))) + + (testing "Including private vars" + (let [ns-vars (:ns-vars (session/message {:op "ns-vars" + :ns "clojure.core" + :var-query {:private? 1}}))] + (is (sequential? ns-vars)) + (is (every? string? ns-vars)) + (is (some #(= "is-annotation?" %) ns-vars))))) + (deftest ns-vars-with-meta-integration-test (let [ns-vars-with-meta (:ns-vars-with-meta (session/message {:op "ns-vars-with-meta" @@ -62,6 +78,23 @@ (is (= (:*ns* ns-vars-with-meta) {:doc "\"A clojure.lang.Namespace object representing the current namespace.\""})))) +(deftest ns-vars-with-meta-including-privates-test + (testing "Without private vars" + (let [ns-vars-with-meta (:ns-vars-with-meta + (session/message {:op "ns-vars-with-meta" + :ns "clojure.core"}))] + (is (every? (comp map? second) ns-vars-with-meta)) + (is (nil? (:is-annotation? ns-vars-with-meta))))) + + (testing "Including private vars" + (let [ns-vars-with-meta (:ns-vars-with-meta + (session/message {:op "ns-vars-with-meta" + :ns "clojure.core" + :var-query {:private? 1}}))] + (is (every? (comp map? second) ns-vars-with-meta)) + (is (= (:is-annotation? ns-vars-with-meta) + {:arglists "([c])"}))))) + (deftest ns-path-integration-test (let [ns-path (:path (session/message {:op "ns-path" :ns "cider.nrepl.middleware.ns"})) diff --git a/test/cljs/cider/nrepl/middleware/cljs_ns_test.clj b/test/cljs/cider/nrepl/middleware/cljs_ns_test.clj index 04a100425..2d8d5408a 100644 --- a/test/cljs/cider/nrepl/middleware/cljs_ns_test.clj +++ b/test/cljs/cider/nrepl/middleware/cljs_ns_test.clj @@ -16,7 +16,16 @@ (let [{:keys [ns-vars]} (session/message {:op "ns-vars" :ns "cljs.core"})] (is (sequential? ns-vars)) - (is (every? string? ns-vars)))) + (is (every? string? ns-vars)) + (is (not (contains? (set ns-vars) "maybe-warn"))))) + + (testing "ns-vars op with private? var-query" + (let [{:keys [ns-vars]} (session/message {:op "ns-vars" + :ns "cljs.core" + :var-query {:private? 1}})] + (is (sequential? ns-vars)) + (is (every? string? ns-vars)) + (is (contains? (set ns-vars) "maybe-warn")))) (testing "ns-vars-with-meta op" (let [ns-vars-with-meta (:ns-vars-with-meta @@ -25,7 +34,17 @@ (is (every? (comp map? second) ns-vars-with-meta)) (is (= (:+ ns-vars-with-meta) {:arglists "(quote ([] [x] [x y] [x y & more]))" - :doc "\"Returns the sum of nums. (+) returns 0.\""})))) + :doc "\"Returns the sum of nums. (+) returns 0.\""})) + (is (not (contains? ns-vars-with-meta :maybe-warn))))) + + (testing "ns-vars-with-meta op with private? var-query" + (let [ns-vars-with-meta (:ns-vars-with-meta + (session/message {:op "ns-vars-with-meta" + :ns "cljs.core" + :var-query {:private? 1}}))] + (is (every? (comp map? second) ns-vars-with-meta)) + (is (= (:maybe-warn ns-vars-with-meta) + {:arglists "(quote ([e]))"})))) (testing "ns-path op" (let [{:keys [path]} (session/message {:op "ns-path"