Merge pull request #93 from k0kubun/mode

Support modal remapping
pull/113/head
Takashi Kokubun 2 years ago committed by GitHub
commit 18ee84e934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,6 +16,8 @@ pub enum Action {
Remap(Remap),
#[serde(deserialize_with = "deserialize_launch")]
Launch(Vec<String>),
#[serde(deserialize_with = "deserialize_set_mode")]
SetMode(String),
#[serde(deserialize_with = "deserialize_set_mark")]
SetMark(bool),
#[serde(deserialize_with = "deserialize_with_mark")]
@ -48,6 +50,19 @@ where
Err(de::Error::custom("not a map with a single \"launch\" key"))
}
fn deserialize_set_mode<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
let mut action = HashMap::<String, String>::deserialize(deserializer)?;
if let Some(set) = action.remove("set_mode") {
if action.is_empty() {
return Ok(set);
}
}
Err(de::Error::custom("not a map with a single \"set_mode\" key"))
}
fn deserialize_set_mark<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: Deserializer<'de>,

@ -10,7 +10,7 @@ pub struct Application {
pub not: Option<Vec<String>>,
}
fn deserialize_string_or_vec<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
pub fn deserialize_string_or_vec<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
where
D: Deserializer<'de>,
{

@ -1,4 +1,5 @@
use crate::config::action::{Action, Actions};
use crate::config::application::deserialize_string_or_vec;
use crate::config::application::Application;
use crate::config::key_press::{KeyPress, Modifier, ModifierState};
use serde::{Deserialize, Deserializer};
@ -12,6 +13,8 @@ pub struct Keymap {
#[serde(deserialize_with = "deserialize_remap")]
pub remap: HashMap<KeyPress, Vec<Action>>,
pub application: Option<Application>,
#[serde(default, deserialize_with = "deserialize_string_or_vec")]
pub mode: Option<Vec<String>>,
}
fn deserialize_remap<'de, D>(deserializer: D) -> Result<HashMap<KeyPress, Vec<Action>>, D::Error>

@ -25,6 +25,8 @@ pub struct Config {
pub modmap: Vec<Modmap>,
#[serde(default = "Vec::new")]
pub keymap: Vec<Keymap>,
#[serde(default = "default_mode")]
pub default_mode: String,
#[serde(skip)]
pub modify_time: Option<SystemTime>,
}
@ -49,3 +51,7 @@ pub fn config_watcher(watch: bool, file: &Path) -> anyhow::Result<Option<Inotify
Ok(None)
}
}
fn default_mode() -> String {
"default".to_string()
}

@ -127,6 +127,24 @@ fn test_keymap_launch() {
"#})
}
#[test]
fn test_keymap_mode() {
assert_parse(indoc! {"
default_mode: insert
keymap:
- mode: insert
remap:
Esc: { set_mode: normal }
- mode: normal
remap:
i: { set_mode: insert }
h: Left
j: Down
k: Up
l: Right
"})
}
#[test]
fn test_keymap_mark() {
assert_parse(indoc! {"

@ -40,6 +40,8 @@ pub struct EventHandler {
override_timer: TimerFd,
// Whether we've called a sigaction for spawing commands or not
sigaction_set: bool,
// { set_mode: String }
mode: String,
// { set_mark: true }
mark_set: bool,
// { escape_next_key: true }
@ -47,7 +49,7 @@ pub struct EventHandler {
}
impl EventHandler {
pub fn new(device: VirtualDevice, timer: TimerFd) -> EventHandler {
pub fn new(device: VirtualDevice, timer: TimerFd, mode: &str) -> EventHandler {
EventHandler {
device,
shift: PressState::new(),
@ -62,6 +64,7 @@ impl EventHandler {
override_timeout_key: None,
override_timer: timer,
sigaction_set: false,
mode: mode.to_string(),
mark_set: false,
escape_next_key: false,
}
@ -239,6 +242,11 @@ impl EventHandler {
continue;
}
}
if let Some(modes) = &keymap.mode {
if !modes.contains(&self.mode) {
continue;
}
}
return Ok(Some(actions.to_vec()));
}
}
@ -264,6 +272,10 @@ impl EventHandler {
}
}
Action::Launch(command) => self.run_command(command.clone()),
Action::SetMode(mode) => {
self.mode = mode.clone();
println!("mode: {}", mode);
}
Action::SetMark(set) => self.mark_set = *set,
Action::WithMark(key_press) => self.send_key_press(&self.with_mark(key_press))?,
Action::EscapeNextKey(escape_next_key) => self.escape_next_key = *escape_next_key,

@ -100,7 +100,7 @@ fn main() -> anyhow::Result<()> {
};
let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty())?;
let timer_fd = timer.as_raw_fd();
let mut handler = EventHandler::new(output_device, timer);
let mut handler = EventHandler::new(output_device, timer, &config.default_mode);
let mut input_devices = match get_input_devices(&device_filter, &ignore_filter, watch_devices) {
Ok(input_devices) => input_devices,
Err(e) => bail!("Failed to prepare input devices: {}", e),

Loading…
Cancel
Save