diff --git a/ui/src/components/utilities.rs b/ui/src/components/utilities.rs index cca21c6a6..4b3d4cea9 100644 --- a/ui/src/components/utilities.rs +++ b/ui/src/components/utilities.rs @@ -493,7 +493,7 @@ impl Component for Pager { } fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool { let shortcuts = &self.get_shortcuts(context)[Self::DESCRIPTION]; - match *event { + match event { UIEvent::Input(ref key) if *key == shortcuts["scroll_up"] => { if self.cursor_pos > 0 { self.cursor_pos -= 1; @@ -521,6 +521,41 @@ impl Component for Pager { UIEvent::ChangeMode(UIMode::Normal) => { self.dirty = true; } + UIEvent::Action(Pager(Pipe(ref bin, ref args))) => { + use std::io::Write; + use std::process::{Command, Stdio}; + let mut command_obj = match Command::new(bin) + .args(args.as_slice()) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + { + Ok(o) => o, + Err(e) => { + context.replies.push_back(UIEvent::StatusEvent( + StatusEvent::DisplayMessage(format!( + "Could not pipe to {}: {}", + bin, e + )), + )); + return true; + } + }; + let stdin = command_obj.stdin.as_mut().expect("failed to open stdin"); + stdin + .write_all(self.text.as_bytes()) + .expect("Failed to write to stdin"); + + context + .replies + .push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(format!( + "Pager text piped to '{}{}{}'", + &bin, + if args.is_empty() { "" } else { " " }, + args.join(", ") + )))); + return true; + } UIEvent::Resize => { self.dirty = true; self.max_cursor_pos = None; diff --git a/ui/src/execute.rs b/ui/src/execute.rs index 7008064ad..a78334153 100644 --- a/ui/src/execute.rs +++ b/ui/src/execute.rs @@ -28,6 +28,7 @@ pub mod actions; pub use crate::actions::Action::{self, *}; pub use crate::actions::ListingAction::{self, *}; pub use crate::actions::MailingListAction::{self, *}; +pub use crate::actions::PagerAction::{self, *}; pub use crate::actions::TabAction::{self, *}; /* Create a const table with every command part that can be auto-completed and its description */ @@ -161,6 +162,29 @@ define_commands!([ ) ); ) + }, + /* Pipe pager contents to binary */ + { tags: ["pipe "], + desc: "pipe EXECUTABLE ARGS", + parser:( + named!( pipe, + alt_complete!( + do_parse!( + ws!(tag!("pipe")) + >> bin: map_res!(is_not!(" "), std::str::from_utf8) + >> is_a!(" ") + >> args: separated_list!(is_a!(" "), is_not!(" ")) + >> ({ + Pager(Pipe(bin.to_string(), args.into_iter().map(|v| String::from_utf8(v.to_vec()).unwrap()).collect::>())) + })) | do_parse!( + ws!(tag!("pipe")) + >> bin: ws!(map_res!(is_not!(" "), std::str::from_utf8)) + >> ({ + Pager(Pipe(bin.to_string(), Vec::new())) + }) + )) + ); + ) } ]); @@ -207,5 +231,5 @@ named!( alt_complete!(toggle | envelope_action | filter | toggle_thread_snooze) ); named!(pub parse_command, - alt_complete!( goto | listing_action | sort | subsort | close | mailinglist | setenv | printenv) + alt_complete!( goto | listing_action | sort | subsort | close | mailinglist | setenv | printenv | pipe) ); diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs index 0b13bdf72..9b569c534 100644 --- a/ui/src/execute/actions.rs +++ b/ui/src/execute/actions.rs @@ -59,6 +59,11 @@ pub enum MailingListAction { ListUnsubscribe, } +#[derive(Debug)] +pub enum PagerAction { + Pipe(String, Vec), +} + #[derive(Debug)] pub enum Action { Listing(ListingAction), @@ -68,6 +73,7 @@ pub enum Action { Tab(TabAction), ToggleThreadSnooze, MailingListAction(MailingListAction), + Pager(PagerAction), SetEnv(String, String), PrintEnv(String), }