diff --git a/Cargo.lock b/Cargo.lock index cf2b08e0..b6669678 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2456,7 +2456,7 @@ dependencies = [ [[package]] name = "tengri" -version = "0.13.0" +version = "0.14.0" dependencies = [ "tengri_core", "tengri_dsl", @@ -2467,11 +2467,11 @@ dependencies = [ [[package]] name = "tengri_core" -version = "0.13.0" +version = "0.14.0" [[package]] name = "tengri_dsl" -version = "0.13.0" +version = "0.14.0" dependencies = [ "const_panic", "itertools 0.14.0", @@ -2482,15 +2482,14 @@ dependencies = [ [[package]] name = "tengri_input" -version = "0.13.0" +version = "0.14.0" dependencies = [ "tengri_core", - "tengri_dsl", ] [[package]] name = "tengri_output" -version = "0.13.0" +version = "0.14.0" dependencies = [ "tengri_core", "tengri_dsl", @@ -2498,7 +2497,7 @@ dependencies = [ [[package]] name = "tengri_proc" -version = "0.13.0" +version = "0.14.0" dependencies = [ "heck", "proc-macro2", @@ -2509,7 +2508,7 @@ dependencies = [ [[package]] name = "tengri_tui" -version = "0.13.0" +version = "0.14.0" dependencies = [ "atomic_float", "better-panic", diff --git a/crates/config/config.rs b/crates/config/config.rs index ac485ef7..a44e955f 100644 --- a/crates/config/config.rs +++ b/crates/config/config.rs @@ -7,15 +7,16 @@ use ::{ path::PathBuf }, tengri::{ - Usually, - input::{EventMap, Binding}, + Usually, impl_debug, tui::TuiEvent, dsl::{Dsl, DslWord, DslExpr} }, xdg::BaseDirectories, }; -/// Configuration +/// Configuration. +/// +/// Contains mode, view, and bind definitions. #[derive(Default, Debug)] pub struct Config { pub dirs: BaseDirectories, @@ -24,6 +25,8 @@ pub struct Config { pub binds: Arc, EventMap>>>>, } +/// A set of currently active view and keys definitions, +/// with optional name and description. #[derive(Default, Debug)] pub struct Mode { pub path: PathBuf, @@ -34,6 +37,28 @@ pub struct Mode { pub modes: BTreeMap>, } +/// A collection of input bindings. +#[derive(Debug)] +pub struct EventMap( + /// Map of each event (e.g. key combination) to + /// all command expressions bound to it by + /// all loaded input layers. + pub BTreeMap>> +); + +/// An input binding. +#[derive(Debug, Clone)] +pub struct Binding { + pub commands: Arc<[C]>, + pub condition: Option, + pub description: Option>, + pub source: Option>, +} + +/// Input bindings are only returned if this evaluates to true +#[derive(Clone)] +pub struct Condition(Arcbool + Send + Sync>>); + impl Config { const CONFIG: &'static str = "tek.edn"; const DEFAULTS: &'static str = include_str!("../../tek.edn"); @@ -135,3 +160,54 @@ impl Config { }) } } + +/// Default is always empty map regardless if `E` and `C` implement [Default]. +impl Default for EventMap { + fn default () -> Self { Self(Default::default()) } +} + +impl EventMap { + /// Create a new event map + pub fn new () -> Self { + Default::default() + } + /// Add a binding to an owned event map. + pub fn def (mut self, event: E, binding: Binding) -> Self { + self.add(event, binding); + self + } + /// Add a binding to an event map. + pub fn add (&mut self, event: E, binding: Binding) -> &mut Self { + if !self.0.contains_key(&event) { + self.0.insert(event.clone(), Default::default()); + } + self.0.get_mut(&event).unwrap().push(binding); + self + } + /// Return the binding(s) that correspond to an event. + pub fn query (&self, event: &E) -> Option<&[Binding]> { + self.0.get(event).map(|x|x.as_slice()) + } + /// Return the first binding that corresponds to an event, considering conditions. + pub fn dispatch (&self, event: &E) -> Option<&Binding> { + self.query(event) + .map(|bb|bb.iter().filter(|b|b.condition.as_ref().map(|c|(c.0)()).unwrap_or(true)).next()) + .flatten() + } +} + +impl Binding { + pub fn from_dsl (dsl: impl Dsl) -> Usually { + let command: Option = None; + let condition: Option = None; + let description: Option> = None; + let source: Option> = None; + if let Some(command) = command { + Ok(Self { commands: [command].into(), condition, description, source }) + } else { + Err(format!("no command in {dsl:?}").into()) + } + } +} + +impl_debug!(Condition |self, w| { write!(w, "*") }); diff --git a/deps/tengri b/deps/tengri index 06217939..e3e3c163 160000 --- a/deps/tengri +++ b/deps/tengri @@ -1 +1 @@ -Subproject commit 062179393037dc948a09aa24cb0000b6ef1dea8e +Subproject commit e3e3c163da02165e77a259eb715749b7f0097498