summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkshay <nerdy@peppe.rs>2021-02-21 10:15:09 +0530
committerAkshay <nerdy@peppe.rs>2021-02-21 10:15:09 +0530
commit0ed1ae47b47ea378d13574f8260de54556bf243c (patch)
treeb43b30df476d76d0a18feb7c6e7e00fd3ac4dae4
parent879b115d651b26d3935f5c95d06f426019dedcd3 (diff)
sane keybindscursor
-rw-r--r--src/app/impl_view.rs8
-rw-r--r--src/keybinds.rs146
2 files changed, 150 insertions, 4 deletions
diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs
index 98f540c..c369d8f 100644
--- a/src/app/impl_view.rs
+++ b/src/app/impl_view.rs
@@ -96,19 +96,19 @@ impl View for App {
return EventResult::Consumed(None);
}
- Event::Char('w') => {
+ Event::Char('K') => {
self.move_cursor(Absolute::Up);
return EventResult::Consumed(None);
}
- Event::Char('a') => {
+ Event::Char('H') => {
self.move_cursor(Absolute::Left);
return EventResult::Consumed(None);
}
- Event::Char('s') => {
+ Event::Char('J') => {
self.move_cursor(Absolute::Down);
return EventResult::Consumed(None);
}
- Event::Char('d') => {
+ Event::Char('L') => {
self.move_cursor(Absolute::Right);
return EventResult::Consumed(None);
}
diff --git a/src/keybinds.rs b/src/keybinds.rs
new file mode 100644
index 0000000..1b9c234
--- /dev/null
+++ b/src/keybinds.rs
@@ -0,0 +1,146 @@
+use std::convert::From;
+
+use cursive::event::Event as CursiveEvent;
+use serde::ser;
+use serde::{self, Deserialize, Serialize, Serializer};
+
+#[derive(Debug, PartialEq)]
+struct Event(CursiveEvent);
+
+macro_rules! event {
+ ($thing:expr) => {
+ Event { 0: $thing };
+ };
+}
+
+impl<T> From<T> for Event
+where
+ T: AsRef<str>,
+{
+ fn from(key: T) -> Self {
+ let key = key.as_ref();
+ if key.len() == 1 {
+ // single key
+ return event!(CursiveEvent::Char(key.chars().nth(0).unwrap()));
+ } else if (key.starts_with("c-") || key.starts_with("C-")) && key.len() == 3 {
+ // ctrl-key
+ return event!(CursiveEvent::CtrlChar(key.chars().nth(2).unwrap()));
+ } else {
+ panic!(
+ r"Invalid keybind in configuration!
+ (I intend to handle this error gracefully in the near future)"
+ );
+ }
+ }
+}
+
+enum Bind {
+ Char(char),
+ CtrlChar(char),
+ AltChar(char),
+}
+
+impl Serialize for Bind {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self {
+ Bind::Char(c) => serializer.serialize_newtype_variant("bind", 0, "regular", &c),
+ Bind::CtrlChar(c) => serializer.serialize_newtype_variant("bind", 0, "ctrl", &c),
+ Bind::AltChar(c) => serializer.serialize_newtype_variant("bind", 0, "alt", &c),
+ }
+ }
+}
+
+impl Deserialize for Bind {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ eprintln!("hell = {:#?}", hell);
+ }
+}
+
+impl From<Bind> for CursiveEvent {
+ fn from(key: Bind) -> Self {
+ match key {
+ Bind::Char(c) => CursiveEvent::Char(c),
+ Bind::CtrlChar(c) => CursiveEvent::Char(c),
+ Bind::AltChar(c) => CursiveEvent::AltChar(c),
+ }
+ }
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct KeyBinds {
+ grid: Movement,
+ cursor: Movement,
+ week_mode: Bind,
+ global_week_mode: Bind,
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct Movement {
+ up: Bind,
+ down: Bind,
+ left: Bind,
+ right: Bind,
+}
+
+impl Movement {
+ pub fn new(left: char, down: char, up: char, right: char) -> Self {
+ return Movement {
+ up: Bind::Char(up),
+ down: Bind::Char(down),
+ left: Bind::Char(left),
+ right: Bind::Char(right),
+ };
+ }
+}
+
+impl std::default::Default for KeyBinds {
+ fn default() -> Self {
+ let grid = Movement::new('h', 'j', 'k', 'l');
+ let cursor = Movement::new('H', 'J', 'K', 'L');
+ return KeyBinds {
+ grid,
+ cursor,
+ week_mode: Bind::Char('v'),
+ global_week_mode: Bind::Char('V'),
+ };
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn normal_keybind() {
+ let bind = "X";
+ let expected = CursiveEvent::Char('X');
+ assert_eq!(Event::from(bind), event!(expected));
+ }
+
+ #[test]
+ fn control_keybind() {
+ let bind = "C-x";
+ let expected = CursiveEvent::CtrlChar('x');
+ assert_eq!(Event::from(bind), event!(expected));
+ }
+
+ #[test]
+ fn lower_case_control_keybind() {
+ let bind = "c-x";
+ let expected = CursiveEvent::CtrlChar('x');
+ assert_eq!(Event::from(bind), event!(expected));
+ }
+
+ #[test]
+ #[should_panic]
+ fn very_long_and_wrong_keybind() {
+ let bind = "alksdjfalkjdf";
+ Event::from(bind);
+ }
+}