summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--cider-debug.el93
-rw-r--r--test/cider-tests.el17
3 files changed, 67 insertions, 44 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67db534f..95ef7947 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
### Bugs fixed
* [#1632](https://github.com/clojure-emacs/cider/pull/1632): Redefining a function correctly updates eldoc.
+* [#1630](https://github.com/clojure-emacs/cider/pull/1630): The debugger no longer gets confused inside `@` redefs.
* [#1599](https://github.com/clojure-emacs/cider/pull/1599): Don't error when test makes 0 assertions.
* [#1563](https://github.com/clojure-emacs/cider/issues/1563): Handle invalid regular expressions in apropos.
* [#1625](https://github.com/clojure-emacs/cider/issues/1625): Display a more meaningful message when running
diff --git a/cider-debug.el b/cider-debug.el
index a3931b06..46d94091 100644
--- a/cider-debug.el
+++ b/cider-debug.el
@@ -477,51 +477,56 @@ key of a map, and it means \"go to the value associated with this key\"."
(while coordinates
(while (clojure--looking-at-non-logical-sexp)
(forward-sexp))
- (down-list)
- ;; Are we entering a syntax-quote?
- (when (looking-back "`\\(#{\\|[{[(]\\)" (line-beginning-position))
- ;; If we are, this affects all nested structures until the next `~',
- ;; so we set this variable for all following steps in the loop.
- (setq in-syntax-quote t))
- (when in-syntax-quote
- ;; A `(. .) is read as (seq (concat (list .) (list .))). This pops
- ;; the `seq', since the real coordinates are inside the `concat'.
- (pop coordinates)
- ;; Non-list seqs like `[] and `{} are read with
- ;; an extra (apply vector ...), so pop it too.
- (unless (eq ?\( (char-before))
- (pop coordinates)))
- ;; #(...) is read as (fn* ([] ...)), so we patch that here.
- (when (looking-back "#(" (line-beginning-position))
- (pop coordinates))
- (if coordinates
- (let ((next (pop coordinates)))
- (when in-syntax-quote
- ;; We're inside the `concat' form, but we need to discard the
- ;; actual `concat' symbol from the coordinate.
- (setq next (1- next)))
- ;; String coordinates are map keys.
- (if (stringp next)
- (cider--debug-goto-keyval next)
- (clojure-forward-logical-sexp next)
+ ;; An `@x` is read as (deref x), so we pop coordinates once to account
+ ;; for the extra depth, and move past the @ char.
+ (if (eq ?@ (char-after))
+ (progn (forward-char 1)
+ (pop coordinates))
+ (down-list)
+ ;; Are we entering a syntax-quote?
+ (when (looking-back "`\\(#{\\|[{[(]\\)" (line-beginning-position))
+ ;; If we are, this affects all nested structures until the next `~',
+ ;; so we set this variable for all following steps in the loop.
+ (setq in-syntax-quote t))
+ (when in-syntax-quote
+ ;; A `(. .) is read as (seq (concat (list .) (list .))). This pops
+ ;; the `seq', since the real coordinates are inside the `concat'.
+ (pop coordinates)
+ ;; Non-list seqs like `[] and `{} are read with
+ ;; an extra (apply vector ...), so pop it too.
+ (unless (eq ?\( (char-before))
+ (pop coordinates)))
+ ;; #(...) is read as (fn* ([] ...)), so we patch that here.
+ (when (looking-back "#(" (line-beginning-position))
+ (pop coordinates))
+ (if coordinates
+ (let ((next (pop coordinates)))
(when in-syntax-quote
- (clojure-forward-logical-sexp 1)
- (forward-sexp -1)
- ;; Here a syntax-quote is ending.
- (let ((match (when (looking-at "~@?")
- (match-string 0))))
- (when match
- (setq in-syntax-quote nil))
- ;; A `~@' is read as the object itself, so we don't pop
- ;; anything.
- (unless (equal "~@" match)
- ;; Anything else (including a `~') is read as a `list'
- ;; form inside the `concat', so we need to pop the list
- ;; from the coordinates.
- (pop coordinates))))))
- ;; If that extra pop was the last coordinate, this represents the
- ;; entire #(...), so we should move back out.
- (backward-up-list)))
+ ;; We're inside the `concat' form, but we need to discard the
+ ;; actual `concat' symbol from the coordinate.
+ (setq next (1- next)))
+ ;; String coordinates are map keys.
+ (if (stringp next)
+ (cider--debug-goto-keyval next)
+ (clojure-forward-logical-sexp next)
+ (when in-syntax-quote
+ (clojure-forward-logical-sexp 1)
+ (forward-sexp -1)
+ ;; Here a syntax-quote is ending.
+ (let ((match (when (looking-at "~@?")
+ (match-string 0))))
+ (when match
+ (setq in-syntax-quote nil))
+ ;; A `~@' is read as the object itself, so we don't pop
+ ;; anything.
+ (unless (equal "~@" match)
+ ;; Anything else (including a `~') is read as a `list'
+ ;; form inside the `concat', so we need to pop the list
+ ;; from the coordinates.
+ (pop coordinates))))))
+ ;; If that extra pop was the last coordinate, this represents the
+ ;; entire #(...), so we should move back out.
+ (backward-up-list))))
;; Place point at the end of instrumented sexp.
(clojure-forward-logical-sexp 1))
;; Avoid throwing actual errors, since this happens on every breakpoint.
diff --git a/test/cider-tests.el b/test/cider-tests.el
index 582a0c56..19e98805 100644
--- a/test/cider-tests.el
+++ b/test/cider-tests.el
@@ -112,6 +112,23 @@
(cider--debug-move-point '(2 1 1 1))
(should (string= (buffer-substring (point-min) (point)) "`[(~d)"))))
+(ert-deftest test-debug-move-point-@ ()
+ (with-temp-buffer
+ (clojure-mode)
+ (save-excursion (insert "(let [x (atom 1)] @x)"))
+ (cider--debug-move-point '(2 1))
+ (should (looking-back "@x")))
+ (with-temp-buffer
+ (clojure-mode)
+ (save-excursion (insert "(do @(do (atom {})))"))
+ (cider--debug-move-point '(1 1 1))
+ (should (looking-back "(atom {})")))
+ (with-temp-buffer
+ (clojure-mode)
+ (save-excursion (insert "(do @@(do (atom {})))"))
+ (cider--debug-move-point '(1 1 1 1))
+ (should (looking-back "(atom {})"))))
+
(ert-deftest test-debug-move-point-metadata ()
(with-temp-buffer
(clojure-mode)