Add timeout_millis for nested remap

pull/82/head
Takashi Kokubun 3 years ago
parent eaca8be6f7
commit 0d200a87b2
No known key found for this signature in database
GPG Key ID: 6FFC433B12EE23DD

@ -1,9 +1,11 @@
use crate::config::key_press::KeyPress;
use std::collections::HashMap;
use crate::config::remap::Remap;
use serde::de;
use serde::{Deserialize, Deserializer};
use std::fmt::Debug;
use std::time::Duration;
// Values in `keymap.remap`
#[derive(Clone, Debug, Deserialize)]
@ -11,7 +13,7 @@ use std::fmt::Debug;
pub enum Action {
KeyPress(KeyPress),
#[serde(deserialize_with = "deserialize_remap")]
Remap(HashMap<KeyPress, Vec<Action>>),
Remap(Remap),
#[serde(deserialize_with = "deserialize_launch")]
Launch(Vec<String>),
#[serde(deserialize_with = "deserialize_set_mark")]
@ -22,17 +24,15 @@ pub enum Action {
EscapeNextKey(bool),
}
fn deserialize_remap<'de, D>(deserializer: D) -> Result<HashMap<KeyPress, Vec<Action>>, D::Error>
fn deserialize_remap<'de, D>(deserializer: D) -> Result<Remap, D::Error>
where
D: Deserializer<'de>,
{
let mut action = HashMap::<String, HashMap<KeyPress, Actions>>::deserialize(deserializer)?;
if let Some(remap) = action.remove("remap") {
if action.is_empty() {
return Ok(remap.into_iter().map(|(k, v)| (k, v.into_vec())).collect());
}
}
Err(de::Error::custom("not a map with a single \"remap\" key"))
let action = RemapActions::deserialize(deserializer)?;
return Ok(Remap {
remap: action.remap.into_iter().map(|(k, v)| (k, v.into_vec())).collect(),
timeout: action.timeout_millis.map(|ms| Duration::from_millis(ms)),
});
}
fn deserialize_launch<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
@ -88,7 +88,7 @@ where
}
// Used only for deserializing Vec<Action>
#[derive(Clone, Deserialize)]
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
pub enum Actions {
Action(Action),
@ -103,3 +103,10 @@ impl Actions {
}
}
}
// Used only for deserializing Remap with Vec<Action>
#[derive(Debug, Deserialize)]
pub struct RemapActions {
pub remap: HashMap<KeyPress, Actions>,
pub timeout_millis: Option<u64>,
}

@ -6,6 +6,7 @@ pub mod key_press;
mod keymap;
mod modmap;
mod remap;
#[cfg(test)]
mod tests;

@ -0,0 +1,10 @@
use crate::config::action::Action;
use crate::config::key_press::KeyPress;
use std::collections::HashMap;
use std::time::Duration;
#[derive(Clone, Debug)]
pub struct Remap {
pub remap: HashMap<KeyPress, Vec<Action>>,
pub timeout: Option<Duration>,
}

@ -110,6 +110,7 @@ fn test_keymap_remap() {
C-s:
remap:
x: C-z
timeout_millis: 1000
"})
}

@ -25,6 +25,7 @@ pub struct EventHandler {
application_cache: Option<String>,
multi_purpose_keys: HashMap<Key, MultiPurposeKeyState>,
override_remap: Option<HashMap<KeyPress, Vec<Action>>>,
override_timeout_at: Option<Instant>,
sigaction_set: bool,
mark_set: bool,
escape_next_key: bool,
@ -42,6 +43,7 @@ impl EventHandler {
application_cache: None,
multi_purpose_keys: HashMap::new(),
override_remap: None,
override_timeout_at: None,
sigaction_set: false,
mark_set: false,
escape_next_key: false,
@ -169,6 +171,12 @@ impl EventHandler {
alt: self.alt.to_modifier_state(),
windows: self.windows.to_modifier_state(),
};
if let Some(override_timeout_at) = self.override_timeout_at {
if override_timeout_at < Instant::now() {
self.override_remap = None;
self.override_timeout_at = None;
}
}
if let Some(override_remap) = &self.override_remap {
let override_remap = override_remap.clone();
self.override_remap = None;
@ -192,12 +200,13 @@ impl EventHandler {
fn dispatch_action(&mut self, action: &Action) -> Result<(), Box<dyn Error>> {
match action {
Action::KeyPress(key_press) => self.send_key_press(key_press)?,
Action::Remap(remap) => {
Action::Remap(action) => {
let mut override_remap: HashMap<KeyPress, Vec<Action>> = HashMap::new();
for (key_press, actions) in remap.iter() {
for (key_press, actions) in action.remap.iter() {
override_remap.insert(key_press.clone(), actions.to_vec());
}
self.override_remap = Some(override_remap)
self.override_remap = Some(override_remap);
self.override_timeout_at = action.timeout.map(|t| Instant::now() + t)
}
Action::Launch(command) => self.run_command(command.clone()),
Action::SetMark(set) => self.mark_set = *set,

Loading…
Cancel
Save