diff --git a/cove-input/src/event.rs b/cove-input/src/event.rs new file mode 100644 index 0000000..0a92b83 --- /dev/null +++ b/cove-input/src/event.rs @@ -0,0 +1,100 @@ +use crossterm::event::KeyEvent; + +use crate::KeyBinding; + +enum Mode { + Record, + Key(KeyEvent), + Paste(String), +} + +impl Mode { + fn from_crossterm_event(event: crossterm::event::Event) -> Option { + use crossterm::event::Event::*; + match event { + Key(event) => Some(Self::Key(event)), + Paste(string) => Some(Self::Paste(string)), + _ => None, + } + } +} + +pub enum Entry { + Space, + Category(String), + Binding(KeyBinding, String), +} + +pub struct InputEvent { + mode: Mode, + entries: Vec, +} + +impl InputEvent { + pub fn new_recording() -> Self { + Self { + mode: Mode::Record, + entries: vec![], + } + } + + pub fn from_crossterm_event(event: crossterm::event::Event) -> Option { + Some(Self { + mode: Mode::from_crossterm_event(event)?, + entries: vec![], + }) + } + + fn recording(&self) -> bool { + matches!(self.mode, Mode::Record) + } + + pub fn space(&mut self) { + if self.recording() { + self.entries.push(Entry::Space); + } + } + + pub fn category(&mut self, name: S) { + if self.recording() { + self.entries.push(Entry::Category(name.to_string())); + } + } + + pub fn key_event(&self) -> Option { + if let Mode::Key(event) = &self.mode { + Some(*event) + } else { + None + } + } + + pub fn paste_event(&self) -> Option<&str> { + if let Mode::Paste(string) = &self.mode { + Some(string) + } else { + None + } + } + + pub fn matches_key_binding( + &mut self, + binding: &KeyBinding, + description: S, + ) -> bool { + if self.recording() { + self.entries + .push(Entry::Binding(binding.clone(), description.to_string())); + } + + if let Some(event) = self.key_event() { + binding.matches(event) + } else { + false + } + } + + pub fn entries(&self) -> &[Entry] { + &self.entries + } +} diff --git a/cove-input/src/input.rs b/cove-input/src/input.rs deleted file mode 100644 index 5e424ce..0000000 --- a/cove-input/src/input.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crossterm::event::KeyEvent; - -use crate::KeyBinding; - -pub enum Entry { - Space, - Category(String), - Binding(KeyBinding, String), -} - -pub struct Input { - event: Option, - - record_entries: bool, - entries: Vec, -} - -impl Input { - pub fn new_from_event(event: KeyEvent) -> Self { - Self { - event: Some(event), - record_entries: false, - entries: vec![], - } - } - - pub fn new_recording() -> Self { - Self { - event: None, - record_entries: true, - entries: vec![], - } - } - - pub fn space(&mut self) { - if self.record_entries { - self.entries.push(Entry::Space); - } - } - - pub fn category(&mut self, name: S) { - if self.record_entries { - self.entries.push(Entry::Category(name.to_string())); - } - } - - pub fn matches(&mut self, binding: &KeyBinding, description: S) -> bool { - let matches = if let Some(event) = self.event { - binding.matches(event) - } else { - false - }; - - if self.record_entries { - self.entries - .push(Entry::Binding(binding.clone(), description.to_string())); - } - - matches - } - - pub fn entries(&self) -> &[Entry] { - &self.entries - } -} diff --git a/cove-input/src/lib.rs b/cove-input/src/lib.rs index 4129adf..901f48e 100644 --- a/cove-input/src/lib.rs +++ b/cove-input/src/lib.rs @@ -1,14 +1,14 @@ -mod input; +mod event; mod keys; pub use cove_macro::KeyGroup; -pub use input::*; +pub use event::*; pub use keys::*; /// A group of related key bindings. pub trait KeyGroup { type Event; - fn event(&self, input: &mut Input) -> Option; + fn match_input_event(&self, event: &mut InputEvent) -> Option; } diff --git a/cove-macro/src/key_group.rs b/cove-macro/src/key_group.rs index 83cec49..3876956 100644 --- a/cove-macro/src/key_group.rs +++ b/cove-macro/src/key_group.rs @@ -38,7 +38,7 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result { let description = decapitalize(&docstring); let description = description.strip_suffix('.').unwrap_or(&description); match_cases.push(quote!{ - () if input.matches(&self.#field_ident, #description) => Some(Self::Event::#variant_ident), + () if event.matches_key_binding(&self.#field_ident, #description) => Some(Self::Event::#variant_ident), }); } } @@ -52,7 +52,7 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result { impl ::cove_input::KeyGroup for #struct_ident { type Event = #enum_ident; - fn event(&self, input: &mut ::cove_input::Input) -> Option { + fn match_input_event(&self, event: &mut ::cove_input::InputEvent) -> Option { match () { #( #match_cases )* () => None,