Skip to content

Commit 401d10d

Browse files
author
Yannick Scherer
committed
Merge pull request #41 from eraserhd/position_in_zipper
track position in zipper implementation.
2 parents 68ce59f + f6efed3 commit 401d10d

33 files changed

+743
-86
lines changed

src/rewrite_clj/node.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
child-sexprs
2929
concat-strings
3030
inner?
31+
leader-length
3132
length
3233
printable-only?
3334
replace-children

src/rewrite_clj/node/fn.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
children)
7979
(replace-children [this children']
8080
(assoc this :children children'))
81+
(leader-length [_]
82+
2)
8183

8284
Object
8385
(toString [this]

src/rewrite_clj/node/forms.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
children)
2727
(replace-children [this children']
2828
(assoc this :children children'))
29+
(leader-length [_]
30+
0)
2931

3032
Object
3133
(toString [this]

src/rewrite_clj/node/meta.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
(replace-children [this children']
2626
(node/assert-sexpr-count children' 2)
2727
(assoc this :children children'))
28+
(leader-length [_]
29+
(count prefix))
2830

2931
Object
3032
(toString [this]

src/rewrite_clj/node/protocols.clj

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,18 @@
5555
(children [_]
5656
"Get child nodes.")
5757
(replace-children [_ children]
58-
"Replace the node's children."))
58+
"Replace the node's children.")
59+
(leader-length [_]
60+
"How many characters appear before children?"))
5961

6062
(extend-protocol InnerNode
6163
Object
6264
(inner? [_] false)
6365
(children [_]
6466
(throw (UnsupportedOperationException.)))
6567
(replace-children [_ _]
68+
(throw (UnsupportedOperationException.)))
69+
(leader-length [_]
6670
(throw (UnsupportedOperationException.))))
6771

6872
(defn child-sexprs
@@ -113,3 +117,39 @@
113117
(defn ^:no-doc assert-single-sexpr
114118
[nodes]
115119
(assert-sexpr-count nodes 1))
120+
121+
(defn ^:no-doc extent
122+
"A node's extent is how far it moves the \"cursor\".
123+
124+
Rows are simple - if we have x newlines in the string representation, we
125+
will always move the \"cursor\" x rows.
126+
127+
Columns are strange. If we have *any* newlines at all in the textual
128+
representation of a node, following nodes' column positions are not
129+
affected by our startting column position at all. So the second number
130+
in the pair we return is interpreted as a relative column adjustment
131+
when the first number in the pair (rows) is zero, and as an absolute
132+
column position when rows is non-zero."
133+
[node]
134+
(let [{:keys [row col next-row next-col]} (meta node)]
135+
(if (and row col next-row next-col)
136+
[(- next-row row)
137+
(if (= row next-row row)
138+
(- next-col col)
139+
next-col)]
140+
(let [s (string node)
141+
rows (->> s (filter (partial = \newline)) count)
142+
cols (if (zero? rows)
143+
(count s)
144+
(->> s
145+
reverse
146+
(take-while (complement (partial = \newline)))
147+
count
148+
inc))]
149+
[rows cols]))))
150+
151+
(defn ^:no-doc +extent
152+
[[row col] [row-extent col-extent]]
153+
[(+ row row-extent)
154+
(cond-> col-extent (zero? row-extent) (+ col))])
155+

src/rewrite_clj/node/quote.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
(replace-children [this children']
2121
(node/assert-single-sexpr children')
2222
(assoc this :children children'))
23+
(leader-length [_]
24+
(count prefix))
2325

2426
Object
2527
(toString [this]

src/rewrite_clj/node/reader_macro.clj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
(when sexpr-count
3232
(node/assert-sexpr-count children' sexpr-count))
3333
(assoc this :children children'))
34+
(leader-length [_]
35+
(inc (count prefix)))
3436

3537
Object
3638
(toString [this]
@@ -55,6 +57,8 @@
5557
(replace-children [this children']
5658
(node/assert-sexpr-count children' 2)
5759
(assoc this :children children'))
60+
(leader-length [_]
61+
1)
5862

5963
Object
6064
(toString [this]
@@ -79,6 +83,8 @@
7983
(replace-children [this children']
8084
(node/assert-sexpr-count children' 1)
8185
(assoc this :children children'))
86+
(leader-length [_]
87+
1)
8288

8389
Object
8490
(toString [this]

src/rewrite_clj/node/seq.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
children)
2828
(replace-children [this children']
2929
(assoc this :children children'))
30+
(leader-length [_]
31+
(dec wrap-length))
3032

3133
Object
3234
(toString [this]

src/rewrite_clj/node/uneval.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
(replace-children [this children']
2121
(node/assert-single-sexpr children')
2222
(assoc this :children children'))
23+
(leader-length [_]
24+
2)
2325

2426
Object
2527
(toString [this]

src/rewrite_clj/zip.clj

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
[parser :as p]
1818
[potemkin :refer [import-vars]]
1919
[node :as node]]
20-
[clojure.zip :as z]))
20+
[rewrite-clj.zip.zip :as z]))
2121

2222
;; ## API Facade
2323

2424
(import-vars
25-
[clojure.zip
26-
node root]
25+
[rewrite-clj.zip.zip
26+
node position root]
2727

2828
[rewrite-clj.zip.base
2929
child-sexprs
@@ -92,17 +92,19 @@
9292
:arglists `(quote ~arglists)})]
9393
`(def ~sym ~base)))
9494

95-
(defbase right* clojure.zip/right)
96-
(defbase left* clojure.zip/left)
97-
(defbase up* clojure.zip/up)
98-
(defbase down* clojure.zip/down)
99-
(defbase next* clojure.zip/next)
100-
(defbase prev* clojure.zip/prev)
101-
(defbase rightmost* clojure.zip/rightmost)
102-
(defbase leftmost* clojure.zip/leftmost)
103-
(defbase replace* clojure.zip/replace)
104-
(defbase edit* clojure.zip/edit)
105-
(defbase remove* clojure.zip/remove)
95+
(defbase right* rewrite-clj.zip.zip/right)
96+
(defbase left* rewrite-clj.zip.zip/left)
97+
(defbase up* rewrite-clj.zip.zip/up)
98+
(defbase down* rewrite-clj.zip.zip/down)
99+
(defbase next* rewrite-clj.zip.zip/next)
100+
(defbase prev* rewrite-clj.zip.zip/prev)
101+
(defbase rightmost* rewrite-clj.zip.zip/rightmost)
102+
(defbase leftmost* rewrite-clj.zip.zip/leftmost)
103+
(defbase replace* rewrite-clj.zip.zip/replace)
104+
(defbase edit* rewrite-clj.zip.zip/edit)
105+
(defbase remove* rewrite-clj.zip.zip/remove)
106+
(defbase insert-left* rewrite-clj.zip.zip/insert-left)
107+
(defbase insert-right* rewrite-clj.zip.zip/insert-right)
106108

107109
;; ## DEPRECATED
108110

0 commit comments

Comments
 (0)