Skip to content

Commit

Permalink
Implement the :here debug action
Browse files Browse the repository at this point in the history
This action takes a coords vector in the message, and tells the debugger
to skip any breakpoints before that.
  • Loading branch information
Malabarba committed Jan 16, 2016
1 parent dfd9474 commit aebd72c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
41 changes: 33 additions & 8 deletions src/cider/nrepl/middleware/debug.clj
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,30 @@
Its value is discarded at the end each eval session."
nil)

(defn coord<
"Return true if coordinate x comes before y.
Here, \"comes before\" means that a sexp at coord x is evaluated
before a sexp at coord y (assuming a trivial code-flow)."
[x y]
(if (seq x)
(if (seq y)
(let [fa (first x)
fb (first y)]
(if (= fa fb)
(recur (rest x) (rest y))
(< fa fb)))
;; If coord `x` goes deeper than `y`, then is `x < y`.
true)
false))

(defn skip-breaks?
"True if the breakpoint at coordinates should be skipped.
If *skip-breaks* is true, return true.
If *skip-breaks* is a vector of integers, return true if coordinates
are deeper than this vector."
If the first element of `*skip-breaks*` is :all, return true.
Otherwise, the first element should be :deeper or :before.
If :deeper, return true if the given coordinates are deeper than the
rest of `*skip-breaks*`. If :before, return true if they represent a
place before the rest."
[coordinates]
(when-let [[mode & skip-coords] @*skip-breaks*]
(case mode
Expand All @@ -75,11 +94,13 @@
;; From :out, skip some breaks.
:deeper (let [parent (take (count skip-coords) coordinates)]
(and (= skip-coords parent)
(> (count coordinates) (count parent)))))))
(> (count coordinates) (count parent))))
;; From :here, skip some breaks.
:before (coord< coordinates skip-coords))))

(defn skip-breaks!
"Set the value of *skip-breaks* for the top-level breakpoint.
If bool-or-vec is a vector, mode should be :deeper (see
If bool-or-vec is a vector, mode should be :deeper or :before (see
`skip-breaks?`). Otherwise mode should be :all or false."
[mode & [bool-or-vec]]
(reset! *skip-breaks* (when mode
Expand Down Expand Up @@ -234,18 +255,22 @@
a :code entry, its value is used for operations such as :eval, which
would otherwise interactively prompt for an expression."
[value extras]
(let [commands (cond->> [:next :continue :out :inspect :locals :inject :eval :quit]
(let [commands (cond->> [:next :continue :out :here :inspect :locals :inject :eval :quit]
(not (map? *msg*)) (remove #{:quit})
(cljs/grab-cljs-env *msg*) identity)
response-raw (read-debug extras commands nil)
{:keys [code response page-size] :or {page-size 32}} (if (map? response-raw) response-raw
{:response response-raw})

{:keys [code coord response page-size] :or {page-size 32}}
(if (map? response-raw) response-raw
{:response response-raw})
extras (dissoc extras :inspect)]
(case response
:next value
:continue (do (skip-breaks! :all) value)
:out (do (skip-breaks! :deeper (butlast (:coor extras)))
value)
:here (do (skip-breaks! :before coord)
value)
:locals (inspect-then-read-command value extras page-size *locals*)
:inspect (->> (read-debug-eval-expression "Inspect value: " extras code)
(inspect-then-read-command value extras page-size))
Expand Down
9 changes: 9 additions & 0 deletions test/clj/cider/nrepl/middleware/debug_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
[clojure.tools.nrepl.transport :as t]
[cider.nrepl.middleware.debug :as d]))

(deftest coord<
(are [a b] (and (d/coord< a b)
(not (d/coord< b a)))
[1] []
[0] [1]
[1] [2]
[1 2] [1 3]
[1 0] [1]))

(deftest skip-breaks
(binding [d/*skip-breaks* (atom [:all])]
(is (#'d/skip-breaks? []))
Expand Down

0 comments on commit aebd72c

Please sign in to comment.