summaryrefslogtreecommitdiff
path: root/lib/editorBuffer.ml
diff options
context:
space:
mode:
authorFederico Igne <undyamon@disroot.org>2024-01-24 21:14:11 +0100
committerFederico Igne <undyamon@disroot.org>2024-01-24 21:14:11 +0100
commitaf0cd851fec5038faff5a8133cadad6c65568374 (patch)
tree5f594f6140f6e070fb4a96b1ba4d937d7f43d1b7 /lib/editorBuffer.ml
parent7510a0194125ad6229fe8e84f436faa7f87b7c25 (diff)
downloadsandy-af0cd851fec5038faff5a8133cadad6c65568374.tar.gz
sandy-af0cd851fec5038faff5a8133cadad6c65568374.zip
feat: add ability to paste text from a register
Register are simplier than Vim register, in particular no register is local to buffers.
Diffstat (limited to 'lib/editorBuffer.ml')
-rw-r--r--lib/editorBuffer.ml55
1 files changed, 52 insertions, 3 deletions
diff --git a/lib/editorBuffer.ml b/lib/editorBuffer.ml
index c492b8b..295e6e7 100644
--- a/lib/editorBuffer.ml
+++ b/lib/editorBuffer.ml
@@ -61,12 +61,22 @@ module Action = struct
61 61
62 (* let on_content_stored ?(register = '"') ?(append = false) f b = ... *) 62 (* let on_content_stored ?(register = '"') ?(append = false) f b = ... *)
63 63
64 let update_render_at_cursor b = 64 let update_render ?(before = false) ~n b =
65 match b.content with 65 match b.content with
66 | Error _ -> b 66 | Error _ -> b
67 | Ok c -> 67 | Ok c ->
68 let l = apply_focus_or ~default:Sequence.empty (to_seq &> render) c in 68 let step = if before then left else right in
69 { b with rendered = swap_focus l b.rendered } 69 let rec aux i r c =
70 if i = 0 then r
71 else
72 let default = Sequence.empty in
73 let l = apply_focus_or ~default (to_seq &> render) c in
74 let c' = step c and r' = swap_focus l r |> step in
75 aux (i - 1) r' c'
76 in
77 { b with rendered = aux n b.rendered c |> goto (left_length c) }
78
79 let update_render_at_cursor = update_render ~n:1
70 80
71 let move_up ?(n = 1) = 81 let move_up ?(n = 1) =
72 let change_content = 82 let change_content =
@@ -218,6 +228,45 @@ module Action = struct
218 in 228 in
219 change_content &> change_rendered &> update_render_at_cursor 229 change_content &> change_rendered &> update_render_at_cursor
220 230
231 let paste ?(before = false) ?(linewise = false) ?(n = 1) s =
232 let change_content =
233 if linewise then
234 let push = if before then push_before_seq else push_after_seq in
235 push (Sequence.map ~f:of_seq s) |> on_content
236 else
237 let aux z =
238 match Sequence.next s with
239 | None -> z
240 | Some (h, t) ->
241 let init =
242 let default = Zipper.(of_seq h |> far_right) in
243 map_focus_or ~default (push_before_seq h) z
244 and f z l =
245 let default = (Zipper.empty, Zipper.empty) in
246 let z1, z2 = apply_focus_or ~default split z in
247 z |> push_before z1 |> swap_focus z2
248 |> map_focus (push_before_seq l)
249 in
250 let folded = Sequence.fold ~init ~f t in
251 if before then folded
252 else
253 folded
254 |> Fn.apply_n_times ~n:(Sequence.length t) left
255 |> map_focus (Fn.apply_n_times ~n:(Sequence.length h) left)
256 in
257 on_content aux
258 and change_rendered =
259 if linewise then
260 let push = if before then push_before_seq else push_after_seq in
261 push (Sequence.map ~f:render s) |> on_rendered
262 else
263 let len = Sequence.length s in
264 let push = if before then push_before else push in
265 let aux z = Fn.apply_n_times ~n:(len - 1) (push Sequence.empty) z in
266 on_rendered aux &> update_render ~before ~n:len
267 in
268 Fn.apply_n_times ~n (change_content &> change_rendered)
269
221 (* let save_history_to ?(clear = true) r = () *) 270 (* let save_history_to ?(clear = true) r = () *)
222end 271end
223 272