use crate::*; /// Group of view and keys definitions. /// /// ``` /// let mode = tek::Mode::>::default(); /// ``` #[derive(Default, Debug)] pub struct Mode { pub path: PathBuf, pub name: Vec, pub info: Vec, pub view: Vec, pub keys: Vec, pub modes: Modes, } impl Mode> { /// Add a definition to the mode. /// /// Supported definitions: /// /// - (name ...) -> name /// - (info ...) -> description /// - (keys ...) -> key bindings /// - (mode ...) -> submode /// - ... -> view /// /// ``` /// let mut mode: tek::Mode> = 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()? { self.modes.add(&id, &dsl.tail())?; } else { return Err(format!("Mode::add: self: incomplete: {dsl:?}").into()); })) } }