diff --git a/crates/modalkit-ratatui/examples/editor.rs b/crates/modalkit-ratatui/examples/editor.rs index fb8c6e0..ff28a36 100644 --- a/crates/modalkit-ratatui/examples/editor.rs +++ b/crates/modalkit-ratatui/examples/editor.rs @@ -54,7 +54,7 @@ use modalkit::{ rope::EditRope, store::Store, }, - env::mixed::{MixedBindings, MixedChoice}, + env::mixed::{MixedChoice, MixedMachine}, env::vim::command::{complete_cmdbar, VimCommandMachine}, errors::{EditError, EditResult, UIError, UIResult}, key::TerminalKey, @@ -546,7 +546,7 @@ impl Editor { let mut store = Store::default(); store.completer = Box::new(EditorCompleter); - let bindings = MixedBindings::::from(env); + let bindings = MixedMachine::::from(env); let bindings = KeyManager::new(bindings); let buf = store.load_buffer(EditorContentId::Scratch); diff --git a/crates/modalkit/src/env/mixed.rs b/crates/modalkit/src/env/mixed.rs index 3f73407..e3179b7 100644 --- a/crates/modalkit/src/env/mixed.rs +++ b/crates/modalkit/src/env/mixed.rs @@ -12,19 +12,20 @@ use crate::{ editing::context::EditContext, editing::cursor::CursorStyle, key::TerminalKey, - keybindings::{dialog::Dialog, BindingMachine, InputKey, Step}, + keybindings::{dialog::Dialog, BindingMachine, InputBindings, InputKey, Step}, prelude::RepeatType, }; use super::{ emacs::{ - keybindings::{default_emacs_keys, EmacsMachine, InputStep as EmacsStep}, + keybindings::{default_emacs_keys, EmacsBindings, EmacsMachine, InputStep as EmacsStep}, EmacsState, }, vim::{ - keybindings::{default_vim_keys, InputStep as VimStep, VimMachine}, + keybindings::{default_vim_keys, InputStep as VimStep, VimBindings, VimMachine}, VimState, }, + ShellBindings, }; /// Multiple keybinding styles that users can select. @@ -41,27 +42,66 @@ pub enum MixedChoice { macro_rules! delegate_bindings { ($s: expr, $invoke: expr) => { match $s { - MixedBindings::Emacs(c) => $invoke(c), - MixedBindings::Vim(c) => $invoke(c), + MixedMachine::Emacs(c) => $invoke(c), + MixedMachine::Vim(c) => $invoke(c), } }; ($s: expr, $invoke: expr, $arg: expr) => { match $s { - MixedBindings::Emacs(c) => $invoke(c, $arg), - MixedBindings::Vim(c) => $invoke(c, $arg), + MixedMachine::Emacs(c) => $invoke(c, $arg), + MixedMachine::Vim(c) => $invoke(c, $arg), } }; ($s: expr, $invoke: expr, $arg1: expr, $arg2: expr) => { match $s { - MixedBindings::Emacs(c) => $invoke(c, $arg1, $arg2), - MixedBindings::Vim(c) => $invoke(c, $arg1, $arg2), + MixedMachine::Emacs(c) => $invoke(c, $arg1, $arg2), + MixedMachine::Vim(c) => $invoke(c, $arg1, $arg2), } }; } /// Type for wrapping different keybindings in contexts where keybindings can be determined /// dynamically. -pub enum MixedBindings +#[non_exhaustive] +pub enum MixedBindings +where + I: ApplicationInfo, +{ + /// Wrap Emacs bindings. + Emacs(EmacsBindings), + + /// Wrap Vim bindings. + Vim(VimBindings), +} + +impl ShellBindings for MixedBindings +where + I: ApplicationInfo, +{ + fn shell(self) -> Self { + match self { + MixedBindings::Emacs(b) => MixedBindings::Emacs(b.shell()), + MixedBindings::Vim(b) => MixedBindings::Vim(b.shell()), + } + } +} + +impl From for MixedBindings +where + I: ApplicationInfo, +{ + fn from(choice: MixedChoice) -> Self { + match choice { + MixedChoice::Emacs => MixedBindings::Emacs(EmacsBindings::default()), + MixedChoice::Vim => MixedBindings::Vim(VimBindings::default()), + } + } +} + +/// Type for wrapping different [BindingMachine] values in contexts where keybindings can be +/// determined dynamically. +#[non_exhaustive] +pub enum MixedMachine where K: InputKey, I: ApplicationInfo, @@ -75,20 +115,41 @@ where Vim(VimMachine), } -impl From for MixedBindings +impl From for MixedMachine where I: ApplicationInfo, { fn from(choice: MixedChoice) -> Self { match choice { - MixedChoice::Emacs => MixedBindings::Emacs(default_emacs_keys()), - MixedChoice::Vim => MixedBindings::Vim(default_vim_keys()), + MixedChoice::Emacs => MixedMachine::Emacs(default_emacs_keys()), + MixedChoice::Vim => MixedMachine::Vim(default_vim_keys()), + } + } +} + +impl From> for MixedMachine +where + I: ApplicationInfo, +{ + fn from(bindings: MixedBindings) -> Self { + match bindings { + MixedBindings::Emacs(b) => { + let mut machine = EmacsMachine::empty(); + b.setup(&mut machine); + + MixedMachine::Emacs(machine) + }, + MixedBindings::Vim(b) => { + let mut machine = VimMachine::empty(); + b.setup(&mut machine); + + MixedMachine::Vim(machine) + }, } } } -impl BindingMachine, RepeatType, EditContext, CursorStyle> - for MixedBindings +impl BindingMachine, RepeatType, EditContext, CursorStyle> for MixedMachine where K: InputKey, I: ApplicationInfo,