mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-07-18 00:06:59 +02:00
Some checks are pending
/ build (push) Waiting to run
gotta replace that Measure thing with RwLock<[u16;2]>
99 lines
3.5 KiB
Rust
99 lines
3.5 KiB
Rust
use crate::{*, config::*};
|
|
|
|
impl Config {
|
|
pub fn get_mode (&self, mode: impl AsRef<str>) -> Option<Arc<Mode<Arc<str>>>> {
|
|
self.modes.clone().read().unwrap().get(mode.as_ref()).cloned()
|
|
}
|
|
}
|
|
|
|
pub(crate) fn load_mode (modes: &Modes, name: &impl AsRef<str>, body: &impl Language) -> Usually<()> {
|
|
let mut mode = Mode::default();
|
|
body.each(|item|mode.add(item))?;
|
|
modes.write().unwrap().insert(name.as_ref().into(), Arc::new(mode));
|
|
Ok(())
|
|
}
|
|
|
|
/// Collection of interaction modes.
|
|
pub type Modes = Arc<RwLock<BTreeMap<Arc<str>, Arc<Mode<Arc<str>>>>>>;
|
|
|
|
impl Mode<Arc<str>> {
|
|
/// Add a definition to the mode.
|
|
///
|
|
/// Supported definitions:
|
|
///
|
|
/// - (name ...) -> name
|
|
/// - (info ...) -> description
|
|
/// - (keys ...) -> key bindings
|
|
/// - (mode ...) -> submode
|
|
/// - ... -> view
|
|
///
|
|
/// ```
|
|
/// let mut mode: tek::Mode<std::sync::Arc<str>> = Default::default();
|
|
/// mode.add("(name hello)").unwrap();
|
|
/// ```
|
|
pub fn add (&mut self, dsl: impl Language) -> Usually<()> {
|
|
Ok(if let Ok(Some(expr)) = dsl.expr() && let Ok(Some(head)) = expr.head() {
|
|
//println!("Mode::add: {head} {:?}", expr.tail());
|
|
let tail = expr.tail()?.map(|x|x.trim()).unwrap_or("");
|
|
match head {
|
|
"name" => self.add_name(tail)?,
|
|
"info" => self.add_info(tail)?,
|
|
"keys" => self.add_keys(tail)?,
|
|
"mode" => self.add_mode(tail)?,
|
|
_ => self.add_view(tail)?,
|
|
};
|
|
} else if let Ok(Some(word)) = dsl.word() {
|
|
self.add_view(word);
|
|
} else {
|
|
return Err(format!("Mode::add: unexpected: {dsl:?}").into());
|
|
})
|
|
|
|
//DslParse(dsl, ||Err(format!("Mode::add: unexpected: {dsl:?}").into()))
|
|
//.word(|word|self.add_view(word))
|
|
//.expr(|expr|expr.head(|head|{
|
|
////println!("Mode::add: {head} {:?}", expr.tail());
|
|
//let tail = expr.tail()?.map(|x|x.trim()).unwrap_or("");
|
|
//match head {
|
|
//"name" => self.add_name(tail),
|
|
//"info" => self.add_info(tail),
|
|
//"keys" => self.add_keys(tail)?,
|
|
//"mode" => self.add_mode(tail)?,
|
|
//_ => self.add_view(tail),
|
|
//};
|
|
//}))
|
|
}
|
|
|
|
fn add_name (&mut self, dsl: impl Language) -> Perhaps<()> {
|
|
Ok(dsl.src()?.map(|src|self.name.push(src.into())))
|
|
}
|
|
fn add_info (&mut self, dsl: impl Language) -> Perhaps<()> {
|
|
Ok(dsl.src()?.map(|src|self.info.push(src.into())))
|
|
}
|
|
fn add_view (&mut self, dsl: impl Language) -> Perhaps<()> {
|
|
Ok(dsl.src()?.map(|src|self.view.push(src.into())))
|
|
}
|
|
fn add_keys (&mut self, dsl: impl Language) -> Perhaps<()> {
|
|
Ok(Some(dsl.each(|expr|{ self.keys.push(expr.trim().into()); Ok(()) })?))
|
|
}
|
|
fn add_mode (&mut self, dsl: impl Language) -> Perhaps<()> {
|
|
Ok(Some(if let Some(id) = dsl.head()? {
|
|
load_mode(&self.modes, &id, &dsl.tail())?;
|
|
} else {
|
|
return Err(format!("Mode::add: self: incomplete: {dsl:?}").into());
|
|
}))
|
|
}
|
|
}
|
|
/// Group of view and keys definitions.
|
|
///
|
|
/// ```
|
|
/// let mode = tek::Mode::<std::sync::Arc<str>>::default();
|
|
/// ```
|
|
#[derive(Default, Debug)] pub struct Mode<D: Language + Ord> {
|
|
pub path: PathBuf,
|
|
pub name: Vec<D>,
|
|
pub info: Vec<D>,
|
|
pub view: Vec<D>,
|
|
pub keys: Vec<D>,
|
|
pub modes: Modes,
|
|
}
|
|
|