Skip to content

Commit 8d6ff2f

Browse files
author
Yannick Scherer
committed
Added 'edit->', 'subzip' and 'prewalk'.
1 parent 303af09 commit 8d6ff2f

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

examples/rewrite_clj/cljx.clj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,7 @@
6464
(defn cljx-walk
6565
"Replace all occurences of profile reader macros."
6666
[root active-profiles]
67-
(loop [loc root]
68-
(if-let [mloc (z/find loc z/next cljx-macro?)]
69-
(recur (handle-reader-macro active-profiles mloc))
70-
loc)))
67+
(z/prewalk root cljx-macro? #(handle-reader-macro active-profiles %)))
7168

7269
;; ## Test
7370

src/rewrite_clj/zip.clj

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,39 @@
379379
(if (map? zloc)
380380
(-> zloc (append-child k) (append-child v))
381381
(throw (Exception. (str "not a valid index to assoc: " v))))))
382+
383+
;; ## Edit Scope
384+
385+
(defn subzip
386+
"Create zipper that only contains the given zipper location's node."
387+
[zloc]
388+
(when zloc
389+
(edn (z/node zloc))))
390+
391+
(defmacro edit->
392+
"Will pass arguments to `->`. Return value will be the state of the input node
393+
after all modifications have been performed. This means that the result is
394+
automatically 'zipped up' to represent the same location the macro was given."
395+
[zloc & body]
396+
`(let [zloc# ~zloc
397+
loc# (subzip zloc#)]
398+
(if-let [edit# (-> loc# ~@body)]
399+
(z/replace zloc# (z/root edit#))
400+
(throw (Exception. "Body of edit-> did not return value.")))))
401+
402+
;; ## Walk
403+
404+
(defn prewalk
405+
"Perform a depth-first pre-order traversal starting at the given zipper location
406+
and apply the given function to each child node. If a predicate `p?` is given,
407+
only apply the function to nodes matching it."
408+
([zloc f] (prewalk zloc (constantly true) f))
409+
([zloc p? f]
410+
(loop [loc (subzip zloc)]
411+
(if (z/end? loc)
412+
(z/replace zloc (z/root loc))
413+
(if-let [n0 (find loc next p?)]
414+
(if-let [n1 (f n0)]
415+
(recur (z/next n1))
416+
(recur (z/next n0)))
417+
(z/replace zloc (z/root loc)))))))

0 commit comments

Comments
 (0)