From 2fff914206bb39b3e16498892ad6108056bd22c4 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Thu, 9 Jul 2015 12:28:26 +0100 Subject: [PATCH] Limit the size of data printed by the debugger --- src/cider/nrepl/middleware/debug.clj | 20 ++++++++++--- .../clj/cider/nrepl/middleware/debug_test.clj | 30 +++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/cider/nrepl/middleware/debug.clj b/src/cider/nrepl/middleware/debug.clj index 4cd3cf867..406a08db6 100644 --- a/src/cider/nrepl/middleware/debug.clj +++ b/src/cider/nrepl/middleware/debug.clj @@ -117,12 +117,22 @@ "Bound by the `breakpoint` macro to the local &env." {}) +(def print-length (atom nil)) +(def print-level (atom nil)) + +(defn pr-short + "Like `pr-str` but limited in length and depth." + [x] + (binding [*print-length* @print-length + *print-level* @print-level] + (pr-str x))) + (defn- locals-for-message "Prepare a map of local variables for sending through the repl. This involves removing any keys whose name looks like it was autogenerated by a macro, and turning keys and values to strings." [m] - (map (partial map pr-str) + (map (partial map pr-short) (remove (fn [[k]] (re-find #"_" (name k))) m))) (defn- read-debug @@ -215,7 +225,7 @@ (inspect-then-read-command value extras)) :inject (read-debug-eval-expression "Expression to inject: " extras code) :eval (let [return (read-debug-eval-expression "Expression to evaluate: " extras code)] - (read-debug-command value (assoc extras :debug-value (pr-str return)))) + (read-debug-command value (assoc extras :debug-value (pr-short return)))) :quit (abort!)))) ;;; ## High-level functions @@ -238,7 +248,7 @@ (assoc ~(let [{:keys [code id file point]} *msg*] {:code code, :original-id id, :coor coor :file file, :point point}) - :debug-value (pr-str val#))))))) + :debug-value (pr-short val#))))))) ;;; Data readers (defn breakpoint-reader @@ -294,11 +304,13 @@ (defn- initialize "Initialize the channel used for debug-input requests." - [msg] + [{:keys [print-length print-level] :as msg}] (when-let [stored-message @debugger-message] (transport/send (:transport stored-message) (response-for stored-message :status :done))) ;; The above is just bureaucracy. The below is important. + (reset! @#'print-length print-length) + (reset! @#'print-level print-level) (reset! debugger-message msg)) (defn- instrumented-defs-reply diff --git a/test/clj/cider/nrepl/middleware/debug_test.clj b/test/clj/cider/nrepl/middleware/debug_test.clj index c15649cc8..abac87d43 100644 --- a/test/clj/cider/nrepl/middleware/debug_test.clj +++ b/test/clj/cider/nrepl/middleware/debug_test.clj @@ -169,3 +169,33 @@ (is (:cider-breakfunction (meta (read-string "#dbg [a b c]")))) (is (= (count (remove #(:cider-breakfunction (meta %)) (read-string "#dbg [a :b 10]"))) 2)))) + +(deftest pr-short + (reset! d/print-length 4) + (reset! d/print-level 2) + (is (< (count (d/pr-short [1 2 3 4 5 6 7 8 9 10])) + (count (pr-str [1 2 3 4 5 6 7 8 9 10])))) + (is (< (count (d/pr-short [[[1 2 3 4]]])) + (count (pr-str [[[1 2 3 4]]])))) + (is (= (d/pr-short [1 2 3 4]) + (pr-str [1 2 3 4])))) + +(deftest breakpoint + ;; Map merging + (with-redefs [d/read-debug-command (fn [v e] (assoc e :value v)) + d/debugger-message (atom [:fake])] + (binding [*msg* {:session (atom {#'d/*skip-breaks* false}) + :code :code, :id :id, :file :file, :point :point}] + (let [m (eval '(cider.nrepl.middleware.debug/breakpoint (inc 10) [6]))] + (are [k v] (= (k m) v) + :value 11 + :debug-value "11" + :coor [6] + :file :file + :point :point + :code :code + :original-id :id)) + ;; Locals capturing + (reset! @#'d/debugger-message nil) + (is (= (eval '(let [x 10] (cider.nrepl.middleware.debug/breakpoint cider.nrepl.middleware.debug/*locals* []))) + '{x 10})))))