diff options
author | Federico Igne <undyamon@disroot.org> | 2024-01-22 23:44:14 +0100 |
---|---|---|
committer | Federico Igne <undyamon@disroot.org> | 2024-01-22 23:44:14 +0100 |
commit | 0b2c183dbf275fbca3f9e0522cc583f85edccab5 (patch) | |
tree | 32bcc85dbb28425792c66edf7890cba3ccd46f5b | |
parent | 43bf616d8e58adf393762b13663cbff5ffb84ce3 (diff) | |
download | sandy-0b2c183dbf275fbca3f9e0522cc583f85edccab5.tar.gz sandy-0b2c183dbf275fbca3f9e0522cc583f85edccab5.zip |
refactor: naming convention in zipper
Unless specified otherwise:
- "before" and "left" mean "before the cursor";
- "right" mean "after (and including) the cursor";
- "after" mean "after (i.e., excluding) the cursor".
-rw-r--r-- | lib/zipper.ml | 96 | ||||
-rw-r--r-- | lib/zipper.mli | 125 |
2 files changed, 112 insertions, 109 deletions
diff --git a/lib/zipper.ml b/lib/zipper.ml index 9313518..202f6d4 100644 --- a/lib/zipper.ml +++ b/lib/zipper.ml | |||
@@ -2,28 +2,14 @@ | |||
2 | 2 | ||
3 | open Base | 3 | open Base |
4 | 4 | ||
5 | type !+'a zipper = { | 5 | type !+'a zipper = { pos : int; before : 'a Sequence.t; after : 'a Sequence.t } |
6 | pos : int; | ||
7 | popped : 'a Sequence.t; | ||
8 | before : 'a Sequence.t; | ||
9 | after : 'a Sequence.t; | ||
10 | } | ||
11 | |||
12 | type !+'a t = 'a zipper | 6 | type !+'a t = 'a zipper |
13 | 7 | ||
14 | let empty = | 8 | let empty = { pos = 0; before = Sequence.empty; after = Sequence.empty } |
15 | { | ||
16 | pos = 0; | ||
17 | popped = Sequence.empty; | ||
18 | before = Sequence.empty; | ||
19 | after = Sequence.empty; | ||
20 | } | ||
21 | |||
22 | let before z = z.before | 9 | let before z = z.before |
23 | let after z = z.after | 10 | let after z = z.after |
24 | let focus z = after z |> Sequence.next |> Option.map ~f:fst | 11 | let focus z = after z |> Sequence.next |> Option.map ~f:fst |
25 | let focus_or z ~default = Option.value ~default (focus z) | 12 | let focus_or ~default z = Option.value ~default (focus z) |
26 | let history z = z.popped | ||
27 | let is_far_left z = before z |> Sequence.is_empty | 13 | let is_far_left z = before z |> Sequence.is_empty |
28 | let is_far_right z = after z |> Sequence.is_empty | 14 | let is_far_right z = after z |> Sequence.is_empty |
29 | let is_empty z = is_far_left z && is_far_right z | 15 | let is_empty z = is_far_left z && is_far_right z |
@@ -35,12 +21,7 @@ let left z = | |||
35 | match Sequence.next z.before with | 21 | match Sequence.next z.before with |
36 | | None -> z | 22 | | None -> z |
37 | | Some (h, t) -> | 23 | | Some (h, t) -> |
38 | { | 24 | { pos = z.pos - 1; before = t; after = Sequence.shift_right z.after h } |
39 | z with | ||
40 | pos = z.pos - 1; | ||
41 | before = t; | ||
42 | after = Sequence.shift_right z.after h; | ||
43 | } | ||
44 | 25 | ||
45 | let rec left_while f z = | 26 | let rec left_while f z = |
46 | if (not (is_far_left z)) && Option.(focus z |> map ~f |> value ~default:false) | 27 | if (not (is_far_left z)) && Option.(focus z |> map ~f |> value ~default:false) |
@@ -53,12 +34,7 @@ let right z = | |||
53 | match Sequence.next z.after with | 34 | match Sequence.next z.after with |
54 | | None -> z | 35 | | None -> z |
55 | | Some (h, t) -> | 36 | | Some (h, t) -> |
56 | { | 37 | { pos = z.pos + 1; before = Sequence.shift_right z.before h; after = t } |
57 | z with | ||
58 | pos = z.pos + 1; | ||
59 | before = Sequence.shift_right z.before h; | ||
60 | after = t; | ||
61 | } | ||
62 | 38 | ||
63 | let rec right_while f z = | 39 | let rec right_while f z = |
64 | if | 40 | if |
@@ -73,34 +49,46 @@ let goto n z = | |||
73 | let step = if n < 0 then left else right in | 49 | let step = if n < 0 then left else right in |
74 | Fn.apply_n_times ~n:(abs n) step z | 50 | Fn.apply_n_times ~n:(abs n) step z |
75 | 51 | ||
76 | let pop_after z = { z with after = Sequence.drop_eagerly z.after 1 } | 52 | let pop ?(n = 1) z = { z with after = Sequence.drop_eagerly z.after n } |
77 | let pop_before z = if is_far_left z then z else z |> left |> pop_after | 53 | |
78 | let pop = pop_before | 54 | let pop_before ?(n = 1) = |
79 | let push_after x z = { z with after = Sequence.shift_right z.after x } | 55 | let rec aux m z = |
56 | if m < n && not (is_far_left z) then aux (m + 1) (left z) else pop ~n:m z | ||
57 | in | ||
58 | aux 0 | ||
59 | |||
60 | let pop_after ?(n = 1) z = | ||
61 | if right_length z < 2 then z else right z |> pop ~n |> left | ||
62 | |||
63 | let push x z = { z with after = Sequence.shift_right z.after x } | ||
64 | let push_after x z = right z |> push x |> left | ||
80 | 65 | ||
81 | let push_before x z = | 66 | let push_before x z = |
82 | { z with pos = z.pos + 1; before = Sequence.shift_right z.before x } | 67 | { z with pos = z.pos + 1; before = Sequence.shift_right z.before x } |
83 | 68 | ||
84 | let push = push_before | ||
85 | |||
86 | let split z = | 69 | let split z = |
87 | ( { z with after = Sequence.empty }, | 70 | ( { z with after = Sequence.empty }, |
88 | { z with pos = 0; before = Sequence.empty } ) | 71 | { z with pos = 0; before = Sequence.empty } ) |
89 | 72 | ||
90 | let join z1 z2 = { z1 with after = z2.after } | 73 | let join z1 ~z2 = |
91 | let iter_before f z = Sequence.iter ~f z.before | 74 | let z1 = far_right z1 and z2 = far_left z2 in |
92 | let iter_after f z = Sequence.iter ~f z.after | 75 | { z1 with after = z2.after } |
76 | |||
77 | let iter_left f z = Sequence.iter ~f z.before | ||
78 | let iter_right f z = Sequence.iter ~f z.after | ||
93 | 79 | ||
94 | let iter f z = | 80 | let iter f z = |
95 | iter_before f z; | 81 | iter_left f z; |
96 | iter_after f z | 82 | iter_right f z |
97 | 83 | ||
98 | let for_all f z = Sequence.(for_all ~f z.before && for_all ~f z.after) | 84 | let for_all f z = Sequence.(for_all ~f z.before && for_all ~f z.after) |
99 | let exists f z = Sequence.(exists ~f z.before || exists ~f z.after) | 85 | let exists f z = Sequence.(exists ~f z.before || exists ~f z.after) |
100 | let find_before f z = Sequence.find ~f z.before | 86 | let find_left f z = Sequence.find ~f z.before |
101 | let find_after f z = Sequence.find ~f z.after | 87 | let find_right f z = Sequence.find ~f z.after |
102 | let map_before f z = { z with before = Sequence.map ~f z.before } | 88 | let apply_focus f z = Option.map ~f (focus z) |
103 | let map_after f z = { z with after = Sequence.map ~f z.after } | 89 | let apply_focus_or ~default f z = Option.value ~default (apply_focus f z) |
90 | let map_left f z = { z with before = Sequence.map ~f z.before } | ||
91 | let map_right f z = { z with after = Sequence.map ~f z.after } | ||
104 | 92 | ||
105 | let map_focus f z = | 93 | let map_focus f z = |
106 | match Sequence.next z.after with | 94 | match Sequence.next z.after with |
@@ -115,8 +103,8 @@ let map_focus_or ~default f z = | |||
115 | let map f z = | 103 | let map f z = |
116 | { z with before = Sequence.map ~f z.before; after = Sequence.map ~f z.after } | 104 | { z with before = Sequence.map ~f z.before; after = Sequence.map ~f z.after } |
117 | 105 | ||
118 | let mapi_before f z = { z with before = Sequence.mapi ~f z.before } | 106 | let mapi_left f z = { z with before = Sequence.mapi ~f z.before } |
119 | let mapi_after f z = { z with after = Sequence.mapi ~f z.after } | 107 | let mapi_right f z = { z with after = Sequence.mapi ~f z.after } |
120 | 108 | ||
121 | let mapi f z = | 109 | let mapi f z = |
122 | { | 110 | { |
@@ -125,13 +113,13 @@ let mapi f z = | |||
125 | after = Sequence.mapi ~f z.after; | 113 | after = Sequence.mapi ~f z.after; |
126 | } | 114 | } |
127 | 115 | ||
128 | let filter_before f z = { z with before = Sequence.filter ~f z.before } | 116 | let filter_left f z = { z with before = Sequence.filter ~f z.before } |
129 | let filter_after f z = { z with after = Sequence.filter ~f z.after } | 117 | let filter_right f z = { z with after = Sequence.filter ~f z.after } |
130 | let filter p z = z |> filter_before p |> filter_after p | 118 | let filter p z = z |> filter_left p |> filter_right p |
131 | let context_before n z = { z with before = Sequence.take z.before n } | 119 | let context_left n z = { z with before = Sequence.take z.before n } |
132 | let context_after n z = { z with after = Sequence.take z.after n } | 120 | let context_right n z = { z with after = Sequence.take z.after n } |
133 | let context ~b ?(a = b) z = z |> context_before b |> context_after a | 121 | let context ~l ?(r = l) z = z |> context_left l |> context_right r |
134 | let clear_history z = { z with popped = Sequence.empty } | 122 | let swap_focus a = map_focus (Fn.const a) |
135 | let of_seq s = { empty with after = s } | 123 | let of_seq s = { empty with after = s } |
136 | let to_seq z = z |> far_left |> after | 124 | let to_seq z = z |> far_left |> after |
137 | let window ~from ~len z = goto from z |> context_after len |> after | 125 | let window ~from ~len z = goto from z |> context_right len |> after |
diff --git a/lib/zipper.mli b/lib/zipper.mli index e25d57b..d79604e 100644 --- a/lib/zipper.mli +++ b/lib/zipper.mli | |||
@@ -35,17 +35,14 @@ val before : 'a zipper -> 'a Sequence.t | |||
35 | (** Return the sequence before the cursor *) | 35 | (** Return the sequence before the cursor *) |
36 | 36 | ||
37 | val after : 'a zipper -> 'a Sequence.t | 37 | val after : 'a zipper -> 'a Sequence.t |
38 | (** Return the sequence after the cursor *) | 38 | (** Return the sequence after (and including) the cursor *) |
39 | 39 | ||
40 | val focus : 'a zipper -> 'a option | 40 | val focus : 'a zipper -> 'a option |
41 | (** Return the focus of the zipper, if any. *) | 41 | (** Return the focus of the zipper, if any. *) |
42 | 42 | ||
43 | val focus_or : 'a zipper -> default:'a -> 'a | 43 | val focus_or : default:'a -> 'a zipper -> 'a |
44 | (** Return the focus of the zipper, or a user-provided default, otherwise. *) | 44 | (** Return the focus of the zipper, or a user-provided default, otherwise. *) |
45 | 45 | ||
46 | val history : 'a zipper -> 'a Sequence.t | ||
47 | (** Returns the sequence of elements [pop]ped so far from the zipper. *) | ||
48 | |||
49 | val is_far_left : 'a zipper -> bool | 46 | val is_far_left : 'a zipper -> bool |
50 | (** Return whether the cursor is at the beginning of the zipper. *) | 47 | (** Return whether the cursor is at the beginning of the zipper. *) |
51 | 48 | ||
@@ -109,43 +106,52 @@ val goto : int -> 'a zipper -> 'a zipper | |||
109 | This involve [push]ing and [pop]ping elements before and after the | 106 | This involve [push]ing and [pop]ping elements before and after the |
110 | cursor. *) | 107 | cursor. *) |
111 | 108 | ||
112 | val pop_after : 'a zipper -> 'a zipper | 109 | val pop : ?n:int -> 'a zipper -> 'a zipper |
113 | (** Remove the element at the cursor position, if any, and return the | 110 | (** Remove [n] elements at the cursor position (1 by default), if any, |
114 | modified zipper. Calling [pop_after z], | 111 | and return the modified zipper. Calling [pop z], |
115 | 112 | ||
116 | - if [z] is [([3; 2; 1], [4; 5])], the result is [([3; 2; 1], [5])], | 113 | - if [z] is [([3; 2; 1], [4; 5])], the result is [([3; 2; 1], [5])], |
117 | - if [z] is [([1; 2; 3], [])], the result is [([1; 2; 3], [])]. | 114 | - if [z] is [([1; 2; 3], [])], the result is [([1; 2; 3], [])]. |
118 | *) | 115 | *) |
119 | 116 | ||
120 | val pop_before : 'a zipper -> 'a zipper | 117 | val pop_before : ?n:int -> 'a zipper -> 'a zipper |
121 | (** Remove the element before the cursor, if any, and return the | 118 | (** Remove [n] elements before the cursor (1 by default), if any, and |
122 | modified zipper. Calling [pop_before z], | 119 | return the modified zipper. Calling [pop_before z], |
123 | 120 | ||
124 | - if [z] is [([3; 2; 1], [4; 5])], the result is [([2; 1], [4, 5])], | 121 | - if [z] is [([3; 2; 1], [4; 5])], the result is [([2; 1], [4, 5])], |
125 | - if [z] is [([], [1; 2; 3])], the result is [([], [1; 2; 3])]. | 122 | - if [z] is [([], [1; 2; 3])], the result is [([], [1; 2; 3])]. |
126 | *) | 123 | *) |
127 | 124 | ||
128 | val pop : 'a zipper -> 'a zipper | 125 | val pop_after : ?n:int -> 'a zipper -> 'a zipper |
129 | (** [pop] is an alias for [pop_before]. *) | 126 | (** Remove [n] elements after (and {b not} including) the cursor |
127 | (1 by default), if any, and return the modified zipper. | ||
128 | Calling [pop_after z], | ||
129 | |||
130 | - if [z] is [([3; 2; 1], [4; 5])], the result is [([3; 2; 1], [4])], | ||
131 | - if [z] is [([1; 2; 3], [4])], the result is [([1; 2; 3], [4])]. | ||
132 | *) | ||
133 | |||
134 | val push : 'a -> 'a zipper -> 'a zipper | ||
135 | (** Insert an element at the cursor position. | ||
136 | Calling [push 0 z], if [z] is [([3; 2; 1], [4; 5])], | ||
137 | the result is [([3; 2; 1], [0; 4; 5]))], *) | ||
130 | 138 | ||
131 | val push_after : 'a -> 'a zipper -> 'a zipper | 139 | val push_after : 'a -> 'a zipper -> 'a zipper |
132 | (** Insert an element after the cursor. | 140 | (** Insert an element after the cursor. Behaves like {!Zipper.push} if |
141 | the cursor is at the far right of the zipper. | ||
133 | Calling [push_after 0 z], if [z] is [([3; 2; 1], [4; 5])], | 142 | Calling [push_after 0 z], if [z] is [([3; 2; 1], [4; 5])], |
134 | the result is [([3; 2; 1], [0; 4, 5]))], *) | 143 | the result is [([3; 2; 1], [4; 0; 5]))], *) |
135 | 144 | ||
136 | val push_before : 'a -> 'a zipper -> 'a zipper | 145 | val push_before : 'a -> 'a zipper -> 'a zipper |
137 | (** Insert an element before the cursor. Return the modified zipper. | 146 | (** Insert an element before the cursor. Return the modified zipper. |
138 | Calling [push_before 0 z], if [z] is [([3; 2; 1], [4; 5])], | 147 | Calling [push_before 0 z], if [z] is [([3; 2; 1], [4; 5])], |
139 | the result is [([0; 3; 2; 1], [4, 5]))]. *) | 148 | the result is [([0; 3; 2; 1], [4; 5]))]. *) |
140 | |||
141 | val push : 'a -> 'a zipper -> 'a zipper | ||
142 | (** [push] is an alias for [push_before]. *) | ||
143 | 149 | ||
144 | val split : 'a zipper -> 'a zipper * 'a zipper | 150 | val split : 'a zipper -> 'a zipper * 'a zipper |
145 | (** [split z] splits the zipper in two. [([3; 2; 1], [4; 5])] becomes | 151 | (** [split z] splits the zipper in two. [([3; 2; 1], [4; 5])] becomes |
146 | [([3; 2; 1], []), ([], [4; 5])]. *) | 152 | [([3; 2; 1], []), ([], [4; 5])]. *) |
147 | 153 | ||
148 | val join : 'a zipper -> 'a zipper -> 'a zipper | 154 | val join : 'a zipper -> z2:'a zipper -> 'a zipper |
149 | (** [join z1 z2] creates a new zipper using [before z1] and [after z2]. | 155 | (** [join z1 z2] creates a new zipper using [before z1] and [after z2]. |
150 | [([3; 2; 1], []) ([4; 2], [4; 5])] becomes [([3; 2; 1], [4; 5])]. *) | 156 | [([3; 2; 1], []) ([4; 2], [4; 5])] becomes [([3; 2; 1], [4; 5])]. *) |
151 | 157 | ||
@@ -156,16 +162,16 @@ val join : 'a zipper -> 'a zipper -> 'a zipper | |||
156 | Unless otherwise stated, these functions will iterate on the | 162 | Unless otherwise stated, these functions will iterate on the |
157 | elements before the cursor, first. *) | 163 | elements before the cursor, first. *) |
158 | 164 | ||
159 | val iter_before : ('a -> unit) -> 'a zipper -> unit | 165 | val iter_left : ('a -> unit) -> 'a zipper -> unit |
160 | (** [iter_before f z] will call [f x] for all [x], elements before the | 166 | (** [iter_left f z] will call [f x] for all [x], elements before the |
161 | cursor in [z].*) | 167 | cursor in [z].*) |
162 | 168 | ||
163 | val iter_after : ('a -> unit) -> 'a zipper -> unit | 169 | val iter_right : ('a -> unit) -> 'a zipper -> unit |
164 | (** [iter_after f z] will call [f x] for all [x], elements after the | 170 | (** [iter_right f z] will call [f x] for all [x], elements after (in |
165 | cursor in [z].*) | 171 | including) the cursor in [z]. *) |
166 | 172 | ||
167 | val iter : ('a -> unit) -> 'a zipper -> unit | 173 | val iter : ('a -> unit) -> 'a zipper -> unit |
168 | (** [iter f z] is equivalent to [iter_before f z; iter_after f z] *) | 174 | (** [iter f z] is equivalent to [iter_left f z; iter_right f z] *) |
169 | 175 | ||
170 | val for_all : ('a -> bool) -> 'a zipper -> bool | 176 | val for_all : ('a -> bool) -> 'a zipper -> bool |
171 | (** [for_all p z] tests whether a predicate [p] is [true] for all | 177 | (** [for_all p z] tests whether a predicate [p] is [true] for all |
@@ -175,25 +181,33 @@ val exists : ('a -> bool) -> 'a zipper -> bool | |||
175 | (** [exists p z] tests whether at least one element in the zipper is | 181 | (** [exists p z] tests whether at least one element in the zipper is |
176 | [true] according to the predicate [p]. *) | 182 | [true] according to the predicate [p]. *) |
177 | 183 | ||
178 | val find_before : ('a -> bool) -> 'a zipper -> 'a option | 184 | val find_left : ('a -> bool) -> 'a zipper -> 'a option |
179 | (** [find_before p z] will return the first element before the cursor in | 185 | (** [find_left p z] will return the first element before the cursor in |
180 | [z] satisfying the predicate [p], if any. *) | 186 | [z] satisfying the predicate [p], if any. *) |
181 | 187 | ||
182 | val find_after : ('a -> bool) -> 'a zipper -> 'a option | 188 | val find_right : ('a -> bool) -> 'a zipper -> 'a option |
183 | (** [find_after p z] will return the first element after the cursor in | 189 | (** [find_right p z] will return the first element after the cursor in |
184 | [z] satisfying the predicate [p], if any. *) | 190 | [z] satisfying the predicate [p], if any. *) |
185 | 191 | ||
192 | val apply_focus : ('a -> 'b) -> 'a zipper -> 'b option | ||
193 | (** [apply focus f z] applies f to the current focus, if any, and | ||
194 | returns its result *) | ||
195 | |||
196 | val apply_focus_or : default:'b -> ('a -> 'b) -> 'a zipper -> 'b | ||
197 | (** [apply focus f z] applies f to the current focus and returns its | ||
198 | result. Return a default value if no element is in focus. *) | ||
199 | |||
186 | (** {1 Transforming zippers} *) | 200 | (** {1 Transforming zippers} *) |
187 | 201 | ||
188 | (** Since zippers are based on sequences, the functions in this section | 202 | (** Since zippers are based on sequences, the functions in this section |
189 | are lazy; i.e., resulting elements of the zipper are computed only | 203 | are lazy; i.e., resulting elements of the zipper are computed only |
190 | when demanded. *) | 204 | when demanded. *) |
191 | 205 | ||
192 | val map_before : ('a -> 'a) -> 'a zipper -> 'a zipper | 206 | val map_left : ('a -> 'a) -> 'a zipper -> 'a zipper |
193 | (** Map a function over all elements before the cursor. *) | 207 | (** Map a function over all elements before the cursor. *) |
194 | 208 | ||
195 | val map_after : ('a -> 'a) -> 'a zipper -> 'a zipper | 209 | val map_right : ('a -> 'a) -> 'a zipper -> 'a zipper |
196 | (** Map a function over all elements after the cursor. *) | 210 | (** Map a function over all elements after (and including) the cursor. *) |
197 | 211 | ||
198 | val map_focus : ('a -> 'a) -> 'a zipper -> 'a zipper | 212 | val map_focus : ('a -> 'a) -> 'a zipper -> 'a zipper |
199 | (** Map a function over the element focused by the cursor, if any. *) | 213 | (** Map a function over the element focused by the cursor, if any. *) |
@@ -202,31 +216,31 @@ val map_focus_or : default:'a -> ('a -> 'a) -> 'a zipper -> 'a zipper | |||
202 | (** Map a function over the element focused by the cursor. Push | 216 | (** Map a function over the element focused by the cursor. Push |
203 | [default] if no element is focused. *) | 217 | [default] if no element is focused. *) |
204 | 218 | ||
205 | val map : ('a -> 'a) -> 'a zipper -> 'a zipper | 219 | val map : ('a -> 'b) -> 'a zipper -> 'b zipper |
206 | (** Map a function over all elements of a zipper. *) | 220 | (** Map a function over all elements of a zipper. *) |
207 | 221 | ||
208 | val mapi_before : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper | 222 | val mapi_left : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper |
209 | (** [mapi_before] is analogous to {!Zipper.map_before}, but the function | 223 | (** [mapi_left] is analogous to {!Zipper.map_left}, but the function |
210 | takes an index and an element. | 224 | takes an index and an element. |
211 | The index indicates the distance of an element from the cursor. *) | 225 | The index indicates the distance of an element from the cursor. *) |
212 | 226 | ||
213 | val mapi_after : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper | 227 | val mapi_right : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper |
214 | (** [mapi_after] is analogous to {!Zipper.map_after}, but the function | 228 | (** [mapi_right] is analogous to {!Zipper.map_right}, but the function |
215 | takes an index and an element. | 229 | takes an index and an element. |
216 | The index indicates the distance of an element from the cursor. *) | 230 | The index indicates the distance of an element from the cursor. *) |
217 | 231 | ||
218 | val mapi : (int -> 'a -> 'a) -> 'a zipper -> 'a zipper | 232 | val mapi : (int -> 'a -> 'b) -> 'a zipper -> 'b zipper |
219 | (** [mapi] is analogous to {!Zipper.map}, but the function takes an | 233 | (** [mapi] is analogous to {!Zipper.map}, but the function takes an |
220 | index and an element. | 234 | index and an element. |
221 | The index indicates the distance of an element from the cursor. *) | 235 | The index indicates the distance of an element from the cursor. *) |
222 | 236 | ||
223 | val filter_before : ('a -> bool) -> 'a zipper -> 'a zipper | 237 | val filter_left : ('a -> bool) -> 'a zipper -> 'a zipper |
224 | (** [filter_before p z] filters the elements before the cursor in a | 238 | (** [filter_left p z] filters the elements before the cursor in a |
225 | zipper [z] according to a predicate [p], i.e., keeping the elements | 239 | zipper [z] according to a predicate [p], i.e., keeping the elements |
226 | that satisfy the predicate. *) | 240 | that satisfy the predicate. *) |
227 | 241 | ||
228 | val filter_after : ('a -> bool) -> 'a zipper -> 'a zipper | 242 | val filter_right : ('a -> bool) -> 'a zipper -> 'a zipper |
229 | (** [filter_after p z] filters the elements after the cursor in a | 243 | (** [filter_right p z] filters the elements after the cursor in a |
230 | zipper [z] according to a predicate [p], i.e., keeping the elements | 244 | zipper [z] according to a predicate [p], i.e., keeping the elements |
231 | that satisfy the predicate. *) | 245 | that satisfy the predicate. *) |
232 | 246 | ||
@@ -235,21 +249,22 @@ val filter : ('a -> bool) -> 'a zipper -> 'a zipper | |||
235 | predicate [p], i.e., keeping the elements that satisfy the | 249 | predicate [p], i.e., keeping the elements that satisfy the |
236 | predicate. *) | 250 | predicate. *) |
237 | 251 | ||
238 | val context_before : int -> 'a zipper -> 'a zipper | 252 | val context_left : int -> 'a zipper -> 'a zipper |
239 | (** [context_before n z] will limit the zipper [z] to [n] elements before | 253 | (** [context_left n z] will limit the zipper [z] to [n] elements before |
240 | the cursor. *) | 254 | the cursor. *) |
241 | 255 | ||
242 | val context_after : int -> 'a zipper -> 'a zipper | 256 | val context_right : int -> 'a zipper -> 'a zipper |
243 | (** [context_after n z] will limit the zipper [z] to [n] elements after | 257 | (** [context_right n z] will limit the zipper [z] to [n] elements after |
244 | the cursor. *) | 258 | the cursor. *) |
245 | 259 | ||
246 | val context : b:int -> ?a:int -> 'a zipper -> 'a zipper | 260 | val context : l:int -> ?r:int -> 'a zipper -> 'a zipper |
247 | (** [context ~b ~a z] will limit the zipper [z] to [b] elements before | 261 | (** [context ~l ~r z] will limit the zipper [z] to [l] elements before |
248 | the cursor and [a] elements after the cursor. When [a] is not | 262 | the cursor and [r] elements after the cursor. When [r] is not |
249 | provided, it defaults to [b]. *) | 263 | provided, it defaults to [l]. *) |
250 | 264 | ||
251 | val clear_history : 'a zipper -> 'a zipper | 265 | val swap_focus : 'a -> 'a zipper -> 'a zipper |
252 | (** Clear the history of the zipper. See {!Zipper.history}. *) | 266 | (** Swap the element in focus with a newly provided element. Nothing |
267 | happens if no element is in focus. *) | ||
253 | 268 | ||
254 | (** {1 Zippers and sequences} *) | 269 | (** {1 Zippers and sequences} *) |
255 | 270 | ||