|
21 | 21 | [root]
|
22 | 22 | {:node root
|
23 | 23 | :position [1 1]
|
| 24 | + :parent nil |
24 | 25 | :path nil})
|
25 | 26 |
|
26 | 27 | (defn node
|
|
66 | 67 | (when cs
|
67 | 68 | {:node c
|
68 | 69 | :position [row (+ col (node/leader-length node))]
|
| 70 | + :parent loc |
69 | 71 | :path {:l []
|
70 | 72 | :pnodes (if path (conj (:pnodes path) node) [node])
|
71 | 73 | :ppath path
|
|
75 | 77 | "Returns the loc of the parent of the node at this loc, or nil if at
|
76 | 78 | the top"
|
77 | 79 | [loc]
|
78 |
| - (let [{:keys [node position] {:keys [l ppath pnodes r changed?]} :path} loc] |
79 |
| - (when pnodes |
80 |
| - (let [pnode (peek pnodes)] |
81 |
| - (if changed? |
82 |
| - {:node (make-node loc pnode (concat l (cons node r))) |
83 |
| - :path (and ppath (assoc ppath :changed? true)) |
84 |
| - :position position} |
85 |
| - {:node pnode |
86 |
| - :path ppath |
87 |
| - :position position}))))) |
| 80 | + (let [{:keys [node parent position] {:keys [l ppath pnodes r changed?]} :path} loc] |
| 81 | + (when parent |
| 82 | + (if changed? |
| 83 | + {:node (make-node loc (peek pnodes) (concat l (cons node r))) |
| 84 | + :path (and ppath (assoc ppath :changed? true)) |
| 85 | + :parent (:parent parent) |
| 86 | + :position position} |
| 87 | + parent)))) |
88 | 88 |
|
89 | 89 | (defn root
|
90 | 90 | "zips all the way up and returns the root node, reflecting any
|
|
100 | 100 | (defn right
|
101 | 101 | "Returns the loc of the right sibling of the node at this loc, or nil"
|
102 | 102 | [loc]
|
103 |
| - (let [{:keys [node position] {l :l [r & rnext :as rs] :r :as path} :path} loc] |
| 103 | + (let [{:keys [node parent position] {l :l [r & rnext :as rs] :r :as path} :path} loc] |
104 | 104 | (when (and path rs)
|
105 | 105 | {:node r
|
106 | 106 | :path (assoc path :l (conj l node) :r rnext)
|
| 107 | + :parent parent |
107 | 108 | :position (node/+extent position (node/extent node))})))
|
108 | 109 |
|
109 | 110 | (defn rightmost
|
|
116 | 117 | (defn left
|
117 | 118 | "Returns the loc of the left sibling of the node at this loc, or nil"
|
118 | 119 | [loc]
|
119 |
| - (let [{:keys [node position] {:keys [l r] :as path} :path} loc] |
| 120 | + (let [{:keys [node parent position] {:keys [l r] :as path} :path} loc] |
120 | 121 | (when (and path (seq l))
|
121 | 122 | {:node (peek l)
|
122 | 123 | :path (assoc path :l (pop l) :r (cons node r))
|
| 124 | + :parent parent |
123 | 125 | :position position})))
|
124 | 126 |
|
125 | 127 | (defn leftmost
|
126 | 128 | "Returns the loc of the leftmost sibling of the node at this loc, or self"
|
127 | 129 | [loc]
|
128 |
| - (let [{:keys [node position] {:keys [l r] :as path} :path} loc] |
| 130 | + (let [{:keys [node parent position] {:keys [l r] :as path} :path} loc] |
129 | 131 | (if (and path (seq l))
|
130 | 132 | {:node (first l)
|
131 | 133 | :path (assoc path :l [] :r (concat (rest l) [node] r))
|
| 134 | + :parent parent |
132 | 135 | :position position}
|
133 | 136 | loc)))
|
134 | 137 |
|
135 | 138 | (defn insert-left
|
136 | 139 | "Inserts the item as the left sibling of the node at this loc,
|
137 | 140 | without moving"
|
138 | 141 | [loc item]
|
139 |
| - (let [{:keys [node position] {:keys [l] :as path} :path} loc] |
| 142 | + (let [{:keys [node parent position] {:keys [l] :as path} :path} loc] |
140 | 143 | (if (nil? path)
|
141 | 144 | (throw (new Exception "Insert at top"))
|
142 | 145 | {:node node
|
143 | 146 | :path (assoc path :l (conj l item) :changed? true)
|
| 147 | + :parent parent |
144 | 148 | :position position})))
|
145 | 149 |
|
146 | 150 | (defn insert-right
|
147 | 151 | "Inserts the item as the right sibling of the node at this loc,
|
148 | 152 | without moving"
|
149 | 153 | [loc item]
|
150 |
| - (let [{:keys [node position] {:keys [r] :as path} :path} loc] |
| 154 | + (let [{:keys [node parent position] {:keys [r] :as path} :path} loc] |
151 | 155 | (if (nil? path)
|
152 | 156 | (throw (new Exception "Insert at top"))
|
153 | 157 | {:node node
|
154 | 158 | :path (assoc path :r (cons item r) :changed? true)
|
| 159 | + :parent parent |
155 | 160 | :position position})))
|
156 | 161 |
|
157 | 162 | (defn replace
|
|
214 | 219 | "Removes the node at loc, returning the loc that would have preceded
|
215 | 220 | it in a depth-first walk."
|
216 | 221 | [loc]
|
217 |
| - (let [{:keys [node position] {:keys [l ppath pnodes r] :as path} :path} loc] |
| 222 | + (let [{:keys [node parent position] {:keys [l ppath pnodes r] :as path} :path} loc] |
218 | 223 | (if (nil? path)
|
219 | 224 | (throw (new Exception "Remove at top"))
|
220 | 225 | (if (pos? (count l))
|
221 | 226 | (loop [loc {:node (peek l)
|
222 | 227 | :path (assoc path :l (pop l) :changed? true)
|
| 228 | + :parent parent |
223 | 229 | :position position}]
|
224 | 230 | (if-let [child (and (branch? loc) (down loc))]
|
225 | 231 | (recur (rightmost child))
|
226 | 232 | loc))
|
227 | 233 | {:node (make-node loc (peek pnodes) r)
|
228 | 234 | :path (and ppath (assoc ppath :changed? true))
|
| 235 | + :parent (:parent parent) |
229 | 236 | :position position}))))
|
0 commit comments