fix: compiles again
Some checks failed
/ build (push) Has been cancelled

This commit is contained in:
🪞👃🪞 2025-07-19 20:25:42 +03:00
parent 71c519b711
commit 4fbd6ab408
3 changed files with 37 additions and 95 deletions

View file

@ -7,10 +7,11 @@ macro_rules! cmd_todo { ($msg:literal) => {{ println!($msg); None }}; }
handle!(TuiIn: |self: App, input|self.handle_tui_key_with_history(input)); handle!(TuiIn: |self: App, input|self.handle_tui_key_with_history(input));
impl App { impl App {
fn handle_tui_key_with_history (&mut self, input: &TuiIn) -> Perhaps<bool> { fn handle_tui_key_with_history (&mut self, input: &TuiIn) -> Perhaps<bool> {
Ok(if let Some(command) = self.config.keys.handle(self, input)? { Ok(if let Some(binding) = self.config.keys.dispatch(input.event()) {
// FIXME failed commands not persisted in undo history let binding = binding.clone();
let undo = command.clone().execute(self)?; let undo = binding.command.clone().execute(self)?;
self.history.push((command, undo)); // FIXME failed commands are not persisted in undo history
//self.history.push((binding.command.clone(), undo));
Some(true) Some(true)
} else { } else {
None None

View file

@ -1,5 +1,6 @@
use crate::*; use crate::*;
use std::path::PathBuf; use std::path::PathBuf;
use std::error::Error;
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct App { pub struct App {
/// Must not be dropped for the duration of the process /// Must not be dropped for the duration of the process
@ -9,7 +10,7 @@ pub struct App {
/// Performance counter /// Performance counter
pub perf: PerfModel, pub perf: PerfModel,
// View and input definition // View and input definition
pub config: Configuration<Ast>, pub config: Configuration,
/// Contains all recently created clips. /// Contains all recently created clips.
pub pool: Pool, pub pool: Pool,
/// Contains the currently edited musical arrangement /// Contains the currently edited musical arrangement
@ -319,7 +320,7 @@ impl App {
/// Configuration /// Configuration
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Configuration<T: Dsl> { pub struct Configuration {
/// Path of configuration entrypoint /// Path of configuration entrypoint
pub path: PathBuf, pub path: PathBuf,
/// Name of configuration /// Name of configuration
@ -327,99 +328,39 @@ pub struct Configuration<T: Dsl> {
/// Description of configuration /// Description of configuration
pub info: Option<Arc<str>>, pub info: Option<Arc<str>>,
/// View definition /// View definition
pub view: T, pub view: Arc<str>,
// Input keymap // Input keymap
pub keys: EventMap<TuiEvent, T>, pub keys: EventMap<TuiEvent, AppCommand>,
} }
impl<T: Dsl> Configuration<T> { impl Configuration {
pub fn from_path (path: &impl AsRef<Path>, _watch: bool) -> Usually<Self> where T: for<'a> From<&'a str> { pub fn from_path (path: &impl AsRef<Path>, _watch: bool) -> Usually<Self> {
let mut dsl = T::from(read_and_leak(path.as_ref())?); let mut config = Self::default();
let mut name: Option<T::Exp> = None; config.path = path.as_ref().into();
let mut info: Option<T::Exp> = None; let mut dsl = read_and_leak(path.as_ref())?;
let mut view: Option<T::Exp> = None; while let Some(mut exp) = dsl.exp_next()? {
let mut keys: Option<T::Exp> = None; match exp.exp_head()?.key()? {
dsl.exp_each(|form|Ok(match form.exp_head().dsl() { Some("name") => match exp.text()? {
Val::Key(key) => match key.as_ref() { Some(name) => config.name = Some(name.into()),
"name" => name = Some(form.exp_tail()), _ => return Err(format!("missing name definition").into())
"info" => info = Some(form.exp_tail()),
"keys" => keys = Some(form.exp_tail()),
"view" => view = Some(form.exp_tail()),
_ => return Err(format!("(e3) unexpected key {key:?} in {form:?}").into())
}, },
_ => return Err(format!("(e2) unexpected exp {form :?}").into()) Some("info") => match exp.text()? {
}))?; Some(info) => config.info = Some(info.into()),
Ok(Self { _ => return Err(format!("missing info definition").into())
path: path.as_ref().into(), },
info: info.map(Self::parse_info).flatten(), Some("keys") => match exp.text()? {
name: name.map(Self::parse_name).flatten(), Some(keys) => config.keys = EventMap::from_dsl(keys)?,
view: Self::parse_view(view)?.into(), _ => return Err(format!("missing keys definition").into())
keys: Self::parse_keys(&path, keys)?.into(), },
}) Some("view") => match exp.exp_tail()? {
} Some(tail) => config.view = tail.src().into(),
fn parse_name (dsl: T) -> Option<Arc<str>> { _ => return Err(format!("missing view definition").into())
dsl.str().map(Into::into) },
} Some(k) => return Err(format!("(e3) unexpected key {k:?} in {exp:?}").into()),
fn parse_info (dsl: T) -> Option<Arc<str>> { None => return Err(format!("(e2) unexpected exp {exp:?}").into()),
dsl.str().map(Into::into)
}
fn parse_view (dsl: Option<T>) -> Usually<T> {
match dsl { Some(view) => Ok(view), _ => Err(format!("missing view definition").into()) }
}
fn parse_keys (base: &impl AsRef<Path>, dsl: Option<T>) -> Usually<EventMap<TuiIn, T>> {
let mut map = EventMap::default();
let mut keys = if let Some(keys) = dsl { keys } else {
return Err(format!("missing keys definition").into())
};
keys.exp_each(|form|Ok(match form.exp_head().dsl() {
Val::Sym(s) if s.as_ref() == "layer" =>
Self::parse_keys_layer(&mut map, base, form.exp_tail()),
Val::Sym(s) if s.as_ref() == "layer-if" =>
Self::parse_keys_layer_if(&mut map, base, form.exp_tail()),
x =>
return Err(format!("(e3) unexpected {x:?} in {form:?}").into())
}))?;
Ok(map)
}
fn parse_keys_layer (map: &mut EventMap<TuiIn, T>, base: &impl AsRef<Path>, exp: &T) {
let next = exp.peek().map(|x|x.val());
if let Some(Val::Str(path)) = next {
let path = base.as_ref().parent().unwrap().join(unquote(path));
if !std::fs::exists(&path)? {
return Err(format!("(e5) not found: {path:?}").into())
}
map.add_layer(read_and_leak(path)?.into());
print!("layer:\n path: {:?}...", exp.0.0.trim());
println!("ok");
} else {
return Err(format!("(e4) unexpected non-string {next:?}").into())
} }
} }
fn parse_keys_layer_if (map: &mut EventMap<TuiIn, T>, base: &impl AsRef<Path>, exp: &T) { Ok(config)
let next = exp.next().map(|x|x.val());
let cond = if let Some(Val::Sym(sym)) = next {
leak(sym)
} else {
return Err(format!("(e4) unexpected non-symbol {next:?}").into())
};
let next = exp.peek().map(|x|x.val());
if let Some(Val::Str(path)) = next {
let path = base.as_ref().parent().unwrap().join(unquote(path));
if !std::fs::exists(&path)? {
return Err(format!("(e5) not found: {path:?}").into())
}
print!("layer-if:\n cond: {cond}\n path: {path:?}...");
let keys = read_and_leak(path)?.into();
println!("ok");
//map.add_layer_if(
//Box::new(move |state: &App|Take::take_or_fail(
//state, exp, ||"missing input layer conditional"
//)), keys
//);
} else {
return Err(format!("(e4) unexpected non-symbol {next:?}").into())
}
} }
} }

2
deps/tengri vendored

@ -1 +1 @@
Subproject commit 7b67d29c012f2d39a5d9d2fcd840417c90256503 Subproject commit 360b404b69abb1ec4e0e9959667e08d4b99c6131