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 /lib | |
| 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".
Diffstat (limited to 'lib')
| -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 | ||
