Skip to content

Commit 850985f

Browse files
committed
distinguish ~@ from ~(deref), don't unexpand reader macros if lossy
Use ~,@ as canonical form instead of ~ @ for emphasis.
1 parent a4cb207 commit 850985f

2 files changed

Lines changed: 45 additions & 5 deletions

File tree

src/fipp/clojure.cljc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,21 @@
126126

127127
;;; Format deref, quote, unquote, var
128128

129-
(defn pretty-quote [p [macro arg]]
130-
[:span (case (keyword (name macro))
131-
:deref "@", :quote "'", :unquote "~", :var "#'")
132-
(visit p arg)])
129+
(defn- deref? [arg]
130+
(and (seq? arg)
131+
(= 2 (count arg))
132+
(= 'clojure.core/deref (first arg))))
133+
134+
(defn pretty-quote [p [macro arg :as all]]
135+
(if-some [rm (when (= 2 (count all))
136+
(case macro
137+
clojure.core/deref "@"
138+
quote "'"
139+
clojure.core/unquote (if (deref? arg) "~," "~")
140+
var "#'"
141+
nil))]
142+
[:span rm (visit p arg)]
143+
(apply list-group (interpose " " (map #(visit p %) all)))))
133144

134145
;;; Format let, loop, and similar
135146

@@ -183,7 +194,7 @@
183194
pretty-ns '[ns]
184195
pretty-let '[binding doseq dotimes for if-let if-some let let* loop loop*
185196
when-first when-let when-some with-local-vars with-open with-redefs]
186-
pretty-quote '[deref quote unquote var]
197+
pretty-quote '[clojure.core/deref quote clojure.core/unquote var]
187198
pretty-type '[deftype defrecord]
188199
pretty-reify '[reify]}))
189200

test/fipp/clojure_test.cljc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,33 @@
1818
#?(:clj "[#'clojure.core/inc ^{:y 1} x]"
1919
:cljs "[#'cljs.core/inc ^{:y 1} x]")))))
2020

21+
(deftest lossy-reader-unexpansion-test
22+
(is (= (clean (with-out-str (pprint '(let [deref foo] (deref foo)))))
23+
"(let [deref foo] (deref foo))"))
24+
(is (= (clean (with-out-str (pprint '~(deref foo))))
25+
"~(deref foo)"))
26+
(is (= (clean (with-out-str (pprint '(clojure.core/deref))))
27+
"(clojure.core/deref)"))
28+
(is (= (clean (with-out-str (pprint '(clojure.core/deref 1 2 3))))
29+
"(clojure.core/deref 1 2 3)"))
30+
(is (= (clean (with-out-str (pprint '(clojure.core/unquote))))
31+
"(clojure.core/unquote)"))
32+
(is (= (clean (with-out-str (pprint '(clojure.core/unquote 1 2 3))))
33+
"(clojure.core/unquote 1 2 3)"))
34+
(is (= (clean (with-out-str (pprint '(unquote (deref foo)))))
35+
"(unquote (deref foo))")))
36+
37+
(deftest quote-deref-test
38+
(testing "~(deref) is not ~@"
39+
(is (= (clean (with-out-str (pprint '(clojure.core/unquote (clojure.core/deref foo)))))
40+
"~,@foo"))
41+
(is (= (clean (with-out-str (pprint '~(clojure.core/deref foo))))
42+
"~,@foo"))
43+
(is (= (clean (with-out-str (pprint '~(clojure.core/deref foo))))
44+
"~,@foo"))
45+
(is (= (clean (with-out-str (pprint '~ @foo)))
46+
"~,@foo"))
47+
(is (= (clean (with-out-str (pprint '~,@foo)))
48+
"~,@foo"))))
49+
2150
;;TODO lots more tests

0 commit comments

Comments
 (0)