From 5117d8c39d458da8b16f33fa54a714febd512af2 Mon Sep 17 00:00:00 2001 From: yuhan0 Date: Fri, 20 Mar 2020 13:12:41 +0800 Subject: [PATCH 1/3] Fix namespace detection with complex metadata --- clojure-mode.el | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/clojure-mode.el b/clojure-mode.el index bf183fbe..03f89a28 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -1888,6 +1888,11 @@ content) are considered part of the preceding sexp." (zero-or-one (any ":'")) ;; (in-ns 'foo) or (ns+ :user) (group (one-or-more (not (any "()\"" whitespace))) symbol-end))) +(make-obsolete-variable 'clojure-namespace-name-regex 'clojure-namespace-regexp "5.12.0") + +(defconst clojure-namespace-regexp + (rx line-start "(" (? "clojure.core/") (or "in-ns" "ns" "ns+"))) + (defcustom clojure-cache-ns nil "Whether to cache the results of `clojure-find-ns'. @@ -1911,9 +1916,16 @@ DIRECTION is `forward' or `backward'." #'search-forward-regexp #'search-backward-regexp))) (while (and (not candidate) - (funcall fn clojure-namespace-name-regex nil t)) - (unless (or (clojure--in-string-p) (clojure--in-comment-p)) - (setq candidate (match-string-no-properties 4)))) + (funcall fn clojure-namespace-regexp nil t)) + (let ((end (match-end 0))) + (save-excursion + (save-match-data + (goto-char end) + (clojure-forward-logical-sexp) + (when (and (looking-back clojure--sym-regexp end 'greedy) + (not (clojure--in-string-p)) + (not (clojure--in-comment-p))) + (setq candidate (match-string-no-properties 0))))))) candidate)) (defun clojure-find-ns () From 618385bc55642c6a86880d40edf3e327548afa19 Mon Sep 17 00:00:00 2001 From: yuhan0 Date: Fri, 20 Mar 2020 13:13:02 +0800 Subject: [PATCH 2/3] Support #^ metadata syntax --- clojure-mode.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clojure-mode.el b/clojure-mode.el index 03f89a28..cf6acb26 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -1994,7 +1994,7 @@ Returns a list pair, e.g. (\"defn\" \"abc\") or (\"deftest\" \"some-test\")." \"Non-logical\" sexp are ^metadata and #reader.macros." (comment-normalize-vars) (comment-forward (point-max)) - (looking-at-p "\\^\\|#:?:?[[:alpha:]]")) + (looking-at-p "\\(?:#?\\^\\)\\|#:?:?[[:alpha:]]")) (defun clojure-forward-logical-sexp (&optional n) "Move forward N logical sexps. From 089f38f7e34750628a8dd8b26428bf9fec3ad04a Mon Sep 17 00:00:00 2001 From: yuhan0 Date: Fri, 20 Mar 2020 07:05:30 +0800 Subject: [PATCH 3/3] update find-ns tests --- test/clojure-mode-util-test.el | 92 +++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/test/clojure-mode-util-test.el b/test/clojure-mode-util-test.el index ee5591a6..d8d9b984 100644 --- a/test/clojure-mode-util-test.el +++ b/test/clojure-mode-util-test.el @@ -57,47 +57,57 @@ (clojure-expected-ns)) clj-file-ns)))))) -(describe "clojure-namespace-name-regex" - (it "should match common namespace declarations" - (let ((ns "(ns foo)")) - (expect (string-match clojure-namespace-name-regex ns)) - (match-string 4 ns)) - (let ((ns "(ns - foo)")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "foo")) - (let ((ns "(ns foo.baz)")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "foo.baz")) - (let ((ns "(ns ^:bar foo)")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "foo")) - (let ((ns "(ns ^:bar ^:baz foo)")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "foo")) - (let ((ns "(ns ^{:bar true} foo)")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "foo")) - (let ((ns "(ns #^{:bar true} foo)")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "foo")) - ;; TODO - ;; (let ((ns "(ns #^{:fail {}} foo)")) - ;; (should (string-match clojure-namespace-name-regex ns)) - ;; (match-string 4 ns)) - ;; (let ((ns "(ns ^{:fail2 {}} foo.baz)")) - ;; (should (string-match clojure-namespace-name-regex ns)) - ;; (should (equal "foo.baz" (match-string 4 ns)))) - (let ((ns "(ns ^{} foo)")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "foo")) - (let ((ns "(ns ^{:skip-wiki true} - aleph.netty")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "aleph.netty")) - (let ((ns "(ns foo+)")) - (expect (string-match clojure-namespace-name-regex ns)) - (expect (match-string 4 ns) :to-equal "foo+")))) +(describe "clojure-find-ns" + (it "should find common namespace declarations" + (with-clojure-buffer "(ns foo)" + (expect (clojure-find-ns) :to-equal "foo")) + (with-clojure-buffer "(ns + foo)" + (expect (clojure-find-ns) :to-equal "foo")) + (with-clojure-buffer "(ns foo.baz)" + (expect (clojure-find-ns) :to-equal "foo.baz")) + (with-clojure-buffer "(ns ^:bar foo)" + (expect (clojure-find-ns) :to-equal "foo")) + (with-clojure-buffer "(ns ^:bar ^:baz foo)" + (expect (clojure-find-ns) :to-equal "foo"))) + (it "should find namespace declarations with nested metadata and docstrings" + (with-clojure-buffer "(ns ^{:bar true} foo)" + (expect (clojure-find-ns) :to-equal "foo")) + (with-clojure-buffer "(ns #^{:bar true} foo)" + (expect (clojure-find-ns) :to-equal "foo")) + (with-clojure-buffer "(ns #^{:fail {}} foo)" + (expect (clojure-find-ns) :to-equal "foo")) + (with-clojure-buffer "(ns ^{:fail2 {}} foo.baz)" + (expect (clojure-find-ns) :to-equal "foo.baz")) + (with-clojure-buffer "(ns ^{} foo)" + (expect (clojure-find-ns) :to-equal "foo")) + (with-clojure-buffer "(ns ^{:skip-wiki true} + aleph.netty" + (expect (clojure-find-ns) :to-equal "aleph.netty")) + (with-clojure-buffer "(ns ^{:foo {:bar :baz} :fake (ns in.meta)} foo + \"docstring +(ns misleading)\")" + (expect (clojure-find-ns) :to-equal "foo"))) + (it "should support non-alphanumeric characters" + (with-clojure-buffer "(ns foo+)" + (expect (clojure-find-ns) :to-equal "foo+")) + (with-clojure-buffer "(ns bar**baz$-_quux)" + (expect (clojure-find-ns) :to-equal "bar**baz$-_quux"))) + (it "should support in-ns forms" + (with-clojure-buffer "(in-ns 'bar.baz)" + (expect (clojure-find-ns) :to-equal "bar.baz"))) + (it "should take the closest ns before point" + (with-clojure-buffer " (ns foo1) + +(ns foo2)" + (expect (clojure-find-ns) :to-equal "foo2")) + (with-clojure-buffer " (in-ns foo1) +(ns 'foo2) +(in-ns 'foo3) +| +(ns foo4)" + (re-search-backward "|") + (expect (clojure-find-ns) :to-equal "foo3")))) (describe "clojure-sort-ns" (it "should sort requires in a basic ns"