Skip to content

Commit fe75c7c

Browse files
[print] Add support for compact qualified keywords
1 parent d7f0617 commit fe75c7c

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

src/orchard/print.clj

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
{:author "Oleksandr Yakushev"
99
:added "0.24"}
1010
(:refer-clojure :exclude [print print-str])
11+
(:require [clojure.string :as str])
1112
(:import
1213
(clojure.core Eduction)
1314
(clojure.lang AFunction Compiler IDeref IPending IPersistentMap MultiFn
@@ -16,8 +17,7 @@
1617
(java.io Writer)
1718
(java.util List Map Map$Entry)
1819
(mx.cider.orchard TruncatingStringWriter
19-
TruncatingStringWriter$TotalLimitExceeded))
20-
(:require [clojure.string :as str]))
20+
TruncatingStringWriter$TotalLimitExceeded)))
2121

2222
(defmulti print
2323
(fn [x _]
@@ -28,8 +28,8 @@
2828
(instance? String x) :string
2929
(instance? Double x) :double
3030
(instance? Number x) :scalar
31-
(instance? Keyword x) :scalar
3231
(instance? Symbol x) :scalar
32+
(instance? Keyword x) :keyword
3333
(instance? IRecord x) :record
3434
(instance? Map x) :map
3535
(instance? IPersistentVector x) :vector
@@ -52,6 +52,13 @@
5252
"When displaying collection diffs, whether to hide matching values."
5353
false)
5454

55+
(def ^:dynamic *pov-ns*
56+
"The \"point-of-view namespace\" for the printer. When bound to a namespace
57+
object, use this namespace data to shorten qualified keywords:
58+
- print `::foo` instead of `:pov.ns/foo`
59+
- print `::alias/foo` instead of `:ns.aliases.in.pov.ns/foo`"
60+
nil)
61+
5562
(defn- print-coll-item
5663
"Print an item in the context of a collection. When printing a map, don't print
5764
`[]` characters around map entries."
@@ -114,6 +121,22 @@
114121
(defmethod print :scalar [^Object x, ^Writer w]
115122
(.write w (.toString x)))
116123

124+
(defmethod print :keyword [^Keyword kw, ^Writer w]
125+
(if-some [kw-ns (and *pov-ns* (namespace kw))]
126+
(if (= kw-ns (name (ns-name *pov-ns*)))
127+
(do (.write w "::")
128+
(.write w (name kw)))
129+
(if-some [matched-alias (some (fn [[alias ns]]
130+
(when (= kw-ns (name (ns-name ns)))
131+
alias))
132+
(ns-aliases *pov-ns*))]
133+
(do (.write w "::")
134+
(.write w (name matched-alias))
135+
(.write w "/")
136+
(.write w (name kw)))
137+
(.write w (.toString kw))))
138+
(.write w (.toString kw))))
139+
117140
(defmethod print :double [x, ^Writer w]
118141
(cond (= Double/POSITIVE_INFINITY x) (.write w "##Inf")
119142
(= Double/NEGATIVE_INFINITY x) (.write w "##-Inf")

test/orchard/print_test.clj

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,29 @@
156156
(deftest print-custom-print-method
157157
(is (= "hello"
158158
(sut/print-str (with-meta (->TestRecord 1 2 3 4) {:type ::custom-rec})))))
159+
160+
(deftest qualified-keywords-compaction
161+
(are [kw repr] (= repr (sut/print-str kw))
162+
:foo ":foo"
163+
:foo/bar ":foo/bar"
164+
::foo ":orchard.print-test/foo"
165+
::t/foo ":clojure.test/foo")
166+
(is (= ":foo" (sut/print-str :foo)))
167+
(is (= ":foo/bar" (sut/print-str :foo/bar)))
168+
(is (= ":orchard.print-test/foo" (sut/print-str ::foo)))
169+
(is (= ":clojure.test/foo" (sut/print-str :clojure.test/foo)))
170+
171+
(testing "binding *pov-ns* enables keyword compaction"
172+
(binding [sut/*pov-ns* (find-ns 'orchard.print-test)]
173+
(are [kw repr] (= repr (sut/print-str kw))
174+
:foo ":foo"
175+
:foo/bar ":foo/bar"
176+
::foo "::foo"
177+
::t/foo "::t/foo"
178+
:clojure.set/foo ":clojure.set/foo")))
179+
180+
(testing "from other pov NS the printing will be different"
181+
(binding [sut/*pov-ns* (create-ns 'throwaway)]
182+
(are [kw repr] (= repr (sut/print-str kw))
183+
::foo ":orchard.print-test/foo"
184+
::t/foo ":clojure.test/foo"))))

0 commit comments

Comments
 (0)