Skip to content

Commit 77feec4

Browse files
authored
Make clojure-find-ns work when preceded by other forms (#664)
Fixes #656
1 parent 1dc343f commit 77feec4

4 files changed

+62
-9
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
### Bugs fixed
1010

11+
* [#656](https://github.com/clojure-emacs/clojure-mode/issues/656): Fix clojure-find-ns when ns form is preceded by other forms.
12+
1113
* [#593](https://github.com/clojure-emacs/clojure-mode/issues/593): Fix clojure-find-ns when ns form is preceded by whitespace or inside comment form.
1214

1315
## 5.16.2 (2023-08-23)

clojure-mode.el

+17-6
Original file line numberDiff line numberDiff line change
@@ -2125,7 +2125,7 @@ content) are considered part of the preceding sexp."
21252125
(make-obsolete-variable 'clojure-namespace-name-regex 'clojure-namespace-regexp "5.12.0")
21262126

21272127
(defconst clojure-namespace-regexp
2128-
(rx line-start (zero-or-more whitespace) "(" (? "clojure.core/") (or "in-ns" "ns" "ns+") symbol-end))
2128+
(rx "(" (? "clojure.core/") (or "in-ns" "ns" "ns+") symbol-end))
21292129

21302130
(defcustom clojure-cache-ns nil
21312131
"Whether to cache the results of `clojure-find-ns'.
@@ -2148,12 +2148,13 @@ DIRECTION is `forward' or `backward'."
21482148
#'search-backward-regexp)))
21492149
(while (and (not candidate)
21502150
(funcall fn clojure-namespace-regexp nil t))
2151-
(let ((end (match-end 0)))
2151+
(let ((start (match-beginning 0))
2152+
(end (match-end 0)))
21522153
(save-excursion
2153-
(save-match-data
2154-
(goto-char end)
2155-
(clojure-forward-logical-sexp)
2156-
(unless (or (clojure--in-string-p) (clojure--in-comment-p) (clojure-top-level-form-p "comment"))
2154+
(when (clojure--looking-at-top-level-form start)
2155+
(save-match-data
2156+
(goto-char end)
2157+
(clojure-forward-logical-sexp)
21572158
(setq candidate (string-remove-prefix "'" (thing-at-point 'symbol))))))))
21582159
candidate))
21592160

@@ -2270,6 +2271,16 @@ This will skip over sexps that don't represent objects, so that ^hints and
22702271
(backward-sexp 1))
22712272
(setq n (1- n))))))
22722273

2274+
(defun clojure--looking-at-top-level-form (&optional point)
2275+
"Return truthy if form at POINT is a top level form."
2276+
(save-excursion
2277+
(when point (goto-char point))
2278+
(and (looking-at-p "(")
2279+
(= (point)
2280+
(progn (forward-char)
2281+
(beginning-of-defun-raw)
2282+
(point))))))
2283+
22732284
(defun clojure-top-level-form-p (first-form)
22742285
"Return truthy if the first form matches FIRST-FORM."
22752286
(condition-case nil

test/clojure-mode-sexp-test.el

+22-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,26 @@
4141
(wrong))"
4242
(expect (let ((beginning-of-defun-function nil))
4343
(clojure-top-level-form-p "comment"))))))
44-
44+
(describe "clojure--looking-at-top-level-form"
45+
(it "should return nil when point is inside a top level form"
46+
(with-clojure-buffer-point
47+
"(comment
48+
|(ns foo))"
49+
(expect (clojure--looking-at-top-level-form) :to-equal nil))
50+
(with-clojure-buffer-point
51+
"\"|(ns foo)\""
52+
(expect (clojure--looking-at-top-level-form) :to-equal nil))
53+
(with-clojure-buffer-point
54+
"^{:fake-ns |(ns foo)}"
55+
(expect (clojure--looking-at-top-level-form) :to-equal nil)))
56+
(it "should return true when point is looking at a top level form"
57+
(with-clojure-buffer-point
58+
"(comment
59+
|(ns foo))"
60+
(expect (clojure--looking-at-top-level-form (point-min)) :to-equal t))
61+
(with-clojure-buffer-point
62+
"|(ns foo)"
63+
(expect (clojure--looking-at-top-level-form) :to-equal t))))
4564
(describe "clojure-beginning-of-defun-function"
4665
(it "should go to top level form"
4766
(with-clojure-buffer-point
@@ -164,9 +183,9 @@
164183
(expect (equal "baz-quux" (clojure-find-ns))))
165184
(let ((data
166185
'(("\"\n(ns foo-bar)\"\n" "(in-ns 'baz-quux)" "baz-quux")
167-
(";(ns foo-bar)\n" "(in-ns 'baz-quux)" "baz-quux")
186+
(";(ns foo-bar)\n" "(in-ns 'baz-quux2)" "baz-quux2")
168187
("(ns foo-bar)\n" "\"\n(in-ns 'baz-quux)\"" "foo-bar")
169-
("(ns foo-bar)\n" ";(in-ns 'baz-quux)" "foo-bar"))))
188+
("(ns foo-bar2)\n" ";(in-ns 'baz-quux)" "foo-bar2"))))
170189
(pcase-dolist (`(,form1 ,form2 ,expected) data)
171190
(with-clojure-buffer form1
172191
(save-excursion (insert form2))

test/clojure-mode-util-test.el

+21
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,27 @@
142142
(with-clojure-buffer "(ns foo)
143143
(ns-unmap *ns* 'map)
144144
(ns.misleading 1 2 3)"
145+
(expect (clojure-find-ns) :to-equal "foo")))
146+
(it "should skip leading garbage"
147+
(with-clojure-buffer " (ns foo)"
148+
(expect (clojure-find-ns) :to-equal "foo"))
149+
(with-clojure-buffer "1(ns foo)"
150+
(expect (clojure-find-ns) :to-equal "foo"))
151+
(with-clojure-buffer "1 (ns foo)"
152+
(expect (clojure-find-ns) :to-equal "foo"))
153+
(with-clojure-buffer "1
154+
(ns foo)"
155+
(expect (clojure-find-ns) :to-equal "foo"))
156+
(with-clojure-buffer "[1]
157+
(ns foo)"
158+
(expect (clojure-find-ns) :to-equal "foo"))
159+
(with-clojure-buffer "[1] (ns foo)"
160+
(expect (clojure-find-ns) :to-equal "foo"))
161+
(with-clojure-buffer "[1](ns foo)"
162+
(expect (clojure-find-ns) :to-equal "foo"))
163+
(with-clojure-buffer "(ns)(ns foo)"
164+
(expect (clojure-find-ns) :to-equal "foo"))
165+
(with-clojure-buffer "(ns )(ns foo)"
145166
(expect (clojure-find-ns) :to-equal "foo"))))
146167

147168
(describe "clojure-sort-ns"

0 commit comments

Comments
 (0)