input and bindings refactoring

This commit is contained in:
cqc
2021-09-22 17:28:12 -05:00
parent 72e907a341
commit fe935c4e1f

144
main.ml
View File

@ -57,20 +57,12 @@ module Input = struct
| Unknown | Unknown
| None | None
type keystate =
{ctrl: bool; meta: bool; shift: bool; super: bool; code: code}
type mods = Ctrl | Meta | Super | Shift
type key = Char of char | Code of code type key = Char of char | Code of code
module KeymodSet = struct
type t = Shift | Ctrl | Meta | Fn
let compare (x : t) (y : t) = compare x y
end
module Keymod = Set.Make (KeymodSet)
let modset = Keymod.of_list
type keystate = {mods: Keymod.t; code: code}
module Key = struct module Key = struct
type t = keystate type t = keystate
@ -80,7 +72,6 @@ module Input = struct
module Bind = struct module Bind = struct
(* parts stolen from lambda-term/src/lTerm_{edit,key}.ml{,i} *) (* parts stolen from lambda-term/src/lTerm_{edit,key}.ml{,i} *)
module S = Zed_input.Make (Key) module S = Zed_input.Make (Key)
include S
type action = Custom of (unit -> unit) | Zed of Zed_edit.action type action = Custom of (unit -> unit) | Zed of Zed_edit.action
type t = action list S.t type t = action list S.t
@ -93,26 +84,74 @@ module Input = struct
; mutable last_keyseq: keystate list ; mutable last_keyseq: keystate list
; mutable last_actions: action list } ; mutable last_actions: action list }
let keystate_of_mods ks m =
List.fold_left
(fun ks m ->
match m with
| Meta -> {ks with meta= true}
| Ctrl -> {ks with ctrl= true}
| Super -> {ks with super= true}
| Shift -> {ks with shift= true} )
ks m
let add events action bindings = let add events action bindings =
let events = let events =
List.map List.map
(fun (m, k) -> (fun (m, k) ->
{ mods= Keymod.of_list m keystate_of_mods
; code= { meta= false
( match k with ; ctrl= false
| Char c -> UChar (UChar.of_char c) ; super= false
| Code c -> c ) } ) ; shift= false
; code=
( match k with
| Char c -> UChar (UChar.of_char c)
| Code c -> c ) }
m )
events in events in
S.add events action bindings S.add events action bindings
let default_resolver b = let default_resolver b = S.resolver [S.pack (fun x -> x) b]
resolver [pack (fun (x : action list) -> x) b]
let get_resolver result default = let get_resolver result default =
match result with Continue r -> r | _ -> default match result with S.Continue r -> r | _ -> default
let init bindings = let init bindings =
{bindings; state= S.Rejected; last_keyseq= []; last_actions= []} {bindings; state= S.Rejected; last_keyseq= []; last_actions= []}
let resolve = S.resolve
let empty = S.empty
let actions_of_events (state : state) events =
List.flatten
(List.filter_map
(fun e ->
(*F.epr "action_of_events: %s@." (to_string e) ;*)
match e with
| `Key_down (k : keystate) -> (
( match state.state with
| Continue _ -> ()
| _ -> state.last_keyseq <- [] ) ;
state.state <-
resolve k
(get_resolver state.state
(default_resolver state.bindings) ) ;
state.last_keyseq <- k :: state.last_keyseq ;
match state.state with
| Accepted a ->
state.last_actions <- a ;
Some a
| Rejected ->
state.last_actions <- [] ;
None
| _ -> None )
| _ -> None )
events )
let process bindstate events =
List.iter
(function Custom f -> f () | _ -> ())
(actions_of_events bindstate events)
end end
(* stolen from lambda-term/src/lTerm_{edit,key}.ml{,i} *) (* stolen from lambda-term/src/lTerm_{edit,key}.ml{,i} *)
@ -149,19 +188,16 @@ module Input = struct
let to_string key = let to_string key =
Printf.sprintf Printf.sprintf
"{ control = %B; meta = %B; shift = %B; fn = %B; code = %s }" "{ control = %B; meta = %B; shift = %B; super = %B; code = %s }"
(Keymod.mem Ctrl key.mods) key.ctrl key.meta key.shift key.super
(Keymod.mem Meta key.mods)
(Keymod.mem Shift key.mods)
(Keymod.mem Fn key.mods)
(string_of_code key.code) (string_of_code key.code)
let to_string_compact key = let to_string_compact key =
let buffer = Buffer.create 32 in let buffer = Buffer.create 32 in
if Keymod.mem Ctrl key.mods then Buffer.add_string buffer "C-" ; if key.ctrl then Buffer.add_string buffer "Ctrl-" ;
if Keymod.mem Meta key.mods then Buffer.add_string buffer "M-" ; if key.meta then Buffer.add_string buffer "Meta-" ;
if Keymod.mem Shift key.mods then Buffer.add_string buffer "S-" ; if key.shift then Buffer.add_string buffer "Shift-" ;
if Keymod.mem Fn key.mods then Buffer.add_string buffer "Fn-" ; if key.super then Buffer.add_string buffer "Super-" ;
( match key.code with ( match key.code with
| UChar ch -> | UChar ch ->
let code = UChar.code ch in let code = UChar.code ch in
@ -192,7 +228,6 @@ module Event = struct
open CamomileLibrary open CamomileLibrary
open Zed_edit open Zed_edit
open Input open Input
open Input.KeymodSet
type mouse = int * int type mouse = int * int
@ -233,7 +268,6 @@ module Event = struct
let event_of_sdlevent ev = let event_of_sdlevent ev =
let key_of_sdlkey ev = let key_of_sdlkey ev =
let km = Sdl.Event.get ev Sdl.Event.keyboard_keymod in
let (kc : Sdl.keycode) = let (kc : Sdl.keycode) =
Sdl.Event.get ev Sdl.Event.keyboard_keycode Sdl.Event.get ev Sdl.Event.keyboard_keycode
land lnot Sdl.K.scancode_mask in land lnot Sdl.K.scancode_mask in
@ -278,13 +312,12 @@ module Event = struct
|'\'' | '>' | '<' | '^' | '`' | '|' -> |'\'' | '>' | '<' | '^' | '`' | '|' ->
UChar (UChar.of_int k) UChar (UChar.of_int k)
| _ -> None ) in | _ -> None ) in
let mods = let km = Sdl.Event.get ev Sdl.Event.keyboard_keymod in
List.filter_map { code= c
(fun (m, v) -> if km land m > 0 then Some v else None) ; ctrl= km land Sdl.Kmod.ctrl > 0
Sdl.Kmod. ; meta= km land Sdl.Kmod.alt > 0
[(shift, Shift); (ctrl, Ctrl); (alt, Meta); (gui, Fn)] ; super= km land Sdl.Kmod.gui > 0
in ; shift= km land Sdl.Kmod.shift > 0 } in
{code= c; mods= Input.Keymod.of_list mods} in
let repeat = Sdl.Event.get ev Sdl.Event.keyboard_repeat in let repeat = Sdl.Event.get ev Sdl.Event.keyboard_repeat in
let r = let r =
match Sdl.Event.enum (Sdl.Event.get ev Sdl.Event.typ) with match Sdl.Event.enum (Sdl.Event.get ev Sdl.Event.typ) with
@ -354,33 +387,6 @@ module Event = struct
let key_left : Sdl.keycode = 0x40000050 let key_left : Sdl.keycode = 0x40000050
let key_right : Sdl.keycode = 0x4000004f let key_right : Sdl.keycode = 0x4000004f
let handle_keyevents (el : events) f = List.iter f el let handle_keyevents (el : events) f = List.iter f el
let actions_of_events (state : Input.Bind.state) (events : events) =
let open Input.Bind in
List.flatten
(List.filter_map
(fun e ->
(*F.epr "action_of_events: %s@." (to_string e) ;*)
match e with
| `Key_down (k : Input.keystate) -> (
( match state.state with
| Continue _ -> ()
| _ -> state.last_keyseq <- [] ) ;
state.state <-
resolve k
(get_resolver state.state
(default_resolver state.bindings) ) ;
state.last_keyseq <- k :: state.last_keyseq ;
match state.state with
| Accepted a ->
state.last_actions <- a ;
Some a
| Rejected ->
state.last_actions <- [] ;
None
| _ -> None )
| _ -> None )
events )
end end
module Display = struct module Display = struct
@ -713,7 +719,7 @@ module Panel = struct
; subpanels ; subpanels
; tag= "origin-box" } ; tag= "origin-box" }
let g_text_height = ref 30. let g_text_height = ref 25.
type Format.stag += Color_bg of Wall.color type Format.stag += Color_bg of Wall.color
type Format.stag += Color_fg of Wall.color type Format.stag += Color_fg of Wall.color
@ -1300,9 +1306,7 @@ module Store = struct
(not sv.editmode) (not sv.editmode)
&& not (Panel.Modal.is_active modalstate) && not (Panel.Modal.is_active modalstate)
then ( then (
List.iter Input.Bind.process bindstate events ;
Input.Bind.(function Custom f -> f () | _ -> ())
(Event.actions_of_events bindstate events) ;
update_textedit () ) ; update_textedit () ) ;
(Panel.vbox panel.subpanels).act panel events ) (Panel.vbox panel.subpanels).act panel events )
; subpanels= ; subpanels=