Skip to content

Commit 572e96b

Browse files
author
Yannick Scherer
committed
Taking care with comments in 'remove'.
1 parent 7862ae0 commit 572e96b

File tree

4 files changed

+61
-29
lines changed

4 files changed

+61
-29
lines changed

src/rewrite_clj/zip/core.clj

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77

88
;; ## Zipper
99

10-
(declare skip-whitespace
11-
skip-whitespace-left)
10+
(declare skip-whitespace)
1211

1312
(defn- z-branch?
1413
[node]
@@ -62,8 +61,19 @@
6261
(when zloc
6362
(prn/estimate-length (z/node zloc))))
6463

64+
(defn comment?
65+
"Check if the node at the current zipper location is a comment."
66+
[zloc]
67+
(= (tag zloc) :comment))
68+
6569
(defn whitespace?
66-
"Check if the node at the current zipper location is whitespace or comment."
70+
"Check if the node at the current zipper location is whitespace (including linebreak)."
71+
[zloc]
72+
(contains? #{:whitespace :newline} (tag zloc)))
73+
74+
(defn whitespace-or-comment?
75+
"Check if the node at the current zipper location is whitespace (including linebreak)
76+
or comment."
6777
[zloc]
6878
(contains? #{:comment :whitespace :newline} (tag zloc)))
6979

@@ -72,16 +82,6 @@
7282
[zloc]
7383
(= (tag zloc) :newline))
7484

75-
(defn leftmost?
76-
"Check if the given zipper is at the leftmost non-whitespace position."
77-
[zloc]
78-
(nil? (skip-whitespace-left (z/left zloc))))
79-
80-
(defn rightmost?
81-
"Check if the given zipper is at the rightmost non-whitespace position."
82-
[zloc]
83-
(nil? (skip-whitespace (z/right zloc))))
84-
8585
;; ## Skip
8686

8787
(defn skip
@@ -99,13 +99,23 @@
9999
"Apply movement function (default: `clojure.z/right`) until a non-whitespace/non-comment
100100
element is reached."
101101
([zloc] (skip-whitespace z/right zloc))
102-
([f zloc] (skip f whitespace? zloc)))
102+
([f zloc] (skip f whitespace-or-comment? zloc)))
103103

104104
(defn skip-whitespace-left
105105
"Move left until a non-whitespace/non-comment element is reached."
106106
[zloc]
107107
(skip-whitespace z/left zloc))
108108

109+
(defn leftmost?
110+
"Check if the given zipper is at the leftmost non-whitespace position."
111+
[zloc]
112+
(nil? (skip-whitespace-left (z/left zloc))))
113+
114+
(defn rightmost?
115+
"Check if the given zipper is at the rightmost non-whitespace position."
116+
[zloc]
117+
(nil? (skip-whitespace (z/right zloc))))
118+
109119
;; ## Whitespace Nodes
110120

111121
(defn prepend-space

src/rewrite_clj/zip/edit.clj

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,12 @@
6767
(defn- remove-trailing-space
6868
"Remove all whitespace following a given node."
6969
[zloc]
70-
(loop [zloc zloc]
71-
(if-let [rloc (z/right zloc)]
72-
(if (zc/whitespace? rloc)
73-
(recur (zu/remove-right zloc))
74-
zloc)
75-
zloc)))
70+
(zu/remove-right-while zloc zc/whitespace?))
7671

7772
(defn- remove-preceding-space
73+
"Remove all whitespace preceding a given node."
7874
[zloc]
79-
(loop [zloc zloc]
80-
(if-let [lloc (z/left zloc)]
81-
(if (zc/whitespace? lloc)
82-
(recur (zu/remove-left zloc))
83-
zloc)
84-
zloc)))
75+
(zu/remove-left-while zloc zc/whitespace?))
8576

8677
(defn remove
8778
"Remove value at the given zipper location. Returns the first non-whitespace node
@@ -95,9 +86,10 @@
9586
[1 [2 3] 4] => [1 [2 3]]
9687
[1 [2 3] 4] => [[2 3] 4]
9788
98-
If a node is located rightmost, both preceding and trailing spaces are removed, otherwise only
99-
trailing spaces are touched. This means that a following element (no matter whether on the
100-
same line or not) will end up in the same position (line/column) as the removed one."
89+
If a node is located rightmost, both preceding and trailing spaces are removed, otherwise only
90+
trailing spaces are touched. This means that a following element (no matter whether on the
91+
same line or not) will end up in the same position (line/column) as the removed one,
92+
_unless_ a comment lies between the original node and the neighbour."
10193
[zloc]
10294
(let [zloc (if (zc/rightmost? zloc) (remove-preceding-space zloc) zloc)
10395
zloc (-> zloc remove-trailing-space z/remove)]

src/rewrite_clj/zip/utils.clj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,25 @@
5555
(.make-node zloc)
5656
(first (.r path))
5757
(assoc path :r (clojure.core/next (.r path)) :changed? true)))))
58+
59+
(defn remove-right-while
60+
"Remove elements to the right of the current zipper location as long as
61+
the given predicate matches."
62+
[zloc p?]
63+
(loop [zloc zloc]
64+
(if-let [rloc (z/right zloc)]
65+
(if (p? rloc)
66+
(recur (remove-right zloc))
67+
zloc)
68+
zloc)))
69+
70+
(defn remove-left-while
71+
"Remove elements to the left of the current zipper location as long as
72+
the given predicate matches."
73+
[zloc p?]
74+
(loop [zloc zloc]
75+
(if-let [lloc (z/left zloc)]
76+
(if (p? lloc)
77+
(recur (remove-left zloc))
78+
zloc)
79+
zloc)))

test/rewrite_clj/zip_test.clj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@
111111
(let [r0 (-> root z/down z/remove)]
112112
(z/sexpr r0) => [2]
113113
(z/->root-string r0) => "[2]"))
114+
(let [root (z/of-string "[1 ;;comment\n 2]")]
115+
(z/sexpr root) => [1 2]
116+
(let [r0 (-> root z/down z/remove)]
117+
(z/sexpr r0) => [2]
118+
(z/->root-string r0) => "[;;comment\n 2]")
119+
(let [r0 (-> root z/down z/right z/remove)]
120+
(z/sexpr (z/up r0)) => [1]
121+
(z/->root-string r0) => "[1 ;;comment\n]"))
114122
(let [root (z/of-string "[1 [2 3] 4]")]
115123
(z/sexpr root) => [1 [2 3] 4]
116124
(let [r0 (-> root z/down z/remove*)]

0 commit comments

Comments
 (0)