Skip to content

Commit 524ca11

Browse files
committed
Simplify the zipper structure
1 parent 666ec15 commit 524ca11

File tree

2 files changed

+47
-51
lines changed

2 files changed

+47
-51
lines changed

src/rewrite_clj/zip/utils.clj

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,20 @@
44
;; ## Remove
55

66
(defn- update-in-path
7-
[{:keys [node path parent position] :as loc} k f]
8-
(let [v (get path k)]
9-
(if (seq v)
10-
(assoc loc
11-
:changed? true
12-
:node node
13-
:path (assoc path k (f v)))
14-
loc)))
7+
[{:keys [node path] :as loc} k f]
8+
(if-let [v (get loc k)]
9+
(assoc loc :changed? true k (f v))
10+
loc))
1511

1612
(defn remove-right
1713
"Remove right sibling of the current node (if there is one)."
1814
[loc]
19-
(update-in-path loc :r next))
15+
(update-in-path loc :right next))
2016

2117
(defn remove-left
2218
"Remove left sibling of the current node (if there is one)."
2319
[loc]
24-
(update-in-path loc :l pop))
20+
(update-in-path loc :left pop))
2521

2622
(defn remove-right-while
2723
"Remove elements to the right of the current zipper location as long as
@@ -50,19 +46,19 @@
5046
(defn remove-and-move-left
5147
"Remove current node and move left. If current node is at the leftmost
5248
location, returns `nil`."
53-
[{:keys [position parent] {:keys [l] :as path} :path :as loc}]
54-
(if (seq l)
49+
[{:keys [position left] :as loc}]
50+
(if (seq left)
5551
(assoc loc
5652
:changed? true
57-
:node (peek l)
58-
:path (update-in path [:l] pop))))
53+
:node (peek left)
54+
:left (pop left))))
5955

6056
(defn remove-and-move-right
6157
"Remove current node and move right. If current node is at the rightmost
6258
location, returns `nil`."
63-
[{:keys [position parent] {:keys [r] :as path} :path :as loc}]
64-
(if (seq r)
59+
[{:keys [position right] :as loc}]
60+
(if (seq right)
6561
(assoc loc
6662
:changed? true
67-
:node (first r)
68-
:path (update-in path [:r] next))))
63+
:node (first right)
64+
:right (next right))))

src/rewrite_clj/zip/zip.clj

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
{:node root
2323
:position [1 1]
2424
:parent nil
25-
:path nil})
25+
:left []
26+
:right '()})
2627

2728
(defn node
2829
"Returns the node at loc"
@@ -55,7 +56,7 @@
5556
(defn lefts
5657
"Returns a seq of the left siblings of this loc"
5758
[loc]
58-
(seq (:l (:path loc))))
59+
(seq (:left loc)))
5960

6061
(defn down
6162
"Returns the loc of the leftmost child of the node at this loc, or
@@ -68,21 +69,19 @@
6869
{:node c
6970
:position [row (+ col (node/leader-length node))]
7071
:parent loc
71-
:path {:l []
72-
:ppath path
73-
:r cnext}}))))
72+
:left []
73+
:right cnext}))))
7474

7575
(defn up
7676
"Returns the loc of the parent of the node at this loc, or nil if at
7777
the top"
7878
[loc]
79-
(let [{:keys [node parent position changed?] {:keys [l ppath r]} :path} loc]
79+
(let [{:keys [node parent left right changed?]} loc]
8080
(when parent
8181
(if changed?
8282
(assoc parent
8383
:changed? true
84-
:node (make-node loc (:node parent) (concat l (cons node r)))
85-
:path ppath)
84+
:node (make-node loc (:node parent) (concat left (cons node right))))
8685
parent))))
8786

8887
(defn root
@@ -98,11 +97,12 @@
9897
(defn right
9998
"Returns the loc of the right sibling of the node at this loc, or nil"
10099
[loc]
101-
(let [{:keys [node parent position] {l :l [r & rnext :as rs] :r :as path} :path} loc]
102-
(when (and path rs)
100+
(let [{:keys [node parent position left] [r & rnext :as right] :right} loc]
101+
(when (and parent right)
103102
(assoc loc
104103
:node r
105-
:path (assoc path :l (conj l node) :r rnext)
104+
:left (conj left node)
105+
:right rnext
106106
:position (node/+extent position (node/extent node))))))
107107

108108
(defn rightmost
@@ -115,43 +115,45 @@
115115
(defn left
116116
"Returns the loc of the left sibling of the node at this loc, or nil"
117117
[loc]
118-
(let [{:keys [node parent position] {:keys [l r] :as path} :path} loc]
119-
(when (and path (seq l))
118+
(let [{:keys [node parent left right]} loc]
119+
(when (and parent (seq left))
120120
(assoc loc
121-
:node (peek l)
122-
:path (assoc path :l (pop l) :r (cons node r))))))
121+
:node (peek left)
122+
:left (pop left)
123+
:right (cons node right)))))
123124

124125
(defn leftmost
125126
"Returns the loc of the leftmost sibling of the node at this loc, or self"
126127
[loc]
127-
(let [{:keys [node parent position] {:keys [l r] :as path} :path} loc]
128-
(if (and path (seq l))
128+
(let [{:keys [node parent left right]} loc]
129+
(if (and parent (seq left))
129130
(assoc loc
130-
:node (first l)
131-
:path (assoc path :l [] :r (concat (rest l) [node] r)))
131+
:node (first left)
132+
:left []
133+
:right (concat (rest left) [node] right))
132134
loc)))
133135

134136
(defn insert-left
135137
"Inserts the item as the left sibling of the node at this loc,
136138
without moving"
137139
[loc item]
138-
(let [{:keys [parent position] {:keys [l] :as path} :path} loc]
139-
(if (nil? path)
140+
(let [{:keys [parent left]} loc]
141+
(if-not parent
140142
(throw (new Exception "Insert at top"))
141143
(assoc loc
142144
:changed? true
143-
:path (assoc path :l (conj l item))))))
145+
:left (conj left item)))))
144146

145147
(defn insert-right
146148
"Inserts the item as the right sibling of the node at this loc,
147149
without moving"
148150
[loc item]
149-
(let [{:keys [node parent position] {:keys [r] :as path} :path} loc]
150-
(if (nil? path)
151+
(let [{:keys [node parent right]} loc]
152+
(if-not parent
151153
(throw (new Exception "Insert at top"))
152154
(assoc loc
153155
:changed? true
154-
:path (assoc path :r (cons item r))))))
156+
:right (cons item right)))))
155157

156158
(defn replace
157159
"Replaces the node at this loc, without moving"
@@ -210,19 +212,17 @@
210212
"Removes the node at loc, returning the loc that would have preceded
211213
it in a depth-first walk."
212214
[loc]
213-
(let [{:keys [node parent position] {:keys [l ppath r] :as path} :path} loc]
214-
(if (nil? path)
215+
(let [{:keys [node parent left right]} loc]
216+
(if-not parent
215217
(throw (new Exception "Remove at top"))
216-
(if (pos? (count l))
218+
(if (seq left)
217219
(loop [loc (assoc loc
218220
:changed? true
219-
:node (peek l)
220-
:path (assoc path :l (pop l)))]
221+
:node (peek left)
222+
:left (pop left))]
221223
(if-let [child (and (branch? loc) (down loc))]
222224
(recur (rightmost child))
223225
loc))
224226
(assoc parent
225227
:changed? true
226-
:node (make-node loc (:node parent) r)
227-
:path ppath
228-
:parent (:parent parent))))))
228+
:node (make-node loc (:node parent) right))))))

0 commit comments

Comments
 (0)