mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 03:36:42 +01:00
This commit is contained in:
parent
643658ab16
commit
a601d3d806
3 changed files with 84 additions and 99 deletions
|
|
@ -1,10 +1,9 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use std::{sync::Arc, collections::BTreeMap, path::{Path, PathBuf}, fs::{exists, read_to_string}};
|
||||||
/// Map of each event (e.g. key combination) to
|
/// Map of each event (e.g. key combination) to
|
||||||
/// all command expressions bound to it by
|
/// all command expressions bound to it by
|
||||||
/// all loaded input layers.
|
/// all loaded input layers.
|
||||||
type EventMapImpl<E, C> = BTreeMap<E, Vec<Binding<C>>>;
|
type EventMapImpl<E, C> = BTreeMap<E, Vec<Binding<C>>>;
|
||||||
|
|
||||||
/// A collection of input bindings.
|
/// A collection of input bindings.
|
||||||
///
|
///
|
||||||
/// Each contained layer defines a mapping from input event to command invocation
|
/// Each contained layer defines a mapping from input event to command invocation
|
||||||
|
|
@ -16,7 +15,6 @@ type EventMapImpl<E, C> = BTreeMap<E, Vec<Binding<C>>>;
|
||||||
/// that .event()binding's value is returned.
|
/// that .event()binding's value is returned.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EventMap<E, C>(EventMapImpl<E, C>);
|
pub struct EventMap<E, C>(EventMapImpl<E, C>);
|
||||||
|
|
||||||
/// An input binding.
|
/// An input binding.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Binding<C> {
|
pub struct Binding<C> {
|
||||||
|
|
@ -25,18 +23,14 @@ pub struct Binding<C> {
|
||||||
pub description: Option<Arc<str>>,
|
pub description: Option<Arc<str>>,
|
||||||
pub source: Option<Arc<PathBuf>>,
|
pub source: Option<Arc<PathBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Input bindings are only returned if this evaluates to true
|
/// Input bindings are only returned if this evaluates to true
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Condition(Arc<Box<dyn Fn()->bool + Send + Sync>>);
|
pub struct Condition(Arc<Box<dyn Fn()->bool + Send + Sync>>);
|
||||||
|
|
||||||
impl_debug!(Condition |self, w| { write!(w, "*") });
|
impl_debug!(Condition |self, w| { write!(w, "*") });
|
||||||
|
|
||||||
/// Default is always empty map regardless if `E` and `C` implement [Default].
|
/// Default is always empty map regardless if `E` and `C` implement [Default].
|
||||||
impl<E, C> Default for EventMap<E, C> {
|
impl<E, C> Default for EventMap<E, C> {
|
||||||
fn default () -> Self { Self(Default::default()) }
|
fn default () -> Self { Self(Default::default()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Clone + Ord, C> EventMap<E, C> {
|
impl<E: Clone + Ord, C> EventMap<E, C> {
|
||||||
/// Create a new event map
|
/// Create a new event map
|
||||||
pub fn new () -> Self {
|
pub fn new () -> Self {
|
||||||
|
|
@ -68,7 +62,7 @@ impl<E: Clone + Ord, C> EventMap<E, C> {
|
||||||
/// Create event map from path to text file.
|
/// Create event map from path to text file.
|
||||||
pub fn from_path <P: AsRef<Path>> (path: P) -> Usually<Self> where E: From<Arc<str>> {
|
pub fn from_path <P: AsRef<Path>> (path: P) -> Usually<Self> where E: From<Arc<str>> {
|
||||||
if exists(path.as_ref())? {
|
if exists(path.as_ref())? {
|
||||||
Self::from_source(read_and_leak(path)?)
|
Self::from_source(read_to_string(path)?)
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("(e5) not found: {:?}", path.as_ref()).into())
|
return Err(format!("(e5) not found: {:?}", path.as_ref()).into())
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +111,6 @@ impl<E: Clone + Ord, C> EventMap<E, C> {
|
||||||
Ok(map)
|
Ok(map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> Binding<C> {
|
impl<C> Binding<C> {
|
||||||
fn from_dsl (dsl: impl Dsl) -> Usually<Self> {
|
fn from_dsl (dsl: impl Dsl) -> Usually<Self> {
|
||||||
let mut command: Option<C> = None;
|
let mut command: Option<C> = None;
|
||||||
|
|
@ -131,18 +124,9 @@ impl<C> Binding<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unquote (x: &str) -> &str {
|
fn unquote (x: &str) -> &str {
|
||||||
let mut chars = x.chars();
|
let mut chars = x.chars();
|
||||||
chars.next();
|
chars.next();
|
||||||
//chars.next_back();
|
//chars.next_back();
|
||||||
chars.as_str()
|
chars.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_and_leak (path: impl AsRef<Path>) -> Usually<&'static str> {
|
|
||||||
Ok(leak(String::from_utf8(std::fs::read(path.as_ref())?)?))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn leak (x: impl AsRef<str>) -> &'static str {
|
|
||||||
Box::leak(x.as_ref().into())
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ use crate::*;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(test, feature = "dsl"))] #[test] fn test_dsl_keymap () -> Usually<()> {
|
//#[cfg(all(test, feature = "dsl"))] #[test] fn test_dsl_keymap () -> Usually<()> {
|
||||||
let _keymap = CstIter::new("");
|
//let _keymap = CstIter::new("");
|
||||||
Ok(())
|
//Ok(())
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,86 +1,87 @@
|
||||||
use crate::*;
|
// FIXME
|
||||||
use crate::{dsl::*, input::*, tui::TuiIn};
|
//use crate::*;
|
||||||
use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState};
|
//use crate::{dsl::*, input::*, tui::TuiIn};
|
||||||
use std::cmp::Ordering;
|
//use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState};
|
||||||
|
//use std::cmp::Ordering;
|
||||||
|
|
||||||
#[test] fn test_subcommand () -> Usually<()> {
|
//#[test] fn test_subcommand () -> Usually<()> {
|
||||||
#[derive(Debug)] struct Event(crossterm::event::Event);
|
//#[derive(Debug)] struct Event(crossterm::event::Event);
|
||||||
impl Eq for Event {}
|
//impl Eq for Event {}
|
||||||
impl PartialEq for Event { fn eq (&self, other: &Self) -> bool { todo!() } }
|
//impl PartialEq for Event { fn eq (&self, other: &Self) -> bool { todo!() } }
|
||||||
impl Ord for Event { fn cmp (&self, other: &Self) -> Ordering { todo!() } }
|
//impl Ord for Event { fn cmp (&self, other: &Self) -> Ordering { todo!() } }
|
||||||
impl PartialOrd for Event { fn partial_cmp (&self, other: &Self) -> Option<Ordering> { None } }
|
//impl PartialOrd for Event { fn partial_cmp (&self, other: &Self) -> Option<Ordering> { None } }
|
||||||
struct Test { keys: InputMap<Event, Ast> }
|
//struct Test { keys: InputMap<Event, Ast> }
|
||||||
|
|
||||||
handle!(TuiIn: |self: Test, input|Ok(None));/*if let Some(command) = self.keys.command(self, input) {
|
//handle!(TuiIn: |self: Test, input|Ok(None));[>if let Some(command) = self.keys.command(self, input) {
|
||||||
Ok(Some(true))
|
//Ok(Some(true))
|
||||||
} else {
|
//} else {
|
||||||
Ok(None)
|
//Ok(None)
|
||||||
});*/
|
//});*/
|
||||||
|
|
||||||
#[tengri_proc::command(Test)]
|
//#[tengri_proc::command(Test)]
|
||||||
impl TestCommand {
|
//impl TestCommand {
|
||||||
fn do_thing (_state: &mut Test) -> Perhaps<Self> {
|
//fn do_thing (_state: &mut Test) -> Perhaps<Self> {
|
||||||
Ok(None)
|
//Ok(None)
|
||||||
}
|
//}
|
||||||
fn do_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps<Self> {
|
//fn do_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps<Self> {
|
||||||
Ok(None)
|
//Ok(None)
|
||||||
}
|
//}
|
||||||
fn do_sub (state: &mut Test, command: TestSubcommand) -> Perhaps<Self> {
|
//fn do_sub (state: &mut Test, command: TestSubcommand) -> Perhaps<Self> {
|
||||||
Ok(command.execute(state)?.map(|command|Self::DoSub { command }))
|
//Ok(command.execute(state)?.map(|command|Self::DoSub { command }))
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
|
|
||||||
#[tengri_proc::command(Test)]
|
//#[tengri_proc::command(Test)]
|
||||||
impl TestSubcommand {
|
//impl TestSubcommand {
|
||||||
fn do_other_thing (_state: &mut Test) -> Perhaps<Self> {
|
//fn do_other_thing (_state: &mut Test) -> Perhaps<Self> {
|
||||||
Ok(None)
|
//Ok(None)
|
||||||
}
|
//}
|
||||||
fn do_other_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps<Self> {
|
//fn do_other_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps<Self> {
|
||||||
Ok(None)
|
//Ok(None)
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
|
|
||||||
let mut test = Test {
|
//let mut test = Test {
|
||||||
keys: InputMap::from_source("
|
//keys: InputMap::from_source("
|
||||||
(@a do-thing)
|
//(@a do-thing)
|
||||||
(@b do-thing-arg 0)
|
//(@b do-thing-arg 0)
|
||||||
(@c do-sub do-other-thing)
|
//(@c do-sub do-other-thing)
|
||||||
(@d do-sub do-other-thing-arg 0)
|
//(@d do-sub do-other-thing-arg 0)
|
||||||
")?
|
//")?
|
||||||
};
|
//};
|
||||||
|
|
||||||
//assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
//kind: KeyEventKind::Press,
|
////kind: KeyEventKind::Press,
|
||||||
//code: KeyCode::Char('a'),
|
////code: KeyCode::Char('a'),
|
||||||
//modifiers: KeyModifiers::NONE,
|
////modifiers: KeyModifiers::NONE,
|
||||||
//state: KeyEventState::NONE,
|
////state: KeyEventState::NONE,
|
||||||
//})))?);
|
////})))?);
|
||||||
//assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
//kind: KeyEventKind::Press,
|
////kind: KeyEventKind::Press,
|
||||||
//code: KeyCode::Char('b'),
|
////code: KeyCode::Char('b'),
|
||||||
//modifiers: KeyModifiers::NONE,
|
////modifiers: KeyModifiers::NONE,
|
||||||
//state: KeyEventState::NONE,
|
////state: KeyEventState::NONE,
|
||||||
//})))?);
|
////})))?);
|
||||||
//assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
//kind: KeyEventKind::Press,
|
////kind: KeyEventKind::Press,
|
||||||
//code: KeyCode::Char('c'),
|
////code: KeyCode::Char('c'),
|
||||||
//modifiers: KeyModifiers::NONE,
|
////modifiers: KeyModifiers::NONE,
|
||||||
//state: KeyEventState::NONE,
|
////state: KeyEventState::NONE,
|
||||||
//})))?);
|
////})))?);
|
||||||
//assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
////assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
//kind: KeyEventKind::Press,
|
////kind: KeyEventKind::Press,
|
||||||
//code: KeyCode::Char('d'),
|
////code: KeyCode::Char('d'),
|
||||||
//modifiers: KeyModifiers::NONE,
|
////modifiers: KeyModifiers::NONE,
|
||||||
//state: KeyEventState::NONE,
|
////state: KeyEventState::NONE,
|
||||||
//})))?);
|
////})))?);
|
||||||
//assert_eq!(None, test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
////assert_eq!(None, test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
//kind: KeyEventKind::Press,
|
////kind: KeyEventKind::Press,
|
||||||
//code: KeyCode::Char('z'),
|
////code: KeyCode::Char('z'),
|
||||||
//modifiers: KeyModifiers::NONE,
|
////modifiers: KeyModifiers::NONE,
|
||||||
//state: KeyEventState::NONE,
|
////state: KeyEventState::NONE,
|
||||||
//})))?);
|
////})))?);
|
||||||
Ok(())
|
//Ok(())
|
||||||
}
|
//}
|
||||||
|
|
||||||
//FIXME:
|
//FIXME:
|
||||||
//#[cfg(test)] #[test] fn test_dsl_context () {
|
//#[cfg(test)] #[test] fn test_dsl_context () {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue