summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDominik MiedziƄski <dominik@mdzn.pl>2017-05-25 18:19:00 +0200
committerJoe Wilm <jwilm@users.noreply.github.com>2017-05-25 09:19:00 -0700
commit5977776874d16febbf26d73e833b4e4d104aa359 (patch)
tree7c8c2db296e28d33a39a924dbf4fe263e71b6e8f /src
parent112abf385fef32f30618b4ebb1d1c651661a6fae (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/config.rs49
-rw-r--r--src/input.rs15
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);