mirror of
https://github.com/k0kubun/xremap
synced 2024-11-02 03:40:25 +00:00
commit
18ee84e934
@ -16,6 +16,8 @@ pub enum Action {
|
|||||||
Remap(Remap),
|
Remap(Remap),
|
||||||
#[serde(deserialize_with = "deserialize_launch")]
|
#[serde(deserialize_with = "deserialize_launch")]
|
||||||
Launch(Vec<String>),
|
Launch(Vec<String>),
|
||||||
|
#[serde(deserialize_with = "deserialize_set_mode")]
|
||||||
|
SetMode(String),
|
||||||
#[serde(deserialize_with = "deserialize_set_mark")]
|
#[serde(deserialize_with = "deserialize_set_mark")]
|
||||||
SetMark(bool),
|
SetMark(bool),
|
||||||
#[serde(deserialize_with = "deserialize_with_mark")]
|
#[serde(deserialize_with = "deserialize_with_mark")]
|
||||||
@ -48,6 +50,19 @@ where
|
|||||||
Err(de::Error::custom("not a map with a single \"launch\" key"))
|
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>
|
fn deserialize_set_mark<'de, D>(deserializer: D) -> Result<bool, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
|
@ -10,7 +10,7 @@ pub struct Application {
|
|||||||
pub not: Option<Vec<String>>,
|
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
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::config::action::{Action, Actions};
|
use crate::config::action::{Action, Actions};
|
||||||
|
use crate::config::application::deserialize_string_or_vec;
|
||||||
use crate::config::application::Application;
|
use crate::config::application::Application;
|
||||||
use crate::config::key_press::{KeyPress, Modifier, ModifierState};
|
use crate::config::key_press::{KeyPress, Modifier, ModifierState};
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
@ -12,6 +13,8 @@ pub struct Keymap {
|
|||||||
#[serde(deserialize_with = "deserialize_remap")]
|
#[serde(deserialize_with = "deserialize_remap")]
|
||||||
pub remap: HashMap<KeyPress, Vec<Action>>,
|
pub remap: HashMap<KeyPress, Vec<Action>>,
|
||||||
pub application: Option<Application>,
|
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>
|
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>,
|
pub modmap: Vec<Modmap>,
|
||||||
#[serde(default = "Vec::new")]
|
#[serde(default = "Vec::new")]
|
||||||
pub keymap: Vec<Keymap>,
|
pub keymap: Vec<Keymap>,
|
||||||
|
#[serde(default = "default_mode")]
|
||||||
|
pub default_mode: String,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub modify_time: Option<SystemTime>,
|
pub modify_time: Option<SystemTime>,
|
||||||
}
|
}
|
||||||
@ -49,3 +51,7 @@ pub fn config_watcher(watch: bool, file: &Path) -> anyhow::Result<Option<Inotify
|
|||||||
Ok(None)
|
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]
|
#[test]
|
||||||
fn test_keymap_mark() {
|
fn test_keymap_mark() {
|
||||||
assert_parse(indoc! {"
|
assert_parse(indoc! {"
|
||||||
|
@ -40,6 +40,8 @@ pub struct EventHandler {
|
|||||||
override_timer: TimerFd,
|
override_timer: TimerFd,
|
||||||
// Whether we've called a sigaction for spawing commands or not
|
// Whether we've called a sigaction for spawing commands or not
|
||||||
sigaction_set: bool,
|
sigaction_set: bool,
|
||||||
|
// { set_mode: String }
|
||||||
|
mode: String,
|
||||||
// { set_mark: true }
|
// { set_mark: true }
|
||||||
mark_set: bool,
|
mark_set: bool,
|
||||||
// { escape_next_key: true }
|
// { escape_next_key: true }
|
||||||
@ -47,7 +49,7 @@ pub struct EventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EventHandler {
|
impl EventHandler {
|
||||||
pub fn new(device: VirtualDevice, timer: TimerFd) -> EventHandler {
|
pub fn new(device: VirtualDevice, timer: TimerFd, mode: &str) -> EventHandler {
|
||||||
EventHandler {
|
EventHandler {
|
||||||
device,
|
device,
|
||||||
shift: PressState::new(),
|
shift: PressState::new(),
|
||||||
@ -62,6 +64,7 @@ impl EventHandler {
|
|||||||
override_timeout_key: None,
|
override_timeout_key: None,
|
||||||
override_timer: timer,
|
override_timer: timer,
|
||||||
sigaction_set: false,
|
sigaction_set: false,
|
||||||
|
mode: mode.to_string(),
|
||||||
mark_set: false,
|
mark_set: false,
|
||||||
escape_next_key: false,
|
escape_next_key: false,
|
||||||
}
|
}
|
||||||
@ -239,6 +242,11 @@ impl EventHandler {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(modes) = &keymap.mode {
|
||||||
|
if !modes.contains(&self.mode) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Ok(Some(actions.to_vec()));
|
return Ok(Some(actions.to_vec()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,6 +272,10 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action::Launch(command) => self.run_command(command.clone()),
|
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::SetMark(set) => self.mark_set = *set,
|
||||||
Action::WithMark(key_press) => self.send_key_press(&self.with_mark(key_press))?,
|
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,
|
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 = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty())?;
|
||||||
let timer_fd = timer.as_raw_fd();
|
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) {
|
let mut input_devices = match get_input_devices(&device_filter, &ignore_filter, watch_devices) {
|
||||||
Ok(input_devices) => input_devices,
|
Ok(input_devices) => input_devices,
|
||||||
Err(e) => bail!("Failed to prepare input devices: {}", e),
|
Err(e) => bail!("Failed to prepare input devices: {}", e),
|
||||||
|
Loading…
Reference in New Issue
Block a user