diff options
| author | Federico Igne <undyamon@disroot.org> | 2024-01-24 21:14:11 +0100 |
|---|---|---|
| committer | Federico Igne <undyamon@disroot.org> | 2024-01-24 21:14:11 +0100 |
| commit | af0cd851fec5038faff5a8133cadad6c65568374 (patch) | |
| tree | 5f594f6140f6e070fb4a96b1ba4d937d7f43d1b7 /lib/editor.ml | |
| parent | 7510a0194125ad6229fe8e84f436faa7f87b7c25 (diff) | |
| download | sandy-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/editor.ml')
| -rw-r--r-- | lib/editor.ml | 98 |
1 files changed, 40 insertions, 58 deletions
diff --git a/lib/editor.ml b/lib/editor.ml index f8091b8..0ed2229 100644 --- a/lib/editor.ml +++ b/lib/editor.ml | |||
| @@ -3,6 +3,12 @@ module Buffer = EditorBuffer | |||
| 3 | open Util | 3 | open Util |
| 4 | 4 | ||
| 5 | type mode = Normal | Insert | Control | 5 | type mode = Normal | Insert | Control |
| 6 | |||
| 7 | type selection = | ||
| 8 | | Empty | ||
| 9 | | Glyphwise of char Sequence.t Sequence.t | ||
| 10 | | Linewise of char Sequence.t Sequence.t | ||
| 11 | |||
| 6 | type cursor = int * int | 12 | type cursor = int * int |
| 7 | 13 | ||
| 8 | type editor = { | 14 | type editor = { |
| @@ -19,6 +25,7 @@ type editor = { | |||
| 19 | message_timestamp : float; | 25 | message_timestamp : float; |
| 20 | message_duration : float; | 26 | message_duration : float; |
| 21 | pending_command : string; | 27 | pending_command : string; |
| 28 | registers : selection Array.t; | ||
| 22 | } | 29 | } |
| 23 | 30 | ||
| 24 | type t = editor | 31 | type t = editor |
| @@ -38,6 +45,7 @@ let init (c : Config.t) : editor = | |||
| 38 | message_timestamp = Unix.time (); | 45 | message_timestamp = Unix.time (); |
| 39 | message_duration = 5.; | 46 | message_duration = 5.; |
| 40 | pending_command = ""; | 47 | pending_command = ""; |
| 48 | registers = Array.create ~len:128 Empty; | ||
| 41 | } | 49 | } |
| 42 | 50 | ||
| 43 | let string_of_mode = function | 51 | let string_of_mode = function |
| @@ -142,6 +150,16 @@ module Action = struct | |||
| 142 | let set_focused_buffer b e = ((), { e with buffer = Some b }) | 150 | let set_focused_buffer b e = ((), { e with buffer = Some b }) |
| 143 | let get_terminal_size e = (e.term.size, e) | 151 | let get_terminal_size e = (e.term.size, e) |
| 144 | 152 | ||
| 153 | let get_register r e = | ||
| 154 | assert (Char.('!' <= r && r <= '~')); | ||
| 155 | (e.registers.(Char.to_int r), e) | ||
| 156 | |||
| 157 | let set_register r z e = | ||
| 158 | assert (Char.('!' <= r && r <= '~')); | ||
| 159 | e.registers.(Char.to_int '"') <- z; | ||
| 160 | e.registers.(Char.to_int r) <- z; | ||
| 161 | ((), e) | ||
| 162 | |||
| 145 | let on_focused_buffer f = | 163 | let on_focused_buffer f = |
| 146 | let f e = { e with buffer = Option.map ~f e.buffer } in | 164 | let f e = { e with buffer = Option.map ~f e.buffer } in |
| 147 | modify ~f *> update_cursor | 165 | modify ~f *> update_cursor |
| @@ -218,64 +236,6 @@ let move ?(up = 0) ?(down = 0) ?(left = 0) ?(right = 0) (x, y) = | |||
| 218 | 236 | ||
| 219 | let move_to ?x ?y (sx, sy) = Option.(value x ~default:sx, value y ~default:sy) | 237 | let move_to ?x ?y (sx, sy) = Option.(value x ~default:sx, value y ~default:sy) |
| 220 | 238 | ||
| 221 | (* let get_next_command s = *) | ||
| 222 | (* match Sequence.next s.pending with *) | ||
| 223 | (* | None -> (None, s) *) | ||
| 224 | (* | Some (h, t) -> (Some h, { s with pending = t }) *) | ||
| 225 | |||
| 226 | (* let handle_insert_key = *) | ||
| 227 | (* let open Action in *) | ||
| 228 | (* let open Key in *) | ||
| 229 | (* function *) | ||
| 230 | (* | Arrow_down -> Buffer.Action.down |> on_focused_buffer *) | ||
| 231 | (* | Arrow_left -> Buffer.Action.left |> on_focused_buffer *) | ||
| 232 | (* | Arrow_right -> Buffer.Action.right |> on_focused_buffer *) | ||
| 233 | (* | Arrow_up -> Buffer.Action.up |> on_focused_buffer *) | ||
| 234 | (* | Backspace -> Buffer.Action.delete_before |> on_focused_buffer *) | ||
| 235 | (* | Ctrl 'Q' -> quit 0 *) | ||
| 236 | (* | Delete -> Buffer.Action.delete_after |> on_focused_buffer *) | ||
| 237 | (* | Enter -> Buffer.Action.newline |> on_focused_buffer *) | ||
| 238 | (* | Esc -> (Buffer.Action.left |> on_focused_buffer) *> set_mode Normal *) | ||
| 239 | (* | Key k -> Buffer.Action.insert k |> on_focused_buffer *) | ||
| 240 | (* | _ -> noop *) | ||
| 241 | |||
| 242 | (* let handle_normal_key = *) | ||
| 243 | (* let open Action in *) | ||
| 244 | (* let open Key in *) | ||
| 245 | (* function *) | ||
| 246 | (* | Arrow_down | Key 'j' -> Buffer.Action.down |> on_focused_buffer *) | ||
| 247 | (* | Arrow_left | Backspace | Key 'h' -> Buffer.Action.left |> on_focused_buffer *) | ||
| 248 | (* | Arrow_right | Key ' ' | Key 'l' -> Buffer.Action.right |> on_focused_buffer *) | ||
| 249 | (* | Arrow_up | Key 'k' -> Buffer.Action.up |> on_focused_buffer *) | ||
| 250 | (* | Ctrl 'Q' -> quit 0 *) | ||
| 251 | (* | Key '0' -> Buffer.Action.bol |> on_focused_buffer_or_new *) | ||
| 252 | (* | Key 'A' -> *) | ||
| 253 | (* (Buffer.Action.eol |> on_focused_buffer_or_new) *> set_mode Insert *) | ||
| 254 | (* | Key 'a' -> *) | ||
| 255 | (* (Buffer.Action.right |> on_focused_buffer_or_new) *> set_mode Insert *) | ||
| 256 | (* | Key 'G' -> Buffer.Action.eof |> on_focused_buffer_or_new *) | ||
| 257 | (* | Key 'I' -> *) | ||
| 258 | (* noop *) | ||
| 259 | (* (1* (Buffer.Action.bol |> on_focused_buffer_or_new) *> set_mode Insert *1) *) | ||
| 260 | (* | Key 'i' -> (Fn.id |> on_focused_buffer_or_new) *> set_mode Insert *) | ||
| 261 | (* | Key 's' -> *) | ||
| 262 | (* (Buffer.Action.delete_after |> on_focused_buffer_or_new) *) | ||
| 263 | (* *> set_mode Insert *) | ||
| 264 | (* | Key 'x' -> Buffer.Action.delete_after |> on_focused_buffer_or_new *) | ||
| 265 | (* | Key 'X' -> Buffer.Action.delete_before |> on_focused_buffer_or_new *) | ||
| 266 | (* | Key '$' -> Buffer.Action.eol |> on_focused_buffer_or_new *) | ||
| 267 | (* | _ -> noop *) | ||
| 268 | |||
| 269 | (* let handle_next_command = *) | ||
| 270 | (* let f m = function *) | ||
| 271 | (* | None -> Action.return () *) | ||
| 272 | (* | Some k -> ( *) | ||
| 273 | (* match m with *) | ||
| 274 | (* | Insert -> handle_insert_key k *) | ||
| 275 | (* | Normal -> handle_normal_key k) *) | ||
| 276 | (* in *) | ||
| 277 | (* Action.(map2 ~f get_mode get_next_command |> join) *) | ||
| 278 | |||
| 279 | let handle_insert_command = | 239 | let handle_insert_command = |
| 280 | let open Command in | 240 | let open Command in |
| 281 | let open Action in | 241 | let open Action in |
| @@ -434,6 +394,28 @@ let handle_normal_command c = | |||
| 434 | Buffer.Action.( | 394 | Buffer.Action.( |
| 435 | delete_to_eol &> move_down &> delete_lines ~n &> move_up &> eol) | 395 | delete_to_eol &> move_down &> delete_lines ~n &> move_up &> eol) |
| 436 | |> on_focused_buffer_or_new | 396 | |> on_focused_buffer_or_new |
| 397 | (* Paste *) | ||
| 398 | | Shortcut (r, n, Paste_after) -> | ||
| 399 | let r = Option.value ~default:'"' r in | ||
| 400 | let paste = function | ||
| 401 | | Empty -> noop | ||
| 402 | | Glyphwise z -> Buffer.Action.paste ?n z |> on_focused_buffer_or_new | ||
| 403 | | Linewise z -> | ||
| 404 | Buffer.Action.paste ~linewise:true ?n z | ||
| 405 | |> on_focused_buffer_or_new | ||
| 406 | in | ||
| 407 | get_register r >>= paste | ||
| 408 | | Shortcut (r, n, Paste_before) -> | ||
| 409 | let r = Option.value ~default:'"' r in | ||
| 410 | let paste = function | ||
| 411 | | Empty -> noop | ||
| 412 | | Glyphwise z -> | ||
| 413 | Buffer.Action.paste ~before:true ?n z |> on_focused_buffer_or_new | ||
| 414 | | Linewise z -> | ||
| 415 | Buffer.Action.paste ~before:true ~linewise:true ?n z | ||
| 416 | |> on_focused_buffer_or_new | ||
| 417 | in | ||
| 418 | get_register r >>= paste | ||
| 437 | (* Join *) | 419 | (* Join *) |
| 438 | | Shortcut (_, n, Join) -> | 420 | | Shortcut (_, n, Join) -> |
| 439 | let n = Option.(value ~default:1 n) in | 421 | let n = Option.(value ~default:1 n) in |
