From cf8dd5afbf9963d0ed712b7e92928bce140ff3dd Mon Sep 17 00:00:00 2001 From: yuhan0 Date: Tue, 3 Mar 2020 16:29:07 +0800 Subject: [PATCH] Extend undef op to work on fully qualified symbols (#670) --- CHANGELOG.md | 2 + src/cider/nrepl/middleware/undef.clj | 23 +++++++++-- .../clj/cider/nrepl/middleware/undef_test.clj | 38 ++++++++++++++++++- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6adc2a117..4bad4372d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ ### New Features +* [#670](https://github.com/clojure-emacs/cider-nrepl/pull/670): Extend undef op to work on fully qualified symbols. + ## 0.24.0 (2020-02-14) ### Bugs fixed diff --git a/src/cider/nrepl/middleware/undef.clj b/src/cider/nrepl/middleware/undef.clj index fc839e8b5..5d061649a 100644 --- a/src/cider/nrepl/middleware/undef.clj +++ b/src/cider/nrepl/middleware/undef.clj @@ -1,14 +1,29 @@ (ns cider.nrepl.middleware.undef - "Undefine a symbol" + "Middleware for undefining symbols. + Fully qualified symbols are interpreted as a var to be unmapped in its + original namespace, whereas unqualified symbols are interpreted as both a var + and ns alias to be unmapped from the current namespace." (:require [cider.nrepl.middleware.util.error-handling :refer [with-safe-transport]] [orchard.misc :as misc])) (defn undef + "Undefines a symbol. + When `symbol` is unqualified, it is interpreted as both an alias and var to be + unmapped from the namespace `ns`. + When qualified (eg. `foo/bar`), it is interpreted as a var to be unmapped in + the namespace `foo`, which may be an alias in `ns`." [{:keys [ns symbol]}] - (let [[ns symbol] (map misc/as-sym [ns symbol])] - (ns-unalias ns symbol) - (ns-unmap ns symbol) + (let [ns (misc/as-sym ns) + [sym-ns sym-name] ((juxt (comp misc/as-sym namespace) misc/name-sym) + (misc/as-sym symbol))] + (if sym-ns + ;; fully qualified => var in other namespace + (let [other-ns (get (ns-aliases ns) sym-ns sym-ns)] + (ns-unmap other-ns sym-name)) + ;; unqualified => alias or var in current ns + (do (ns-unalias ns sym-name) + (ns-unmap ns sym-name))) symbol)) (defn undef-reply diff --git a/test/clj/cider/nrepl/middleware/undef_test.clj b/test/clj/cider/nrepl/middleware/undef_test.clj index 9c078bf92..c32eddbf4 100644 --- a/test/clj/cider/nrepl/middleware/undef_test.clj +++ b/test/clj/cider/nrepl/middleware/undef_test.clj @@ -19,7 +19,43 @@ :symbol "x"})))) (is (= ["nil"] (:value (session/message {:op "eval" - :code "(ns-resolve 'user 'x)"})))))) + :code "(ns-resolve 'user 'x)"}))))) + (testing "undef undefines vars in other namespaces" + (is (= #{"done"} + (:status (session/message {:op "eval" + :code "(do (ns other.ns) (in-ns 'user) (require '[other.ns :as other]))"})))) + (is (= ["#'other.ns/x"] + (:value (session/message {:op "eval" + :code "(do (in-ns 'other.ns) (def x 1) (in-ns 'user) (ns-resolve 'other.ns 'x))"})))) + (is (= #{"done"} + (:status (session/message {:op "undef" + :ns "other.ns" + :symbol "x"})))) + (is (= ["nil"] + (:value (session/message {:op "eval" + :code "(ns-resolve 'other.ns 'x)"}))))) + (testing "undef takes fully qualified symbols" + (is (= ["#'other.ns/x"] + (:value (session/message {:op "eval" + :code "(do (in-ns 'other.ns) (def x 1) (in-ns 'user) (ns-resolve 'other.ns 'x))"})))) + (is (= #{"done"} + (:status (session/message {:op "undef" + :ns "user" + :symbol "other.ns/x"})))) + (is (= ["nil"] + (:value (session/message {:op "eval" + :code "(ns-resolve 'other.ns 'x)"}))))) + (testing "undef resolves namespace aliases in fully qualified symbols" + (is (= ["#'other.ns/x"] + (:value (session/message {:op "eval" + :code "(do (in-ns 'other.ns) (def x 1) (in-ns 'user) (ns-resolve 'other.ns 'x))"})))) + (is (= #{"done"} + (:status (session/message {:op "undef" + :ns "user" + :symbol "other/x"})))) + (is (= ["nil"] + (:value (session/message {:op "eval" + :code "(ns-resolve 'other.ns 'x)"})))))) (deftest undef-alias-test (testing "undef undefines aliases"