config: extract
Some checks are pending
/ build (push) Waiting to run

This commit is contained in:
🪞👃🪞 2025-08-23 13:47:56 +03:00
parent 17c6184f0e
commit 5ccbb9719f
3 changed files with 87 additions and 12 deletions

15
Cargo.lock generated
View file

@ -2456,7 +2456,7 @@ dependencies = [
[[package]] [[package]]
name = "tengri" name = "tengri"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"tengri_core", "tengri_core",
"tengri_dsl", "tengri_dsl",
@ -2467,11 +2467,11 @@ dependencies = [
[[package]] [[package]]
name = "tengri_core" name = "tengri_core"
version = "0.13.0" version = "0.14.0"
[[package]] [[package]]
name = "tengri_dsl" name = "tengri_dsl"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"const_panic", "const_panic",
"itertools 0.14.0", "itertools 0.14.0",
@ -2482,15 +2482,14 @@ dependencies = [
[[package]] [[package]]
name = "tengri_input" name = "tengri_input"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"tengri_core", "tengri_core",
"tengri_dsl",
] ]
[[package]] [[package]]
name = "tengri_output" name = "tengri_output"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"tengri_core", "tengri_core",
"tengri_dsl", "tengri_dsl",
@ -2498,7 +2497,7 @@ dependencies = [
[[package]] [[package]]
name = "tengri_proc" name = "tengri_proc"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
@ -2509,7 +2508,7 @@ dependencies = [
[[package]] [[package]]
name = "tengri_tui" name = "tengri_tui"
version = "0.13.0" version = "0.14.0"
dependencies = [ dependencies = [
"atomic_float", "atomic_float",
"better-panic", "better-panic",

View file

@ -7,15 +7,16 @@ use ::{
path::PathBuf path::PathBuf
}, },
tengri::{ tengri::{
Usually, Usually, impl_debug,
input::{EventMap, Binding},
tui::TuiEvent, tui::TuiEvent,
dsl::{Dsl, DslWord, DslExpr} dsl::{Dsl, DslWord, DslExpr}
}, },
xdg::BaseDirectories, xdg::BaseDirectories,
}; };
/// Configuration /// Configuration.
///
/// Contains mode, view, and bind definitions.
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Config { pub struct Config {
pub dirs: BaseDirectories, pub dirs: BaseDirectories,
@ -24,6 +25,8 @@ pub struct Config {
pub binds: Arc<RwLock<BTreeMap<Arc<str>, EventMap<TuiEvent, Arc<str>>>>>, pub binds: Arc<RwLock<BTreeMap<Arc<str>, EventMap<TuiEvent, Arc<str>>>>>,
} }
/// A set of currently active view and keys definitions,
/// with optional name and description.
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Mode<D: Dsl + Ord> { pub struct Mode<D: Dsl + Ord> {
pub path: PathBuf, pub path: PathBuf,
@ -34,6 +37,28 @@ pub struct Mode<D: Dsl + Ord> {
pub modes: BTreeMap<D, Mode<D>>, pub modes: BTreeMap<D, Mode<D>>,
} }
/// A collection of input bindings.
#[derive(Debug)]
pub struct EventMap<E, C>(
/// Map of each event (e.g. key combination) to
/// all command expressions bound to it by
/// all loaded input layers.
pub BTreeMap<E, Vec<Binding<C>>>
);
/// An input binding.
#[derive(Debug, Clone)]
pub struct Binding<C> {
pub commands: Arc<[C]>,
pub condition: Option<Condition>,
pub description: Option<Arc<str>>,
pub source: Option<Arc<PathBuf>>,
}
/// Input bindings are only returned if this evaluates to true
#[derive(Clone)]
pub struct Condition(Arc<Box<dyn Fn()->bool + Send + Sync>>);
impl Config { impl Config {
const CONFIG: &'static str = "tek.edn"; const CONFIG: &'static str = "tek.edn";
const DEFAULTS: &'static str = include_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<E, C> Default for EventMap<E, C> {
fn default () -> Self { Self(Default::default()) }
}
impl<E: Clone + Ord, C> EventMap<E, C> {
/// 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<C>) -> Self {
self.add(event, binding);
self
}
/// Add a binding to an event map.
pub fn add (&mut self, event: E, binding: Binding<C>) -> &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<C>]> {
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<C>> {
self.query(event)
.map(|bb|bb.iter().filter(|b|b.condition.as_ref().map(|c|(c.0)()).unwrap_or(true)).next())
.flatten()
}
}
impl<C> Binding<C> {
pub fn from_dsl (dsl: impl Dsl) -> Usually<Self> {
let command: Option<C> = None;
let condition: Option<Condition> = None;
let description: Option<Arc<str>> = None;
let source: Option<Arc<PathBuf>> = 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, "*") });

2
deps/tengri vendored

@ -1 +1 @@
Subproject commit 062179393037dc948a09aa24cb0000b6ef1dea8e Subproject commit e3e3c163da02165e77a259eb715749b7f0097498