|
|
|
@ -52,6 +52,7 @@ impl fmt::Display for Error {
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
|
pub struct Hotkey {
|
|
|
|
|
pub mode: String,
|
|
|
|
|
pub keysym: evdev::Key,
|
|
|
|
|
pub modifiers: Vec<Modifier>,
|
|
|
|
|
pub command: String,
|
|
|
|
@ -76,8 +77,8 @@ pub enum Modifier {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Hotkey {
|
|
|
|
|
pub fn new(keysym: evdev::Key, modifiers: Vec<Modifier>, command: String) -> Self {
|
|
|
|
|
Hotkey { keysym, modifiers, command }
|
|
|
|
|
pub fn new(mode: String, keysym: evdev::Key, modifiers: Vec<Modifier>, command: String) -> Self {
|
|
|
|
|
Hotkey { mode, keysym, modifiers, command }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -281,9 +282,9 @@ fn parse_contents(contents: String) -> Result<Vec<Hotkey>, Error> {
|
|
|
|
|
|
|
|
|
|
'hotkey_parse: for (key, command) in extracted_keys.iter().zip(extracted_commands.iter()) {
|
|
|
|
|
println!("{} {}", key, command);
|
|
|
|
|
let (keysym, modifiers) =
|
|
|
|
|
let (mode, keysym, modifiers) =
|
|
|
|
|
parse_keybind(key, line_number + 1, &key_to_evdev_key, &mod_to_mod_enum)?;
|
|
|
|
|
let hotkey = Hotkey { keysym, modifiers, command: command.to_string() };
|
|
|
|
|
let hotkey = Hotkey { mode, keysym, modifiers, command: command.to_string() };
|
|
|
|
|
|
|
|
|
|
// Ignore duplicate hotkeys
|
|
|
|
|
for i in hotkeys.iter() {
|
|
|
|
@ -306,7 +307,7 @@ fn parse_keybind(
|
|
|
|
|
line_nr: u32,
|
|
|
|
|
key_to_evdev_key: &HashMap<&str, evdev::Key>,
|
|
|
|
|
mod_to_mod_enum: &HashMap<&str, Modifier>,
|
|
|
|
|
) -> Result<(evdev::Key, Vec<Modifier>), Error> {
|
|
|
|
|
) -> Result<(String, evdev::Key, Vec<Modifier>), Error> {
|
|
|
|
|
let line = line.split('#').next().unwrap();
|
|
|
|
|
let tokens: Vec<String> =
|
|
|
|
|
line.split('+').map(|s| s.trim().to_lowercase()).filter(|s| s != "_").collect();
|
|
|
|
@ -314,6 +315,9 @@ fn parse_keybind(
|
|
|
|
|
|
|
|
|
|
// Check if each token is valid
|
|
|
|
|
for token in &tokens {
|
|
|
|
|
if token.starts_with("[") && token.ends_with("]") {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if key_to_evdev_key.contains_key(token.as_str()) {
|
|
|
|
|
// Can't have a key that's like a modifier
|
|
|
|
|
if token != last_token {
|
|
|
|
@ -331,13 +335,22 @@ fn parse_keybind(
|
|
|
|
|
|
|
|
|
|
// Translate keypress into evdev key
|
|
|
|
|
let keysym = key_to_evdev_key.get(last_token).unwrap();
|
|
|
|
|
let mode = tokens
|
|
|
|
|
.iter()
|
|
|
|
|
.filter(|s| s.starts_with("[") && s.ends_with("]"))
|
|
|
|
|
.map(|s| s.replace(&['[', ']'][..], ""))
|
|
|
|
|
.collect::<Vec<String>>()
|
|
|
|
|
.get(0)
|
|
|
|
|
.unwrap_or(&"".to_string())
|
|
|
|
|
.to_string();
|
|
|
|
|
let mod_index = if mode.is_empty() { 0 } else { 1 };
|
|
|
|
|
|
|
|
|
|
let modifiers: Vec<Modifier> = tokens[0..(tokens.len() - 1)]
|
|
|
|
|
let modifiers: Vec<Modifier> = tokens[mod_index..(tokens.len() - 1)]
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|token| *mod_to_mod_enum.get(token.as_str()).unwrap())
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
Ok((*keysym, modifiers))
|
|
|
|
|
Ok((mode, *keysym, modifiers))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn extract_curly_brace(line: &str) -> Vec<String> {
|
|
|
|
@ -561,7 +574,7 @@ r
|
|
|
|
|
|
|
|
|
|
eval_config_test(
|
|
|
|
|
contents,
|
|
|
|
|
vec![Hotkey::new(evdev::Key::KEY_R, vec![], String::from("alacritty"))],
|
|
|
|
|
vec![Hotkey::new("".to_string(), evdev::Key::KEY_R, vec![], String::from("alacritty"))],
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -578,9 +591,9 @@ t
|
|
|
|
|
/bin/firefox
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
let hotkey_1 = Hotkey::new(evdev::Key::KEY_R, vec![], String::from("alacritty"));
|
|
|
|
|
let hotkey_2 = Hotkey::new(evdev::Key::KEY_W, vec![], String::from("kitty"));
|
|
|
|
|
let hotkey_3 = Hotkey::new(evdev::Key::KEY_T, vec![], String::from("/bin/firefox"));
|
|
|
|
|
let hotkey_1 = Hotkey::new("".to_string(), evdev::Key::KEY_R, vec![], String::from("alacritty"));
|
|
|
|
|
let hotkey_2 = Hotkey::new("".to_string(), evdev::Key::KEY_W, vec![], String::from("kitty"));
|
|
|
|
|
let hotkey_3 = Hotkey::new("".to_string(), evdev::Key::KEY_T, vec![], String::from("/bin/firefox"));
|
|
|
|
|
|
|
|
|
|
eval_config_test(contents, vec![hotkey_1, hotkey_2, hotkey_3])
|
|
|
|
|
}
|
|
|
|
@ -599,8 +612,8 @@ w
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
let expected_keybinds = vec![
|
|
|
|
|
Hotkey::new(evdev::Key::KEY_R, vec![], String::from("alacritty")),
|
|
|
|
|
Hotkey::new(evdev::Key::KEY_W, vec![], String::from("kitty")),
|
|
|
|
|
Hotkey::new("".to_string(), evdev::Key::KEY_R, vec![], String::from("alacritty")),
|
|
|
|
|
Hotkey::new("".to_string(), evdev::Key::KEY_W, vec![], String::from("kitty")),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
eval_config_test(contents, expected_keybinds)
|
|
|
|
@ -614,7 +627,7 @@ super + 5
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
let expected_keybinds =
|
|
|
|
|
vec![Hotkey::new(evdev::Key::KEY_5, vec![Modifier::Super], String::from("alacritty"))];
|
|
|
|
|
vec![Hotkey::new("".to_string(), evdev::Key::KEY_5, vec![Modifier::Super], String::from("alacritty"))];
|
|
|
|
|
|
|
|
|
|
eval_config_test(contents, expected_keybinds)
|
|
|
|
|
}
|
|
|
|
@ -679,21 +692,25 @@ super + z
|
|
|
|
|
|
|
|
|
|
let expected_hotkeys = vec![
|
|
|
|
|
Hotkey::new(
|
|
|
|
|
"".to_string(),
|
|
|
|
|
evdev::Key::KEY_K,
|
|
|
|
|
vec![Modifier::Shift],
|
|
|
|
|
"notify-send 'Hello world!'".to_string(),
|
|
|
|
|
),
|
|
|
|
|
Hotkey::new(
|
|
|
|
|
"".to_string(),
|
|
|
|
|
evdev::Key::KEY_5,
|
|
|
|
|
vec![Modifier::Control],
|
|
|
|
|
"notify-send 'Hello world!'".to_string(),
|
|
|
|
|
),
|
|
|
|
|
Hotkey::new(
|
|
|
|
|
"".to_string(),
|
|
|
|
|
evdev::Key::KEY_2,
|
|
|
|
|
vec![Modifier::Alt],
|
|
|
|
|
"notify-send 'Hello world!'".to_string(),
|
|
|
|
|
),
|
|
|
|
|
Hotkey::new(
|
|
|
|
|
"".to_string(),
|
|
|
|
|
evdev::Key::KEY_Z,
|
|
|
|
|
vec![Modifier::Super],
|
|
|
|
|
"notify-send 'Hello world!'".to_string(),
|
|
|
|
|