From 055c743c55bde27f4475d3434c26d8383c0c3ea1 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 11 Jan 2024 19:31:31 +0100 Subject: bulk: add PoC of vim-like modular editor --- lib/key.ml | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 lib/key.ml (limited to 'lib/key.ml') diff --git a/lib/key.ml b/lib/key.ml new file mode 100644 index 0000000..85aa282 --- /dev/null +++ b/lib/key.ml @@ -0,0 +1,72 @@ +open Base + +type key = + | Arrow_down + | Arrow_left + | Arrow_right + | Arrow_up + | Backspace + | Ctrl of char + | Delete + | End + | Enter + | Esc + | Home + | Key of char + | Nul + | Page_down + | Page_up + +type t = key + +let ctrl c = Ctrl c +let key c = Key c + +let of_char = function + | '\000' -> Nul + | '\013' -> Enter + | '\027' -> Esc + | '\127' -> Backspace + | c when Char.(c < ' ') -> Char.to_int c + 64 |> Char.of_int_exn |> ctrl + | c -> Key c + +let stream = + let step s c = + let open Sequence.Step in + let escaped = function + | 'A' -> Some Arrow_up + | 'B' -> Some Arrow_down + | 'C' -> Some Arrow_right + | 'D' -> Some Arrow_left + | 'F' -> Some End + | 'H' -> Some Home + | _ -> None + and tilda = function + | '1' -> Some Home + | '3' -> Some Delete + | '4' -> Some End + | '5' -> Some Page_up + | '6' -> Some Page_down + | '7' -> Some Home + | '8' -> Some End + | _ -> None + in + match (s, c) with + | `start, Some '\027' -> Skip { state = `esc } + | `esc, None -> Yield { value = Esc; state = `start } + | `esc, Some '[' | `escaped, Some 'O' -> Skip { state = `escaped } + | `escaped, Some i when Char.(i = '1' || ('3' <= i && i <= '8')) -> + Skip { state = `tilda i } + | `escaped, c -> ( + match Option.(c >>= escaped) with + | None -> Skip { state = `state } + | Some c -> Yield { value = c; state = `start }) + | `tilda i, Some '~' -> ( + match tilda i with + | None -> Skip { state = `start } + | Some k -> Yield { value = k; state = `start }) + | `esc, Some _ | `tilda _, _ -> Skip { state = `start } + | _, None -> Skip { state = `start } + | _, Some c -> Yield { value = of_char c; state = `start } + in + Sequence.unfold_with ~init:`start ~f:step Terminal.char_stream -- cgit v1.2.3