@@ -26,8 +26,14 @@ defmodule Styler.Zipper do
26
26
import Kernel , except: [ node: 1 ]
27
27
28
28
@ type tree :: Macro . t ( )
29
+
30
+ @ opaque path :: % {
31
+ l: [ tree ] ,
32
+ ptree: zipper ,
33
+ r: [ tree ]
34
+ }
35
+
29
36
@ type zipper :: { tree , path | nil }
30
- @ type path :: { left :: [ tree ] , parent :: zipper , right :: [ tree ] }
31
37
@ type t :: zipper
32
38
@ type command :: :cont | :skip | :halt
33
39
@@ -85,7 +91,7 @@ defmodule Styler.Zipper do
85
91
def down ( zipper ) do
86
92
case children ( zipper ) do
87
93
[ ] -> nil
88
- [ first | rest ] -> { first , { [ ] , zipper , rest } }
94
+ [ first | rest ] -> { first , % { ptree: zipper , l: [ ] , r: rest } }
89
95
end
90
96
end
91
97
@@ -96,25 +102,26 @@ defmodule Styler.Zipper do
96
102
@ spec up ( zipper ) :: zipper | nil
97
103
def up ( { _ , nil } ) , do: nil
98
104
99
- def up ( { tree , { l , { parent , parent_meta } , r } } ) do
100
- children = Enum . reverse ( l , [ tree | r ] )
105
+ def up ( { tree , meta } ) do
106
+ children = Enum . reverse ( meta . l , [ tree | meta . r ] )
107
+ { parent , parent_meta } = meta . ptree
101
108
{ do_replace_children ( parent , children ) , parent_meta }
102
109
end
103
110
104
111
@ doc """
105
112
Returns the zipper of the left sibling of the node at this zipper, or nil.
106
113
"""
107
114
@ spec left ( zipper ) :: zipper | nil
108
- def left ( { tree , { [ ltree | l ] , p , r } } ) , do: { ltree , { l , p , [ tree | r ] } }
115
+ def left ( { tree , % { l: [ ltree | l ] , r: r } = meta } ) , do: { ltree , % { meta | l: l , r: [ tree | r ] } }
109
116
def left ( _ ) , do: nil
110
117
111
118
@ doc """
112
119
Returns the leftmost sibling of the node at this zipper, or itself.
113
120
"""
114
121
@ spec leftmost ( zipper ) :: zipper
115
- def leftmost ( { tree , { [ _ | _ ] = l , p , r } } ) do
116
- [ leftmost | r ] = Enum . reverse ( l , [ tree | r ] )
117
- { leftmost , { [ ] , p , r } }
122
+ def leftmost ( { tree , % { l: [ _ | _ ] = l } = meta } ) do
123
+ [ leftmost | r ] = Enum . reverse ( l , [ tree | meta . r ] )
124
+ { leftmost , % { meta | l: [ ] , r: r } }
118
125
end
119
126
120
127
def leftmost ( { _ , _ } = zipper ) , do: zipper
@@ -123,16 +130,16 @@ defmodule Styler.Zipper do
123
130
Returns the zipper of the right sibling of the node at this zipper, or nil.
124
131
"""
125
132
@ spec right ( zipper ) :: zipper | nil
126
- def right ( { tree , { l , p , [ rtree | r ] } } ) , do: { rtree , { [ tree | l ] , p , r } }
133
+ def right ( { tree , % { r: [ rtree | r ] } = meta } ) , do: { rtree , % { meta | r: r , l: [ tree | meta . l ] } }
127
134
def right ( _ ) , do: nil
128
135
129
136
@ doc """
130
137
Returns the rightmost sibling of the node at this zipper, or itself.
131
138
"""
132
139
@ spec rightmost ( zipper ) :: zipper
133
- def rightmost ( { tree , { l , p , [ _ | _ ] = r } } ) do
134
- [ rightmost | l ] = Enum . reverse ( r , [ tree | l ] )
135
- { rightmost , { l , p , [ ] } }
140
+ def rightmost ( { tree , % { r: [ _ | _ ] = r } = meta } ) do
141
+ [ rightmost | l ] = Enum . reverse ( r , [ tree | meta . l ] )
142
+ { rightmost , % { meta | l: l , r: [ ] } }
136
143
end
137
144
138
145
def rightmost ( { _ , _ } = zipper ) , do: zipper
@@ -156,8 +163,8 @@ defmodule Styler.Zipper do
156
163
"""
157
164
@ spec remove ( zipper ) :: zipper
158
165
def remove ( { _ , nil } ) , do: raise ( ArgumentError , message: "Cannot remove the top level node." )
159
- def remove ( { _ , { [ left | rest ] , p , r } } ) , do: prev_down ( { left , { rest , p , r } } )
160
- def remove ( { _ , { _ , { parent , parent_meta } , children } } ) , do: { do_replace_children ( parent , children ) , parent_meta }
166
+ def remove ( { _ , % { l: [ left | rest ] } = meta } ) , do: prev_down ( { left , % { meta | l: rest } } )
167
+ def remove ( { _ , % { ptree: { parent , parent_meta } , r: children } } ) , do: { do_replace_children ( parent , children ) , parent_meta }
161
168
162
169
@ doc """
163
170
Inserts the item as the left sibling of the node at this zipper, without
@@ -177,7 +184,7 @@ defmodule Styler.Zipper do
177
184
"""
178
185
@ spec prepend_siblings ( zipper , [ tree ] ) :: zipper
179
186
def prepend_siblings ( { node , nil } , siblings ) , do: { :__block__ , [ ] , siblings ++ [ node ] } |> zip ( ) |> down ( ) |> rightmost ( )
180
- def prepend_siblings ( { tree , { l , p , r } } , siblings ) , do: { tree , { Enum . reverse ( siblings , l ) , p , r } }
187
+ def prepend_siblings ( { tree , meta } , siblings ) , do: { tree , % { meta | l: Enum . reverse ( siblings , meta . l ) } }
181
188
182
189
@ doc """
183
190
Inserts the item as the right sibling of the node at this zipper, without
@@ -197,7 +204,7 @@ defmodule Styler.Zipper do
197
204
"""
198
205
@ spec insert_siblings ( zipper , [ tree ] ) :: zipper
199
206
def insert_siblings ( { node , nil } , siblings ) , do: { :__block__ , [ ] , [ node | siblings ] } |> zip ( ) |> down ( )
200
- def insert_siblings ( { tree , { l , p , r } } , siblings ) , do: { tree , { l , p , siblings ++ r } }
207
+ def insert_siblings ( { tree , meta } , siblings ) , do: { tree , % { meta | r: siblings ++ meta . r } }
201
208
202
209
@ doc """
203
210
Inserts the item as the leftmost child of the node at this zipper,
0 commit comments