diff options
author | Dominik MiedziĆski <dominik@mdzn.pl> | 2017-05-25 18:19:00 +0200 |
---|---|---|
committer | Joe Wilm <jwilm@users.noreply.github.com> | 2017-05-25 09:19:00 -0700 |
commit | 5977776874d16febbf26d73e833b4e4d104aa359 (patch) | |
tree | 7c8c2db296e28d33a39a924dbf4fe263e71b6e8f | |
parent | 112abf385fef32f30618b4ebb1d1c651661a6fae (diff) | |
download | alacritty-5977776874d16febbf26d73e833b4e4d104aa359.tar.gz alacritty-5977776874d16febbf26d73e833b4e4d104aa359.zip |
Add support for running commands on key press (#566)
Based on option `command` in key binding section in config, e.g.
- { key: N, mods: Control|Shift, command: alacritty }
# or
- {
key: N,
mods: Control|Shift,
command: {
program: "alacritty",
args: ["-e", "vttest"],
}}
specified command will be run in the background on key press. Alacritty
doesn't wait for its result nor block IO.
-rw-r--r-- | src/config.rs | 49 | ||||
-rw-r--r-- | src/input.rs | 15 |
2 files changed, 54 insertions, 10 deletions
diff --git a/src/config.rs b/src/config.rs index 62e0ba49..ada6f8d1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -378,6 +378,17 @@ impl de::Deserialize for ActionWrapper { } } +#[derive(Debug, Deserialize)] +#[serde(untagged)] +enum CommandWrapper { + Just(String), + WithArgs { + program: String, + #[serde(default)] + args: Vec<String>, + }, +} + use ::term::{mode, TermMode}; struct ModeWrapper { @@ -517,7 +528,8 @@ impl de::Deserialize for RawBinding { Mode, Action, Chars, - Mouse + Mouse, + Command, } impl de::Deserialize for Field { @@ -527,7 +539,7 @@ impl de::Deserialize for RawBinding { struct FieldVisitor; static FIELDS: &'static [&'static str] = &[ - "key", "mods", "mode", "action", "chars", "mouse" + "key", "mods", "mode", "action", "chars", "mouse", "command", ]; impl Visitor for FieldVisitor { @@ -547,6 +559,7 @@ impl de::Deserialize for RawBinding { "action" => Ok(Field::Action), "chars" => Ok(Field::Chars), "mouse" => Ok(Field::Mouse), + "command" => Ok(Field::Command), _ => Err(E::unknown_field(value, FIELDS)), } } @@ -577,6 +590,7 @@ impl de::Deserialize for RawBinding { let mut mode: Option<TermMode> = None; let mut not_mode: Option<TermMode> = None; let mut mouse: Option<::glutin::MouseButton> = None; + let mut command: Option<CommandWrapper> = None; use ::serde::de::Error; @@ -626,17 +640,32 @@ impl de::Deserialize for RawBinding { } mouse = Some(visitor.visit_value::<MouseButton>()?.into_inner()); - } + }, + Field::Command => { + if command.is_some() { + return Err(<V::Error as Error>::duplicate_field("command")); + } + + command = Some(visitor.visit_value::<CommandWrapper>()?); + }, } } - let action = match (action, chars) { - (Some(_), Some(_)) => { - return Err(V::Error::custom("must specify only chars or action")); + let action = match (action, chars, command) { + (Some(action), None, None) => action, + (None, Some(chars), None) => Action::Esc(chars), + (None, None, Some(cmd)) => { + match cmd { + CommandWrapper::Just(program) => { + Action::Command(program, vec![]) + }, + CommandWrapper::WithArgs { program, args } => { + Action::Command(program, args) + }, + } }, - (Some(action), _) => action, - (_, Some(chars)) => Action::Esc(chars), - _ => return Err(V::Error::custom("must specify chars or action")) + (None, None, None) => return Err(V::Error::custom("must specify chars, action or command")), + _ => return Err(V::Error::custom("must specify only chars, action or command")), }; let mode = mode.unwrap_or_else(TermMode::empty); @@ -659,7 +688,7 @@ impl de::Deserialize for RawBinding { } const FIELDS: &'static [&'static str] = &[ - "key", "mods", "mode", "action", "chars", "mouse" + "key", "mods", "mode", "action", "chars", "mouse", "command", ]; deserializer.deserialize_struct("RawBinding", FIELDS, RawBindingVisitor) diff --git a/src/input.rs b/src/input.rs index a1bd5c9a..47374e47 100644 --- a/src/input.rs +++ b/src/input.rs @@ -20,6 +20,7 @@ //! determine what to do when a non-modifier key is pressed. use std::borrow::Cow; use std::mem; +use std::process::Command; use std::time::Instant; use copypasta::{Clipboard, Load, Buffer}; @@ -144,6 +145,9 @@ pub enum Action { /// Paste contents of selection buffer PasteSelection, + /// Run given command + Command(String, Vec<String>), + /// Quits Alacritty. Quit, } @@ -174,6 +178,17 @@ impl Action { warn!("Error loading data from clipboard. {}", Red(err)); }); }, + Action::Command(ref program, ref args) => { + trace!("running command: {} {:?}", program, args); + match Command::new(program).args(args).spawn() { + Ok(child) => { + debug!("spawned new proc with pid: {}", child.id()); + }, + Err(err) => { + warn!("couldn't run command: {}", err); + }, + } + }, Action::Quit => { // FIXME should do a more graceful shutdown ::std::process::exit(0); |