Skip to content

Commit 055d43b

Browse files
committed
Indent controls
1 parent 829b96e commit 055d43b

File tree

2 files changed

+89
-14
lines changed

2 files changed

+89
-14
lines changed

src/basilisp/pprint.lpy

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
;; TODO:
1717
;; - miser and fill newlines
18-
;; - indent controls
1918

2019
(declare simple-dispatch code-dispatch write-out)
2120

@@ -127,7 +126,9 @@
127126
;; Types ;;
128127
;;;;;;;;;;;
129128

130-
(deftype LogicalBlock [parent prefix per-line-prefix suffix ^:mutable indent ^:mutable force-nl?]
129+
;; `indent` may be changed later by an indent token, whereas `start-col` is fixed at
130+
;; the point the start block token is encountered in the stream.
131+
(deftype LogicalBlock [parent prefix per-line-prefix suffix ^:mutable indent ^:mutable start-col ^:mutable force-nl?]
131132
(__repr__ [self]
132133
(str [(python/id self) (python/repr parent) prefix suffix indent force-nl?])))
133134

@@ -143,7 +144,9 @@
143144
(__repr__ [self]
144145
data))
145146

146-
(deftype Indent [block relative-to offset start end])
147+
(deftype Indent [block relative-to offset start end]
148+
(__repr__ [self]
149+
(str [(python/id block) relative-to offset])))
147150

148151
(deftype Newline [block kind start end]
149152
(__repr__ [self]
@@ -217,6 +220,7 @@
217220
(defprotocol PrettyWriter
218221
(start-block [this prefix per-line-prefix suffix])
219222
(end-block [this])
223+
(pp-indent [this relative-to offset])
220224
(pp-newline [this kind]))
221225

222226
(defn get-pretty-writer
@@ -228,7 +232,7 @@
228232
([writer max-columns]
229233
(let [lock (threading/RLock)
230234
writer (get-column-writer writer max-columns)
231-
state (volatile! {:block (LogicalBlock nil nil nil nil 0 false)
235+
state (volatile! {:block (LogicalBlock nil nil nil nil 0 0 false)
232236
:buffer (queue)
233237
:pos 0})]
234238
(letfn [;; Private helpers can only be called while the lock is held
@@ -249,11 +253,12 @@
249253
(set! (.-force-nl? block) true)
250254
(recur (.-parent block))))))
251255

252-
;; Set the `indent` of the current logical block to match the current
253-
;; column position of the base writer.
254-
(set-block-indent! [block prefix]
256+
;; Set the `indent` and `start-col` of the current logical block to match
257+
;; the current column position of the base writer.
258+
(set-block-cols! [block prefix]
255259
(let [indent (+ (:col @writer) (count prefix))]
256-
(set! (.-indent block) indent)))
260+
(set! (.-indent block) indent)
261+
(set! (.-start-col block) indent)))
257262

258263
;; Return `true` if the given newline type should be emitted.
259264
(emit-nl? [token section]
@@ -281,10 +286,17 @@
281286
Newline (when (or (= (.-kind token) :mandatory)
282287
(.-force-nl? (.-block token)))
283288
(gen-nl token))
284-
StartBlock (let [block (.-block token)]
285-
(when-let [prefix (.-prefix block)]
286-
(set-block-indent! block prefix)
287-
prefix))
289+
Indent (let [block (.-block token)
290+
indent (+ (.-offset token)
291+
(case (.-relative-to token)
292+
:block (.-start-col block)
293+
:current (:col @writer)))]
294+
(set! (.-indent block) indent)
295+
nil)
296+
StartBlock (let [block (.-block token)
297+
prefix (.-prefix block)]
298+
(set-block-cols! block (or prefix ""))
299+
prefix)
288300
EndBlock (.-suffix (.-block token)))]
289301
(.write writer s))))
290302

@@ -370,7 +382,7 @@
370382
(start-block [self prefix per-line-prefix suffix]
371383
(with [_ lock]
372384
(let [current-block (:block @state)
373-
new-block (LogicalBlock current-block prefix per-line-prefix suffix 0 false)
385+
new-block (LogicalBlock current-block prefix per-line-prefix suffix 0 0 false)
374386
[old-pos new-pos] (update-pos prefix)
375387
start-block (StartBlock new-block old-pos new-pos)]
376388
(vswap! state #(-> %
@@ -389,6 +401,13 @@
389401
(add-to-buffer end-block)))
390402
nil)
391403

404+
(pp-indent [self relative-to offset]
405+
(with [_ lock]
406+
(let [{:keys [block pos]} @state
407+
indent (Indent block relative-to offset pos pos)]
408+
(add-to-buffer indent)))
409+
nil)
410+
392411
(pp-newline [self kind]
393412
(with [_ lock]
394413
(let [{:keys [block pos]} @state
@@ -436,6 +455,22 @@
436455
(do ~@body)
437456
(.write *out* "...")))))
438457

458+
(defn pprint-indent
459+
"Configure the indent of `offset` characters relative to an anchor at this point
460+
in the pretty print output.
461+
462+
``relative-to`` must be one of the following keywords:
463+
- ``:current``, meaning that the indent offset is relative to the current column
464+
when the indent token is encountered
465+
- ``:block``, meaning that the indent offset is relative to the starting column of
466+
the current logical block"
467+
[relative-to offset]
468+
(when-not (#{:block :current} relative-to)
469+
(throw
470+
(ex-info "relative-to must be one of: :block, :current"
471+
{:relative-to relative-to})))
472+
(pp-indent *out* relative-to offset))
473+
439474
(defn pprint-newline
440475
"Emit a newline to the output buffer.
441476

@@ -631,6 +666,8 @@
631666
(not (realized? obj))) :not-delivered
632667
:else @obj)]
633668
(pprint-logical-block :prefix prefix :suffix ">"
669+
(pprint-indent :block (- (- (count prefix) 2)))
670+
(pprint-newline :linear)
634671
(write-out contents))))
635672

636673
(alter-var-root #'*print-pprint-dispatch* (constantly simple-dispatch))

tests/basilisp/test_pprint.lpy

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,45 @@
211211
(let [v (volatile! nil)]
212212
(is (= ["Volatile" "nil"] (match-ideref v)))
213213
(vreset! v :not-nil)
214-
(is (= ["Volatile" ":not-nil"] (match-ideref v))))))
214+
(is (= ["Volatile" ":not-nil"] (match-ideref v)))))
215+
216+
(testing "long values"
217+
(let [v (volatile! (range 5))]
218+
(is (= ["Volatile" "(0 1 2 3 4)"] (match-ideref v)))
219+
(vreset! v (range 25))
220+
(is (= ["Volatile" "\n (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)"] (match-ideref v)))
221+
(vreset! v (range 30))
222+
(is (= ["Volatile" "
223+
(0
224+
1
225+
2
226+
3
227+
4
228+
5
229+
6
230+
7
231+
8
232+
9
233+
10
234+
11
235+
12
236+
13
237+
14
238+
15
239+
16
240+
17
241+
18
242+
19
243+
20
244+
21
245+
22
246+
23
247+
24
248+
25
249+
26
250+
27
251+
28
252+
29)"] (match-ideref v))))))
215253

216254
(deftest pprint-print-level-test
217255
(are [res plen expr] (= res (str/rtrim

0 commit comments

Comments
 (0)