Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cider's namespaces and vars filtered from ns-list and apropos #347

Merged
merged 2 commits into from
Apr 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions src/cider/nrepl/middleware/apropos.clj
Original file line number Diff line number Diff line change
Expand Up @@ -41,32 +41,34 @@
"Return the list of namespaces to be searched, ordered with `ns` first,
followed by `clojure.*` namespaces, and then all others sorted alphabetically.
If `search-ns` is specified, the returned list will contain only this
namespace."
[ns search-ns]
namespace. `filter-regexps` is used to filter out namespaces matching regexps."
[ns search-ns & [filter-regexps]]
(let [clojure-ns? #(.startsWith (str (ns-name %)) "clojure.")
current-ns (find-ns (symbol (or ns "")))]
(if search-ns
(list (find-ns (symbol search-ns)))
(sort (fn [x y]
(cond (= x current-ns) -1
(= y current-ns) 1
(and (clojure-ns? x) (not (clojure-ns? y))) -1
(and (clojure-ns? y) (not (clojure-ns? x))) 1
:else (compare (str x) (str y))))
(remove ns/inlined-dependency? (all-ns))))))
(->> (all-ns)
(sort (fn [x y]
(cond (= x current-ns) -1
(= y current-ns) 1
(and (clojure-ns? x) (not (clojure-ns? y))) -1
(and (clojure-ns? y) (not (clojure-ns? x))) 1
:else (compare (str x) (str y)))))
(remove ns/inlined-dependency?)
(remove #(ns/internal-namespace? % filter-regexps))))))

(defn find-symbols
"Find symbols or (optionally) docstrings matching `query` in `search-ns` if
specified or all namespaces. The search may optionally include private vars,
and may be case senstive. Types returned correspond to Apropos types.
Docstring search returns the full doc; symbol search returns an abbreviated
version."
[ns query search-ns docs? privates? case-sensitive?]
[ns query search-ns docs? privates? case-sensitive? filter-regexps]
(let [ns-vars (if privates? ns-interns ns-publics)
var-doc* (if docs? var-doc (partial var-doc 1))
search-prop (if docs? var-doc var-name)
regex (-> (if case-sensitive? query (format "(?i:%s)" query)) re-pattern)]
(->> (namespaces ns search-ns)
(->> (namespaces ns search-ns filter-regexps)
(mapcat (comp (partial sort-by var-name) vals ns-vars))
(filter (comp (partial re-find regex) search-prop))
(map (fn [v] {:name (var-name v)
Expand All @@ -80,8 +82,8 @@
(defn handle-apropos
"Return a sequence of vars whose name matches the query pattern, or if
specified, having the pattern in their docstring."
[{:keys [ns query search-ns docs? privates? case-sensitive?] :as msg}]
{:apropos-matches (find-symbols ns query search-ns docs? privates? case-sensitive?)})
[{:keys [ns query search-ns docs? privates? case-sensitive? filter-regexps] :as msg}]
{:apropos-matches (find-symbols ns query search-ns docs? privates? case-sensitive? filter-regexps)})

(defn wrap-apropos
"Middleware that handles apropos requests"
Expand All @@ -96,4 +98,5 @@
{"apropos"
{:doc (:doc (meta #'handle-apropos))
:requires {"query" "The search query."}
:optional {"filter-regexps" "All vars from namespaces matching any regexp from this list would be dropped from the result."}
:returns {"apropos-matches" "A list of matching symbols."}}}})
7 changes: 4 additions & 3 deletions src/cider/nrepl/middleware/ns.clj
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@
(cljs-info/info env)
(:file)))

(defn ns-list [msg]
(defn ns-list [{:keys [filter-regexps] :as msg}]
(if-let [cljs-env (cljs/grab-cljs-env msg)]
(ns-list-cljs cljs-env)
(ns/loaded-namespaces)))
(ns/loaded-namespaces filter-regexps)))

(defn ns-vars [{:keys [ns] :as msg}]
(if-let [cljs-env (cljs/grab-cljs-env msg)]
Expand Down Expand Up @@ -115,7 +115,8 @@
{:handles
{"ns-list"
{:doc "Return a sorted list of all namespaces."
:returns {"status" "done" "ns-list" "The sorted list of all namespaces."}}
:returns {"status" "done" "ns-list" "The sorted list of all namespaces."}
:optional {"filter-regexps" "All namespaces matching any regexp from this list would be dropped from the result."}}
"ns-list-vars-by-name"
{:doc "Return a list of vars named `name` amongst all namespaces."
:requires {"name" "The name to use."}
Expand Down
17 changes: 14 additions & 3 deletions src/cider/nrepl/middleware/util/namespace.clj
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

(defn inlined-dependency?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still have the inlided-deps filtered separately for clarity's sake.

"Returns true if the namespace matches one of our, or eastwood's,
inlined dependencies."
inlined dependencies."
[namespace]
(let [ns-name (str (ns-name namespace))]
(or
Expand All @@ -52,11 +52,22 @@
;; rewritten by dolly
(.startsWith ns-name "eastwood.copieddeps"))))

(defn internal-namespace?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a regex matcher on a list now. But I think this name makes it easier to read functions where this is used.

"Returns true if the namespace matches the given prefixes."
[namespace & [prefixes]]
(let [ns-name (str (ns-name namespace))]
(->> prefixes
(map re-pattern)
(map #(re-find % ns-name))
(some (complement nil?)))))

(defn loaded-namespaces
"Return all loaded namespaces, except those coming from inlined dependencies."
[]
"Return all loaded namespaces, except those coming from inlined dependencies.
`filter-regexps` is used to filter out namespaces matching regexps."
[& [filter-regexps]]
(->> (all-ns)
(remove inlined-dependency?)
(remove #(internal-namespace? % filter-regexps))
(map ns-name)
(map name)
(sort)))
Expand Down
14 changes: 9 additions & 5 deletions test/clj/cider/nrepl/middleware/apropos_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,24 @@
(is (= (namespaces ns ns)
(namespaces nil ns)
(list (find-ns (symbol ns))))
"Should return a list containing only the searched ns."))))
"Should return a list containing only the searched ns."))

(testing "Removal of namespaces with `filter-regexps`"
(is (not-any? #(re-find #".*nrepl" (str (ns-name %)))
(namespaces nil nil [".*nrepl"]))))))

(deftest test-search
(testing "Search results"
(is (empty? (find-symbols nil "xxxxxxxx" nil false false false))
(is (empty? (find-symbols nil "xxxxxxxx" nil false false false nil))
"Failing searches should return empty.")
(is (= 1 (count (find-symbols nil "handle-apropos" nil false false false)))
(is (= 1 (count (find-symbols nil "handle-apropos" nil false false false nil)))
"Search for specific fn should return it."))

(testing "Symbol vs docstring search"
;; Search for the same fn by name and docstring
(let [x (first (find-symbols nil "handle-apropos" nil false false false))
(let [x (first (find-symbols nil "handle-apropos" nil false false false nil))
y (first (find-symbols nil "Return a sequence of vars whose name matches"
nil true false false))]
nil true false false nil))]
(is (= (dissoc x :doc)
(dissoc y :doc))
"Other than docstring, returned attributes should be the same.")
Expand Down
18 changes: 13 additions & 5 deletions test/clj/cider/nrepl/middleware/ns_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@
(use-fixtures :each session/session-fixture)

(deftest ns-list-integration-test
(let [ns-list (:ns-list (session/message {:op "ns-list"}))]
(is (sequential? ns-list))
(is (every? string? ns-list))
(testing "Removal of namespaces created by source rewriting"
(testing "Basic checks"
(let [ns-list (:ns-list (session/message {:op "ns-list"}))]
(is (sequential? ns-list))
(is (every? string? ns-list))))

(testing "Removal of namespaces created by source rewriting"
(let [ns-list (:ns-list (session/message {:op "ns-list"}))]
(is (not-any? #(or (.startsWith % "deps.")
(.startsWith % "mranderson")
(.startsWith % "eastwood.copieddeps"))
ns-list)))))
ns-list))))

(testing "Removal of namespaces with `filter-regexps`"
(let [ns-list (:ns-list (session/message {:op "ns-list"
:filter-regexps [".*nrepl"]}))]
(is (not-any? #(re-find #".*nrepl" %) ns-list)))))

(deftest ns-list-vars-by-name-integration-test
(let [response (session/message {:op "ns-list-vars-by-name"
Expand Down
4 changes: 2 additions & 2 deletions test/clj/cider/nrepl/middleware/track_state_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@
:requires {'sym-4 'some-namespace}}
{:keys [aliases interns]} (st/ns-as-map cljs-ns)]
(is (= aliases '{sym-3 some-namespace sym-4 some-namespace}))
(is (= interns '{sym-0 {:arglists "([a b] [a] [])"}
sym-1 {}
(is (= interns '{sym-0 {:arglists ([]) :macro true}
sym-1 {:arglists ([])}
sym-2 {}}))))

(deftest calculate-used-aliases
Expand Down
7 changes: 7 additions & 0 deletions test/clj/cider/nrepl/middleware/util/namespace_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@
(deftest test-project-namespaces
(is (contains? (into #{} (n/project-namespaces))
'cider.nrepl.middleware.util.namespace)))

(deftest test-loaded-namespaces
;; If we don't pass the second arg, some cider ns will be returned
(is (some #(re-find #".*nrepl" %) (n/loaded-namespaces)))
;; Shouldn't return any cider.nrepl namespaces
(is (not-any? #(re-find #".*nrepl" %)
Copy link
Contributor Author

@ckoparkar ckoparkar Apr 27, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Malabarba Changed it :-) . I got an email about your comment. But cannot actually see it on GH. Weird.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the comment was on a commit. The rebase must have cleared everything.

(n/loaded-namespaces [".*nrepl"]))))