diff --git a/src/listview.rs b/src/listview.rs index 80cffdf..bd8f3a3 100644 --- a/src/listview.rs +++ b/src/listview.rs @@ -30,6 +30,7 @@ impl ListView where ListView: Widget { }; view } + pub fn to_trait(self) -> Box { Box::new(self) } @@ -170,6 +171,29 @@ impl ListView where self.refresh(); self.show_status(&format!("Direcories first: {}", self.content.dirs_first)); } + + fn exec_cmd(&mut self) { + match self.minibuffer("exec ($s for selected files)") { + Some(cmd) => { + let filename = self.selected_file().name.clone(); + let cmd = cmd.replace("$s", &filename); + self.show_status(&format!("Running: \"{}\"", &cmd)); + let mut parts = cmd.split_whitespace(); + let exe = parts.next().unwrap(); + let status = std::process::Command::new(exe).args(parts) + .status(); + match status { + Ok(status) => self.show_status(&format!("\"{}\" exited with {}", + cmd, + status)), + Err(err) => self.show_status(&format!("Can't run this \"{}\": {}", + cmd, + err)) + } + }, + None => self.show_status("") + } + } } @@ -248,6 +272,7 @@ impl Widget for ListView { }, Key::Char('s') => { self.cycle_sort() } , Key::Char('d') => self.toggle_dirs_first() , + Key::Char('!') => self.exec_cmd() , _ => { self.bad(Event::Key(key)); } } } diff --git a/src/widget.rs b/src/widget.rs index da98f60..2cbdbaf 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -43,10 +43,14 @@ pub trait Widget { } } - fn show_status(&mut self, status: &str) { + fn show_status(&self, status: &str) { crate::window::show_status(status); } + fn minibuffer(&self, query: &str) -> Option { + crate::window::minibuffer(query) + } + fn bad(&mut self, event: Event) { self.show_status(&format!("Stop the nasty stuff!! {:?} does nothing!", event)); } diff --git a/src/window.rs b/src/window.rs index 2e668db..b0a1974 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,6 +1,4 @@ -use std::cell::RefCell; use std::io::{stdin, stdout, Stdout, Write}; -use std::rc::*; use std::sync::{Arc, Mutex}; use termion::event::{Event, Key}; @@ -61,35 +59,7 @@ where Self::show_status(""); } - pub fn minibuffer(&mut self, query: &str) -> Option { - Self::show_status(&(query.to_string() + ": ")); - let reply = Rc::new(RefCell::new(String::new())); - - for key in stdin().events() { - let key = key.unwrap(); - match key { - Event::Key(Key::Esc) => { - return None; - } - Event::Key(Key::Char('\n')) => { - if reply.borrow().len() == 0 { - return None; - } else { - return Some(reply.borrow().to_string()); - } - } - Event::Key(Key::Char(c)) => { - reply.borrow_mut().push(c); - } - Event::Key(Key::Backspace) => { - reply.borrow_mut().pop(); - } - _ => {} - }; - Self::show_status(&(query.to_string() + ": " + &reply.borrow())); - } - None - } + pub fn handle_input(&mut self) { self.draw(); @@ -148,3 +118,26 @@ pub fn show_status(status: &str) { } draw_status(); } + +pub fn minibuffer(query: &str) -> Option { + show_status(&(query.to_string() + ": ")); + let mut buffer = "".to_string(); + + for key in stdin().events() { + match key { + Ok(Event::Key(key)) => { + match key { + Key::Esc => { return None }, + Key::Char('\n') => { return Some(buffer) }, + Key::Backspace => { buffer.pop(); }, + Key::Char(key) => { buffer = buffer + &format!("{}", key); }, + _ => {} + } + }, + _ => {} + } + show_status(&(query.to_string() + ": " + &buffer)); + + }; + None +}