Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

### Bugs fixed

* [#656](https://github.com/clojure-emacs/clojure-mode/issues/656): Fix clojure-find-ns when ns form is preceded by other forms.

* [#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.

## 5.16.2 (2023-08-23)
Expand Down
38 changes: 24 additions & 14 deletions clojure-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@

;;; Code:


(defvar calculate-lisp-indent-last-sexp)
(defvar delete-pair-blink-delay)
(defvar font-lock-beg)
Expand Down Expand Up @@ -717,7 +716,7 @@ If JUSTIFY is non-nil, justify as well as fill the paragraph."
(fill-prefix (clojure-adaptive-fill-function)))
(do-auto-fill)))))


;;; #_ comments font-locking
;; Code heavily borrowed from Slime.
;; https://github.com/slime/slime/blob/master/contrib/slime-fontifying-fu.el#L186
Expand Down Expand Up @@ -780,7 +779,7 @@ and `(match-end 1)'."
(scan-error (setq result 'retry))))
result))


;;; General font-locking
(defun clojure-match-next-def ()
"Scans the buffer backwards for the next \"top-level\" definition.
Expand Down Expand Up @@ -1889,7 +1888,7 @@ work). To set it from Lisp code, use
(go-loop 1)
(thread 0))



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
Expand Down Expand Up @@ -1944,7 +1943,7 @@ nil."
(delete-region begin (point))
result)))



(defcustom clojure-cache-project-dir t
"Whether to cache the results of `clojure-project-dir'."
Expand Down Expand Up @@ -1988,7 +1987,7 @@ Return nil if not inside a project."
"Denormalize PATH by making it relative to the project root."
(file-relative-name path (clojure-project-dir)))


;;; ns manipulation
(defun clojure-expected-ns (&optional path)
"Return the namespace matching PATH.
Expand Down Expand Up @@ -2125,7 +2124,7 @@ content) are considered part of the preceding sexp."
(make-obsolete-variable 'clojure-namespace-name-regex 'clojure-namespace-regexp "5.12.0")

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

(defcustom clojure-cache-ns nil
"Whether to cache the results of `clojure-find-ns'.
Expand All @@ -2148,12 +2147,13 @@ DIRECTION is `forward' or `backward'."
#'search-backward-regexp)))
(while (and (not candidate)
(funcall fn clojure-namespace-regexp nil t))
(let ((end (match-end 0)))
(let ((start (match-beginning 0))
(end (match-end 0)))
(save-excursion
(save-match-data
(goto-char end)
(clojure-forward-logical-sexp)
(unless (or (clojure--in-string-p) (clojure--in-comment-p) (clojure-top-level-form-p "comment"))
(when (clojure--is-top-level-form-p start)
(save-match-data
(goto-char end)
(clojure-forward-logical-sexp)
(setq candidate (string-remove-prefix "'" (thing-at-point 'symbol))))))))
candidate))

Expand Down Expand Up @@ -2222,7 +2222,7 @@ Returns a list pair, e.g. (\"defn\" \"abc\") or (\"deftest\" \"some-test\")."
(list (match-string-no-properties 1)
(match-string-no-properties 2)))))


;;; Sexp navigation

(defun clojure--looking-at-non-logical-sexp ()
Expand Down Expand Up @@ -2270,6 +2270,16 @@ This will skip over sexps that don't represent objects, so that ^hints and
(backward-sexp 1))
(setq n (1- n))))))

(defun clojure--is-top-level-form-p (&optional point)
Copy link
Member

Choose a reason for hiding this comment

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

What's the difference with clojure-top-level-form-p? It's a bit confusing to have 2 very similarly named functions IMO.

Copy link
Contributor Author

@p4v4n p4v4n Sep 8, 2023

Choose a reason for hiding this comment

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

clojure--is-top-level-form-p checks if the sexp following the point is a top level form.
clojure-top-level-form-p checks the type of enclosing top level form w.r.t current point.
ex:
|(ns foo) -> (clojure--is-top-level-form-p) returns true.
(|ns foo) -> (clojure--is-top-level-form-p) returns nil.
(comment |(ns foo)) -> (clojure--is-top-level-form-p) returns nil.
(comment (|ns foo)) -> (clojure-top-level-form-p "comment") returns true.

Added some unit tests now for clojure--is-top-level-form-p.

Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest naming it clojure--looking-at-top-level-form

This would be consistent in name and semantics with looking-at, I believe.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed the fn to clojure--looking-at-top-level-form.

"Return truthy if form at POINT is a top level form."
(save-excursion
(when point (goto-char point))
(and (looking-at-p "(")
(= (point)
(progn (forward-char)
(beginning-of-defun-raw)
(point))))))

(defun clojure-top-level-form-p (first-form)
"Return truthy if the first form matches FIRST-FORM."
(condition-case nil
Expand Down Expand Up @@ -3173,7 +3183,7 @@ Assumes cursor is at beginning of function."
(clojure--add-arity-reify-internal)))
(indent-region beg end-marker))))


;;; Toggle Ignore forms

(defun clojure--toggle-ignore-next-sexp (&optional n)
Expand Down
4 changes: 2 additions & 2 deletions test/clojure-mode-sexp-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@
(expect (equal "baz-quux" (clojure-find-ns))))
(let ((data
'(("\"\n(ns foo-bar)\"\n" "(in-ns 'baz-quux)" "baz-quux")
(";(ns foo-bar)\n" "(in-ns 'baz-quux)" "baz-quux")
(";(ns foo-bar)\n" "(in-ns 'baz-quux2)" "baz-quux2")
("(ns foo-bar)\n" "\"\n(in-ns 'baz-quux)\"" "foo-bar")
("(ns foo-bar)\n" ";(in-ns 'baz-quux)" "foo-bar"))))
("(ns foo-bar2)\n" ";(in-ns 'baz-quux)" "foo-bar2"))))
(pcase-dolist (`(,form1 ,form2 ,expected) data)
(with-clojure-buffer form1
(save-excursion (insert form2))
Expand Down
21 changes: 21 additions & 0 deletions test/clojure-mode-util-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,27 @@
(with-clojure-buffer "(ns foo)
(ns-unmap *ns* 'map)
(ns.misleading 1 2 3)"
(expect (clojure-find-ns) :to-equal "foo")))
(it "should skip leading garbage"
(with-clojure-buffer " (ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))
(with-clojure-buffer "1(ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))
(with-clojure-buffer "1 (ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))
(with-clojure-buffer "1
(ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))
(with-clojure-buffer "[1]
(ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))
(with-clojure-buffer "[1] (ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))
(with-clojure-buffer "[1](ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))
(with-clojure-buffer "(ns)(ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))
(with-clojure-buffer "(ns )(ns foo)"
(expect (clojure-find-ns) :to-equal "foo"))))

(describe "clojure-sort-ns"
Expand Down