diff --git a/CHANGELOG.md b/CHANGELOG.md index 50b7455c..27aed4f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +### Changes + +* Improve support for multiple forms in the same line by replacing `beginning-of-defun` fn. + ## 5.16.2 (2023-08-23) ### Changes diff --git a/clojure-mode.el b/clojure-mode.el index 8e7b3626..0d2b613e 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -549,7 +549,7 @@ replacement for `cljr-expand-let`." ;; If we are now precisely at the beginning of a defun, make sure ;; beginning-of-defun finds that one rather than the previous one. (or (eobp) (forward-char 1)) - (beginning-of-defun) + (beginning-of-defun-raw) ;; Make sure we are really inside the defun found, not after it. (when (and (looking-at "\\s(") (progn (end-of-defun) @@ -1188,7 +1188,7 @@ Note that this means that there is no guarantee of proper font locking in def* forms that are not at top level." (goto-char point) (ignore-errors - (beginning-of-defun)) + (beginning-of-defun-raw)) (let ((beg-def (point))) (when (and (not (= point beg-def)) @@ -2217,7 +2217,7 @@ renaming a namespace." Returns a list pair, e.g. (\"defn\" \"abc\") or (\"deftest\" \"some-test\")." (save-excursion (unless (looking-at clojure-def-type-and-name-regex) - (beginning-of-defun)) + (beginning-of-defun-raw)) (when (search-forward-regexp clojure-def-type-and-name-regex nil t) (list (match-string-no-properties 1) (match-string-no-properties 2))))) @@ -2274,7 +2274,7 @@ This will skip over sexps that don't represent objects, so that ^hints and "Return truthy if the first form matches FIRST-FORM." (condition-case nil (save-excursion - (beginning-of-defun) + (beginning-of-defun-raw) (forward-char 1) (clojure-forward-logical-sexp 1) (clojure-backward-logical-sexp 1) @@ -2332,10 +2332,10 @@ many times." (save-match-data (let ((original-position (point)) clojure-comment-end) - (beginning-of-defun) + (beginning-of-defun-raw) (end-of-defun) (setq clojure-comment-end (point)) - (beginning-of-defun) + (beginning-of-defun-raw) (forward-char 1) ;; skip paren so we start at comment (clojure-forward-logical-sexp) ;; skip past the comment form itself (if-let ((sexp-start (clojure-find-first (lambda (beg-pos) @@ -2343,9 +2343,9 @@ many times." (clojure-sexp-starts-until-position clojure-comment-end)))) (progn (goto-char sexp-start) t) - (beginning-of-defun n)))) - (scan-error (beginning-of-defun n))) - (beginning-of-defun n)))) + (beginning-of-defun-raw n)))) + (scan-error (beginning-of-defun-raw n))) + (beginning-of-defun-raw n)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -2467,7 +2467,7 @@ With universal argument \\[universal-argument], fully unwind thread." (n) (1))) (save-excursion (let ((limit (save-excursion - (beginning-of-defun) + (beginning-of-defun-raw) (point)))) (ignore-errors (when (looking-at "(") @@ -2997,7 +2997,7 @@ END marks the end of the fn expression" (goto-char beg)) (if (or (looking-at-p "#(") (ignore-errors (forward-char 1)) - (re-search-backward "#(" (save-excursion (beginning-of-defun) (point)) 'noerror)) + (re-search-backward "#(" (save-excursion (beginning-of-defun-raw) (backward-char) (point)) 'noerror)) (let* ((end (save-excursion (clojure-forward-logical-sexp) (point-marker))) (argspec (clojure--gather-fn-literal-args)) (arity (car argspec)) @@ -3221,7 +3221,7 @@ With universal argument \\[universal-argument], act on the \"top-level\" form." "Toggle the #_ ignore reader form for the \"top-level\" form at point." (interactive) (save-excursion - (beginning-of-defun) + (beginning-of-defun-raw) (clojure--toggle-ignore-next-sexp))) diff --git a/test/clojure-mode-refactor-threading-test.el b/test/clojure-mode-refactor-threading-test.el index 61ad5983..efd7eb1a 100644 --- a/test/clojure-mode-refactor-threading-test.el +++ b/test/clojure-mode-refactor-threading-test.el @@ -247,6 +247,16 @@ (clojure-unwind '(4))) + (when-refactoring-it "should unwind correctly when multiple ->> are present on same line" + "(->> 1 inc) (->> [1 2 3 4 5] + (filter even?) + (map square))" + + "(->> 1 inc) (->> (map square (filter even? [1 2 3 4 5])))" + + (clojure-unwind) + (clojure-unwind)) + (when-refactoring-it "should unwind with function name" "(->> [1 2 3 4 5] sum @@ -299,8 +309,7 @@ (when-refactoring-it "should unwind some->>" "(some->> :b - (find {:a 1}) - val + (find {:a 1}) val (+ 5))" "(some->> (+ 5 (val (find {:a 1} :b))))" diff --git a/test/clojure-mode-sexp-test.el b/test/clojure-mode-sexp-test.el index 1db0e708..aaeb798d 100644 --- a/test/clojure-mode-sexp-test.el +++ b/test/clojure-mode-sexp-test.el @@ -31,30 +31,37 @@ (wrong))" ;; make this use the native beginning of defun since this is used to ;; determine whether to use the comment aware version or not. + (expect (let ((beginning-of-defun-function nil)) + (clojure-top-level-form-p "comment"))))) + (it "should return true when multiple forms are present" + (with-clojure-buffer-point + "(+ 1 2) (comment + (wrong) + (rig|ht) + (wrong))" (expect (let ((beginning-of-defun-function nil)) (clojure-top-level-form-p "comment")))))) (describe "clojure-beginning-of-defun-function" (it "should go to top level form" (with-clojure-buffer-point - "(comment + " (comment (wrong) (wrong) (rig|ht) (wrong))" - (beginning-of-defun) + (clojure-beginning-of-defun-function) (expect (looking-at-p "(comment")))) (it "should eval top level forms inside comment forms when clojure-toplevel-inside-comment-form set to true" (with-clojure-buffer-point - "(comment - (wrong) + "(+ inc 1) (comment (wrong) - (rig|ht) + (wrong) (rig|ht) (wrong))" (let ((clojure-toplevel-inside-comment-form t)) - (beginning-of-defun)) - (expect (looking-at-p "[[:space:]]*(right)")))) + (clojure-beginning-of-defun-function)) + (expect (looking-at-p "(right)")))) (it "should go to beginning of previous top level form" (with-clojure-buffer-point