mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 03:36:41 +01:00
58 lines
2 KiB
Rust
58 lines
2 KiB
Rust
use super::*;
|
|
|
|
pub type Modes = Arc<RwLock<BTreeMap<Arc<str>, Arc<Mode<Arc<str>>>>>>;
|
|
|
|
/// A set of currently active view and keys definitions,
|
|
/// with optional name and description.
|
|
#[derive(Default, Debug)]
|
|
pub struct Mode<D: Dsl + Ord> {
|
|
pub path: PathBuf,
|
|
pub name: Vec<D>,
|
|
pub info: Vec<D>,
|
|
pub view: Vec<D>,
|
|
pub keys: Vec<D>,
|
|
pub modes: Modes,
|
|
}
|
|
|
|
impl<D: Dsl + Ord> Draw<TuiOut> for Mode<D> {
|
|
fn draw (&self, to: &mut TuiOut) {
|
|
self.content().draw(to)
|
|
}
|
|
}
|
|
|
|
impl Mode<Arc<str>> {
|
|
|
|
pub fn load_into (modes: &Modes, name: &impl AsRef<str>, body: &impl Dsl) -> Usually<()> {
|
|
let mut mode = Self::default();
|
|
println!("Mode::load_into: {}: {body:?}", name.as_ref());
|
|
body.each(|item|mode.load_one(item))?;
|
|
modes.write().unwrap().insert(name.as_ref().into(), Arc::new(mode));
|
|
Ok(())
|
|
}
|
|
|
|
fn load_one (&mut self, dsl: impl Dsl) -> Usually<()> {
|
|
Ok(if let Ok(Some(expr)) = dsl.expr() && let Ok(Some(head)) = expr.head() {
|
|
println!("Mode::load_one: {head} {:?}", expr.tail());
|
|
let tail = expr.tail()?.map(|x|x.trim()).unwrap_or("");
|
|
match head {
|
|
"name" => self.name.push(tail.into()),
|
|
"info" => self.info.push(tail.into()),
|
|
"view" => self.view.push(tail.into()),
|
|
"keys" => tail.each(|expr|{self.keys.push(expr.trim().into()); Ok(())})?,
|
|
"mode" => if let Some(id) = tail.head()? {
|
|
Self::load_into(&self.modes, &id, &tail.tail())?;
|
|
} else {
|
|
return Err(format!("Mode::load_one: self: incomplete: {expr:?}").into());
|
|
},
|
|
_ => {
|
|
return Err(format!("Mode::load_one: unexpected expr: {head:?} {tail:?}").into())
|
|
},
|
|
};
|
|
} else if let Ok(Some(word)) = dsl.word() {
|
|
self.view.push(word.into());
|
|
} else {
|
|
return Err(format!("Mode::load_one: unexpected: {dsl:?}").into());
|
|
})
|
|
}
|
|
|
|
}
|