-
Notifications
You must be signed in to change notification settings - Fork 19
/
dbg.clj
134 lines (119 loc) · 5.3 KB
/
dbg.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
(ns debux.dbg
(:require [debux.common.util :as ut]))
(defmacro dbg-base
[form locals {:keys [level condition ns line msg n tap-output] :as opts} body]
`(let [condition# ~condition]
(if (and (>= (or ~level 0) ut/*debug-level*)
(or ~(not (contains? opts :condition))
condition#))
(binding [ut/*indent-level* (inc ut/*indent-level*)]
(let [src-info# (str (ut/src-info ~ns ~line))
title# (str "dbg: "
(ut/truncate (pr-str '~(ut/remove-dbg-symbols form)))
(and ~msg (str " <" ~msg ">"))
" =>")
locals# ~locals]
(ut/insert-blank-line)
(ut/print-title-with-indent src-info# title#)
(when ~(:locals opts)
(ut/pprint-locals-with-indent locals#)
(ut/insert-blank-line))
(binding [*print-length* (or ~n (:print-length @ut/config*))]
~body) ))
~form) ))
(defmacro dbg->
[[_ & subforms :as form] locals opts]
`(dbg-base ~form ~locals ~opts
(-> ~@(mapcat (fn [subform] [subform `(ut/spy-first '~subform)])
subforms))))
(defmacro dbg->>
[[_ & subforms :as form] locals opts]
`(dbg-base ~form ~locals ~opts
(->> ~@(mapcat (fn [subform] [subform `(ut/spy-last '~subform)])
subforms)) ))
(defmacro dbg-some->
[[_ first-form & subforms :as form] locals opts]
`(dbg-base ~form ~locals ~opts
(some-> (ut/spy ~first-form)
~@(map (fn [subform] `(ut/spy-first2 ~subform))
subforms) )))
(defmacro dbg-some->>
[[_ first-form & subforms :as form] locals opts]
`(dbg-base ~form ~locals ~opts
(some->> (ut/spy ~first-form)
~@(map (fn [subform] `(ut/spy-last2 ~subform))
subforms) )))
(defmacro dbg-cond->
[[_ first-form & subforms :as form] locals opts]
`(dbg-base ~form ~locals ~opts
(cond-> (ut/spy ~first-form)
~@(mapcat (fn [[condition subform]]
[`(ut/spy ~condition) `(ut/spy-first2 ~subform)])
(partition 2 subforms) ))))
(defmacro dbg-cond->>
[[_ first-form & subforms :as form] locals opts]
`(dbg-base ~form ~locals ~opts
(cond->> (ut/spy ~first-form)
~@(mapcat (fn [[condition subform]]
[`(ut/spy ~condition) `(ut/spy-last2 ~subform)])
(partition 2 subforms)))))
(defmacro dbg-comp
[[_ & subforms :as form] locals opts]
`(dbg-base ~form ~locals ~opts
(comp ~@(map (fn [subform] `(ut/spy-comp '~subform ~subform ~opts))
subforms) )))
(defmacro dbg-let
[[_ bindings & subforms :as form] locals opts]
`(dbg-base ~form ~locals ~opts
(let ~(->> (partition 2 bindings)
(mapcat (fn [[sym value :as binding]]
[sym value
'_ `(ut/spy-first ~(if (coll? sym)
(ut/replace-& sym)
sym)
'~sym
~opts)] ))
vec)
(let [result# (do ~@subforms)]
(binding [ut/*indent-level* (dec ut/*indent-level*)]
(ut/pprint-result-with-indent result#)
result#)))))
(defmacro dbg-others
[form locals opts]
`(dbg-base ~form ~locals ~opts
(let [result# ~form]
(if-let [print# ~(:print opts)]
(ut/pprint-result-with-indent (print# result#))
(ut/pprint-result-with-indent result#))
result#) ))
(def dbg-macro-types*
(atom {:-> '#{clojure.core/-> cljs.core/->}
:->> '#{clojure.core/->> cljs.core/->>}
:some-> '#{clojure.core/some-> cljs.core/some->}
:some->> '#{clojure.core/some->> cljs.core/some->>}
:cond-> '#{clojure.core/cond-> cljs.core/cond->}
:cond->> '#{clojure.core/cond->> cljs.core/cond->>}
:comp '#{clojure.core/comp cljs.core/comp}
:let '#{clojure.core/let clojure.core/binding clojure.core/dotimes
clojure.core/when-first clojure.core/when-let clojure.core/when-some
clojure.core/with-in-str clojure.core/with-local-vars clojure.core/with-open
clojure.core/with-out-str clojure.core/with-redefs
cljs.core/let cljs.core/binding cljs.core/dotimes
cljs.core/when-first cljs.core/when-let cljs.core/when-some
cljs.core/with-out-str cljs.core/with-redefs}}))
(defmacro dbg
[form locals & [{:as opts}]]
(if (or (not (list? form))
(:final opts))
`(dbg-others ~form ~locals ~opts)
(let [ns-sym (ut/ns-symbol (first form) &env)]
(condp get ns-sym
(:-> @dbg-macro-types*) `(dbg-> ~form ~locals ~opts)
(:->> @dbg-macro-types*) `(dbg->> ~form ~locals ~opts)
(:some-> @dbg-macro-types*) `(dbg-some-> ~form ~locals ~opts)
(:some->> @dbg-macro-types*) `(dbg-some->> ~form ~locals ~opts)
(:cond-> @dbg-macro-types*) `(dbg-cond-> ~form ~locals ~opts)
(:cond->> @dbg-macro-types*) `(dbg-cond->> ~form ~locals ~opts)
(:comp @dbg-macro-types*) `(dbg-comp ~form ~locals ~opts)
(:let @dbg-macro-types*) `(dbg-let ~form ~locals ~opts)
`(dbg-others ~form ~locals ~opts)))))