Skip to content

Commit

Permalink
feat(whkd): add default cmds and scoped ignores
Browse files Browse the repository at this point in the history
This commit adds two new keyword when handling app binding blocks.

Using "Default" in place of a process name will make the command on the
right of the : apply to all applications.

Using "Ignore" in place of a command will ignore running the hotkey for
the matching process.
  • Loading branch information
LGUG2Z committed Jan 15, 2025
1 parent 9704070 commit 32f07f4
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 24 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format of the configuration file (and this project itself) is heavily inspir
.shell pwsh # can be one of cmd | pwsh | powershell
# Specify different behaviour depending on the app
# These "app : command" style bindings MUST come immediately below the .shell directive
alt + n [
# ProcessName as shown by `Get-Process`
Firefox : echo "hello firefox"
Expand All @@ -24,11 +25,14 @@ alt + n [
Google Chrome : echo "hello chrome"
]
# reload configuration
alt + o : taskkill /f /im whkd.exe && Start-Process whkd -WindowStyle hidden
alt + q [
# Default is a keyword which will apply to all apps
# If you only have Default, this is the same as doing "alt + q : komorebic close"
Default : komorebic close
# app shortcuts
alt + f : if ($wshell.AppActivate('Firefox') -eq $False) { start firefox }
# Ignore is a keyword which will skip running the hotkey for the given process
Google Chrome : Ignore
]
# focus windows with komorebi
alt + h : komorebic focus left
Expand Down
39 changes: 25 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,26 +180,37 @@ fn main() -> Result<()> {
let v = v.clone();
hkm.register_hotkey(vkey, mod_keys, move || {
if let Some(session_stdin) = SESSION_STDIN.lock().as_mut() {
let app_name = active_win_pos_rs::get_active_window()
.unwrap_or_default()
.app_name;

let mut matched_cmd = None;
let mut default_cmd = None;

for e in &v {
let cmd = &e.command;

if let Some(proc) = &e.process_name {
match active_win_pos_rs::get_active_window() {
Ok(window) => {
if window.app_name == *proc {
if matches!(whkdrc.shell, Shell::Pwsh | Shell::Powershell) {
println!("{cmd}");
}

writeln!(session_stdin, "{cmd}")
.expect("failed to execute command");
}
}
Err(error) => {
dbg!(error);
}
if *proc == "Default" {
default_cmd = Some(cmd.clone());
}

if app_name == *proc {
matched_cmd = Some(cmd.clone());
}
}
}

match (matched_cmd, default_cmd) {
(None, Some(cmd)) | (Some(cmd), _) if cmd != "Ignore" => {
if matches!(whkdrc.shell, Shell::Pwsh | Shell::Powershell) {
println!("{cmd}");
}

writeln!(session_stdin, "{cmd}").expect("failed to execute command");
}
(_, _) => {}
}
}
})?;
}
Expand Down
76 changes: 70 additions & 6 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,26 @@ pub fn parser() -> impl Parser<char, Whkdrc, Error = Simple<char>> {
.map(|c| c.0)
.collect::<String>();

let process_name = text::ident()
.padded()
.repeated()
.at_least(1)
.map(|a| a.join(" "));
let default_keyword = just("Default").padded();
let ignore_keyword = just("Ignore").padded();

let process_name = choice((
default_keyword.map(|_| String::from("Default")),
text::ident()
.padded()
.repeated()
.at_least(1)
.map(|a| a.join(" ")),
));

let process_command = choice((
ignore_keyword.map(|_| String::from("Ignore")),
command.clone(),
));

let process_mapping = process_name
.then_ignore(delimiter)
.then(command.clone())
.then(process_command)
.padded()
.padded_by(comment.repeated())
.repeated()
Expand Down Expand Up @@ -249,4 +260,57 @@ f11 : echo "hello f11""#;

assert_eq!(output.unwrap(), expected);
}

#[test]
fn test_default_and_scoped_ignores() {
let src = r#"
.shell pwsh
alt + n [
Default : echo "hello world"
Firefox : echo "hello firefox"
Google Chrome : echo "hello chrome"
Zen Browser : Ignore
]
alt + h : echo "Hello""#;

let output = parser().parse(src);
dbg!(&output);
let expected = Whkdrc {
shell: Shell::Pwsh,
app_bindings: vec![(
vec![String::from("alt"), String::from("n")],
vec![
HotkeyBinding {
keys: vec![String::from("alt"), String::from("n")],
command: String::from(r#"echo "hello world""#),
process_name: Option::from("Default".to_string()),
},
HotkeyBinding {
keys: vec![String::from("alt"), String::from("n")],
command: String::from(r#"echo "hello firefox""#),
process_name: Option::from("Firefox".to_string()),
},
HotkeyBinding {
keys: vec![String::from("alt"), String::from("n")],
command: String::from(r#"echo "hello chrome""#),
process_name: Option::from("Google Chrome".to_string()),
},
HotkeyBinding {
keys: vec![String::from("alt"), String::from("n")],
command: String::from("Ignore"),
process_name: Option::from("Zen Browser".to_string()),
},
],
)],
bindings: vec![HotkeyBinding {
keys: vec![String::from("alt"), String::from("h")],
command: String::from(r#"echo "Hello""#),
process_name: None,
}],
};

assert_eq!(output.unwrap(), expected);
}
}

0 comments on commit 32f07f4

Please sign in to comment.