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/zipper.ml | |
| 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/zipper.ml')
| -rw-r--r-- | lib/zipper.ml | 96 |
1 files changed, 42 insertions, 54 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 |
