diff options
author | rabite <rabite@posteo.de> | 2019-02-16 15:01:46 +0100 |
---|---|---|
committer | rabite <rabite@posteo.de> | 2019-02-16 15:01:46 +0100 |
commit | 6802a764799120a715e1498d5b14aba69439b055 (patch) | |
tree | 522c1244713317668b6a9320235e684e579dafa3 /src | |
parent | f77178938cb015ce25fe522fa580efe6b429653e (diff) |
async v3-beta
Diffstat (limited to 'src')
-rw-r--r-- | src/file_browser.rs | 3 | ||||
-rw-r--r-- | src/files.rs | 22 | ||||
-rw-r--r-- | src/main.rs | 5 | ||||
-rw-r--r-- | src/miller_columns.rs | 6 | ||||
-rw-r--r-- | src/preview.rs | 442 | ||||
-rw-r--r-- | src/textview.rs | 7 |
6 files changed, 266 insertions, 219 deletions
diff --git a/src/file_browser.rs b/src/file_browser.rs index 3a178b0..01eb316 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -69,9 +69,6 @@ impl FileBrowser { self.columns.push_widget(view); self.update_preview(); }, - - Err(ref err) if err.description() == "placeholder".to_string() => - self.show_status("No! Can't open this!"), _ => { let status = std::process::Command::new("rifle") .args(file.path.file_name()) diff --git a/src/files.rs b/src/files.rs index 03f0dc6..7d7b3e4 100644 --- a/src/files.rs +++ b/src/files.rs @@ -1,5 +1,4 @@ use std::cmp::{Ord, Ordering}; -use std::error::Error; use std::ops::Index; use std::os::unix::fs::MetadataExt; use std::path::{Path, PathBuf}; @@ -8,6 +7,9 @@ use lscolors::LsColors; use mime_detective; use users; use chrono::TimeZone; +use failure::Error; + +use crate::fail::HError; lazy_static! { @@ -53,7 +55,7 @@ fn get_color(path: &Path, meta: &std::fs::Metadata) -> Option<lscolors::Color> { } impl Files { - pub fn new_from_path(path: &Path) -> Result<Files, Box<dyn Error>> { + pub fn new_from_path(path: &Path) -> Result<Files, Error> { let direntries: Result<Vec<_>, _> = std::fs::read_dir(&path)?.collect(); let files: Vec<_> = direntries? @@ -244,7 +246,7 @@ impl File { } } - pub fn new_from_path(path: &Path) -> Result<File, Box<Error>> { + pub fn new_from_path(path: &Path) -> Result<File, Error> { let pathbuf = path.to_path_buf(); let name = path .file_name() @@ -265,7 +267,7 @@ impl File { ) } - pub fn new_placeholder(path: &Path) -> Result<File, Box<Error>> { + pub fn new_placeholder(path: &Path) -> Result<File, Error> { let mut file = File::new_from_path(path)?; file.name = "<empty>".to_string(); file.kind = Kind::Placeholder; @@ -314,16 +316,8 @@ impl File { self.kind == Kind::Directory } - pub fn read_dir(&self) -> Result<Files, Box<Error>> { - match self.kind { - Kind::Placeholder => { - let e: Box<Error> - = From::from("placeholder".to_string()); - Err(e) - }, - _ => Files::new_from_path(&self.path) - } - + pub fn read_dir(&self) -> Result<Files, Error> { + Files::new_from_path(&self.path) } diff --git a/src/main.rs b/src/main.rs index 3ac01ac..7de9a46 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,10 @@ extern crate termion; extern crate unicode_width; #[macro_use] extern crate lazy_static; +#[macro_use] +extern crate failure; +#[macro_use] +extern crate failure_derive; extern crate alphanumeric_sort; extern crate dirs_2; extern crate lscolors; @@ -35,6 +39,7 @@ mod window; mod hbox; mod tabview; mod async_widget; +mod fail; use window::Window; ///use async_widget::AsyncPlug; diff --git a/src/miller_columns.rs b/src/miller_columns.rs index 0abb4cb..6351e8d 100644 --- a/src/miller_columns.rs +++ b/src/miller_columns.rs @@ -1,7 +1,7 @@ use termion::event::Key; use crate::coordinates::{Coordinates, Position, Size}; -use crate::preview::AsyncPreviewer; +use crate::preview::Previewer; use crate::widget::Widget; use crate::hbox::HBox; @@ -11,7 +11,7 @@ pub struct MillerColumns<T> where T: Widget { // pub left: Option<T>, // pub main: Option<T>, //pub preview: AsyncPreviewer, - pub preview: crate::preview::LOLPreviewer, + pub preview: Previewer, pub ratio: (u16, u16, u16), pub coordinates: Coordinates, } @@ -25,7 +25,7 @@ where widgets: HBox::new(), coordinates: Coordinates::new(), ratio: (20, 30, 50), - preview: crate::preview::LOLPreviewer::new() + preview: Previewer::new() } } diff --git a/src/preview.rs b/src/preview.rs index b7a2533..e458cfc 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -1,3 +1,6 @@ +use failure::Error; +use failure::Fail; + use std::io::Write; use std::sync::Mutex; use std::sync::Arc; @@ -7,8 +10,10 @@ use crate::files::{File, Files, Kind}; use crate::listview::ListView; use crate::textview::TextView; use crate::widget::Widget; -//use crate::async_widget::AsyncPlug; -use crate::async_widget::AsyncPlug2; +use crate::fail::HError; + + + lazy_static! { static ref PIDS: Arc<Mutex<Vec<u32>>> = { Arc::new(Mutex::new(vec![])) }; @@ -57,11 +62,11 @@ impl<T: Send + 'static> WillBe<T> where { fn run(&mut self, closure: Box<Fn() -> T + Send>, tx: std::sync::mpsc::Sender<T>) { std::thread::spawn(move|| { let thing = closure(); - tx.send(thing).unwrap(); + tx.send(thing).ok(); }); } - pub fn check(&mut self) -> Result<(), Box<std::error::Error>> { + pub fn check(&mut self) -> Result<(), Error> { match self.state { State::Is(_) => Ok(()), _ => { @@ -99,6 +104,15 @@ struct WillBeWidget<T: Widget + Send> { coordinates: Coordinates } +impl<T: Widget + Send + 'static> WillBeWidget<T> { + fn new(closure: Box<Fn() -> T + Send>) -> WillBeWidget<T> { + WillBeWidget { + willbe: WillBe::new_become(Box::new(move || closure())), + coordinates: Coordinates::new() + } + } +} + // impl<T: Widget + Send> WillBeWidget<T> { // fn is_widget(&self) -> bool { // self.willbe.check().is_ok() @@ -148,79 +162,134 @@ impl<T: Widget + Send> Widget for WillBeWidget<T> { } } - +type WidgetO = Box<dyn Widget + Send>; #[derive(PartialEq)] -pub struct LOLPreviewer { +pub struct Previewer { widget: WillBeWidget<Box<dyn Widget + Send>>, } -impl LOLPreviewer { - pub fn new() -> LOLPreviewer { - let willbe = WillBeWidget::<Box<dyn Widget + Send>> { - coordinates: Coordinates::new(), - willbe: WillBe::new_become(Box::new(move || { +impl Previewer { + pub fn new() -> Previewer { + let willbe = WillBeWidget::new(Box::new(move || { Box::new(crate::textview::TextView { lines: vec![], buffer: String::new(), coordinates: Coordinates::new() }) as Box<dyn Widget + Send> - })) - }; - LOLPreviewer { widget: willbe } + })); + Previewer { widget: willbe } } fn become_preview(&mut self, widget: WillBeWidget<Box<dyn Widget + Send>>) { + let coordinates = self.get_coordinates().clone(); self.widget = widget; + self.set_coordinates(&coordinates); } pub fn set_file(&mut self, file: &File) { let coordinates = self.get_coordinates().clone(); - let redraw = crate::term::reset() + &self.get_redraw_empty_list(0); //let pids = PIDS.clone(); //kill_procs(); let file = file.clone(); - self.become_preview(WillBeWidget::<Box<dyn Widget + Send>> { - coordinates: coordinates.clone(), - willbe: WillBe::new_become(Box::new(move || { - //kill_procs(); - let file = file.clone(); - let mut bufout = std::io::BufWriter::new(std::io::stdout()); - match &file.kind { - Kind::Directory => match Files::new_from_path(&file.path) { - Ok(files) => { - //if !is_current(&file) { return } - let len = files.len(); - //if len == 0 { return }; - let mut file_list = ListView::new(files); - file_list.set_coordinates(&coordinates); - file_list.refresh(); - //if !is_current(&file) { return } - file_list.animate_slide_up(); - return Box::new(file_list) as Box<dyn Widget + Send> - - } - Err(err) => {}, - } - _ => {} - }; - let textview = crate::textview::TextView { - lines: vec![], - buffer: "".to_string(), - coordinates: Coordinates::new(), - }; - return Box::new(textview) as Box<dyn Widget + Send> - })) - }); + self.become_preview(WillBeWidget::new(Box::new(move || { + //kill_procs(); + let file = file.clone(); + + if file.kind == Kind::Directory { + let preview = Previewer::preview_dir(&file, &coordinates); + let mut preview = preview.unwrap(); + preview.set_coordinates(&coordinates); + return preview + } + + if file.get_mime() == Some("text".to_string()) { + return Previewer::preview_text(&file, &coordinates) + } else { + + } + + let mut textview = crate::textview::TextView::new_blank(); + textview.set_coordinates(&coordinates); + return Box::new(textview) as Box<dyn Widget + Send> + }))); + } + + fn preview_dir(file: &File, coordinates: &Coordinates) + -> Result<WidgetO, Error> { + let files = Files::new_from_path(&file.path)?; + //if !is_current(&file) { return } + let len = files.len(); + //if len == 0 { return }; + let mut file_list = ListView::new(files); + file_list.set_coordinates(&coordinates); + file_list.refresh(); + //if !is_current(&file) { return } + file_list.animate_slide_up(); + Ok(Box::new(file_list) as Box<dyn Widget + Send>) + } + + fn preview_text(file: &File, coordinates: &Coordinates) -> Box<dyn Widget + Send> { + let lines = coordinates.ysize() as usize; + let mut textview + = TextView::new_from_file_limit_lines(&file, + lines); + //if !is_current(&file) { return } + textview.set_coordinates(&coordinates); + textview.refresh(); + //if !is_current(&file) { return } + textview.animate_slide_up(); + Box::new(textview) + } + + fn preview_external(file: &File, coordinates: &Coordinates) + -> Result<Box<dyn Widget + Send>, HError> { + let process = + std::process::Command::new("scope.sh") + .arg(&file.name) + .arg("10".to_string()) + .arg("10".to_string()) + .arg("".to_string()) + .arg("false".to_string()) + .stdin(std::process::Stdio::null()) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::null()) + .spawn()?; + + let pid = process.id(); + let mut pids = PIDS.lock()?; + pids.push(pid); + + //if !is_current(&file) { return } + + let output = process.wait_with_output()?; + + let status = output.status.code() + .ok_or(HError::PreviewFailed{file: file.name.clone()})?; + + if status == 0 || status == 5 && is_current(&file) { + let output = std::str::from_utf8(&output.stdout) + .unwrap() + .to_string(); + let mut textview = TextView { + lines: output.lines().map(|s| s.to_string()).collect(), + buffer: String::new(), + coordinates: Coordinates::new() }; + textview.set_coordinates(&coordinates); + textview.refresh(); + textview.animate_slide_up(); + return Ok(Box::new(textview)) + } + Err(HError::PreviewFailed{file: file.name.clone()}) } -} +} -impl Widget for LOLPreviewer { +impl Widget for Previewer { fn get_coordinates(&self) -> &Coordinates { &self.widget.coordinates } @@ -264,161 +333,136 @@ impl Widget for LOLPreviewer { -#[derive(PartialEq)] -pub struct AsyncPreviewer { - pub file: Option<File>, - pub buffer: String, - pub coordinates: Coordinates, - pub async_plug: AsyncPlug2<Box<dyn Widget + Send + 'static>> -} +// #[derive(PartialEq)] +// pub struct AsyncPreviewer { +// pub file: Option<File>, +// pub buffer: String, +// pub coordinates: Coordinates, +// pub async_plug: AsyncPlug2<Box<dyn Widget + Send + 'static>> +// } -impl AsyncPreviewer { - pub fn new() -> AsyncPreviewer { - let closure = Box::new(|| { - Box::new(crate::textview::TextView { - lines: vec![], - buffer: "".to_string(), - coordinates: Coordinates::new() - }) as Box<dyn Widget + Send + 'static> - }); - - AsyncPreviewer { - file: None, - buffer: String::new(), - coordinates: Coordinates::new(), - async_plug: AsyncPlug2::new_from_closure(closure), - } - } - pub fn set_file(&mut self, file: &File) { - let coordinates = self.coordinates.clone(); - let file = file.clone(); - let redraw = crate::term::reset() + &self.get_redraw_empty_list(0); - //let pids = PIDS.clone(); - //kill_procs(); +// impl AsyncPreviewer { +// pub fn new() -> AsyncPreviewer { +// let closure = Box::new(|| { +// Box::new(crate::textview::TextView { +// lines: vec![], +// buffer: "".to_string(), +// coordinates: Coordinates::new() +// }) as Box<dyn Widget + Send + 'static> +// }); + +// AsyncPreviewer { +// file: None, +// buffer: String::new(), +// coordinates: Coordinates::new(), +// async_plug: AsyncPlug2::new_from_closure(closure), +// } +// } +// pub fn set_file(&mut self, file: &File) { +// let coordinates = self.coordinates.clone(); +// let file = file.clone(); +// let redraw = crate::term::reset() + &self.get_redraw_empty_list(0); +// //let pids = PIDS.clone(); +// //kill_procs(); + +// self.async_plug.replace_widget(Box::new(move || { +// kill_procs(); +// let mut bufout = std::io::BufWriter::new(std::io::stdout()); +// match &file.kind { +// Kind::Directory => match Files::new_from_path(&file.path) { +// Ok(files) => { +// //if !is_current(&file) { return } +// let len = files.len(); +// //if len == 0 { return }; +// let mut file_list = ListView::new(files); +// file_list.set_coordinates(&coordinates); +// file_list.refresh(); +// //if !is_current(&file) { return } +// file_list.animate_slide_up(); +// return Box::new(file_list) + +// } +// Err(err) => { +// write!(bufout, "{}", redraw).unwrap(); +// let textview = crate::textview::TextView { +// lines: vec![], +// buffer: "".to_string(), +// coordinates: Coordinates::new(), +// }; +// return Box::new(textview) +// }, +// } +// _ => { +// if file.get_mime() == Some("text".to_string()) { +// let lines = coordinates.ysize() as usize; +// let mut textview +// = TextView::new_from_file_limit_lines(&file, +// lines); +// //if !is_current(&file) { return } +// textview.set_coordinates(&coordinates); +// textview.refresh(); +// //if !is_current(&file) { return } +// textview.animate_slide_up(); +// return Box::new(textview) +// } else { +// let process = +// std::process::Command::new("scope.sh") +// .arg(&file.name) +// .arg("10".to_string()) +// .arg("10".to_string()) +// .arg("".to_string()) +// .arg("false".to_string()) +// .stdin(std::process::Stdio::null()) +// .stdout(std::process::Stdio::piped()) +// .stderr(std::process::Stdio::null()) +// .spawn().unwrap(); + +// let pid = process.id(); +// PIDS.lock().unwrap().push(pid); + +// //if !is_current(&file) { return } + +// let output = process.wait_with_output(); +// match output { +// Ok(output) => { +// let status = output.status.code(); +// match status { +// Some(status) => { +// if status == 0 || status == 5 && is_current(&file) { +// let output = std::str::from_utf8(&output.stdout) +// .unwrap() +// .to_string(); +// let mut textview = TextView { +// lines: output.lines().map(|s| s.to_string()).collect(), +// buffer: String::new(), +// coordinates: Coordinates::new() }; +// textview.set_coordinates(&coordinates); +// textview.refresh(); +// textview.animate_slide_up(); +// return Box::new(textview) +// } +// }, None => {} +// } +// }, Err(_) => {} +// } + +// write!(bufout, "{}", redraw).unwrap(); +// //std::io::stdout().flush().unwrap(); +// let textview = crate::textview::TextView { +// lines: vec![], +// buffer: "".to_string(), +// coordinates: Coordinates::new(), +// }; +// return Box::new(textview) +// } +// } +// }})) +// } +// } - self.async_plug.replace_widget(Box::new(move || { - kill_procs(); - let mut bufout = std::io::BufWriter::new(std::io::stdout()); - match &file.kind { - Kind::Directory => match Files::new_from_path(&file.path) { - Ok(files) => { - //if !is_current(&file) { return } - let len = files.len(); - //if len == 0 { return }; - let mut file_list = ListView::new(files); - file_list.set_coordinates(&coordinates); - file_list.refresh(); - //if !is_current(&file) { return } - file_list.animate_slide_up(); - return Box::new(file_list) - - } - Err(err) => { - write!(bufout, "{}", redraw).unwrap(); - let textview = crate::textview::TextView { - lines: vec![], - buffer: "".to_string(), - coordinates: Coordinates::new(), - }; - return Box::new(textview) - }, - } - _ => { - if file.get_mime() == Some("text".to_string()) { - let lines = coordinates.ysize() as usize; - let mut textview - = TextView::new_from_file_limit_lines(&file, - lines); - //if !is_current(&file) { return } - textview.set_coordinates(&coordinates); - textview.refresh(); - //if !is_current(&file) { return } - textview.animate_slide_up(); - return Box::new(textview) - } else { - let process = - std::process::Command::new("scope.sh") - .arg(&file.name) - .arg("10".to_string()) - .arg("10".to_string()) - .arg("".to_string()) - .arg("false".to_string()) - .stdin(std::process::Stdio::null()) - .stdout(std::process::Stdio::piped()) - .stderr(std::process::Stdio::null()) - .spawn().unwrap(); - - let pid = process.id(); - PIDS.lock().unwrap().push(pid); - - //if !is_current(&file) { return } - - let output = process.wait_with_output(); - match output { - Ok(output) => { - let status = output.status.code(); - match status { - Some(status) => { - if status == 0 || status == 5 && is_current(&file) { - let output = std::str::from_utf8(&output.stdout) - .unwrap() - .to_string(); - let mut textview = TextView { - lines: output.lines().map(|s| s.to_string()).collect(), - buffer: String::new(), - coordinates: Coordinates::new() }; - textview.set_coordinates(&coordinates); - textview.refresh(); - textview.animate_slide_up(); - return Box::new(textview) - } - }, None => {} - } - }, Err(_) => {} - } - - write!(bufout, "{}", redraw).unwrap(); - //std::io::stdout().flush().unwrap(); - let textview = crate::textview::TextView { - lines: vec![], - buffer: "".to_string(), - coordinates: Coordinates::new(), - }; - return Box::new(textview) - } - } - }})) - } -} -impl Widget for AsyncPreviewer { - fn get_coordinates(&self) -> &Coordinates { - &self.coordinates - } - fn set_coordinates(&mut self, coordinates: &Coordinates) { - if self.coordinates == *coordinates { - return; - } - self.coordinates = coordinates.clone(); - self.async_plug.set_coordinates(&coordinates.clone()); - self.async_plug.refresh(); - } - fn render_header(&self) -> String { - "".to_string() - } - fn refresh(&mut self) { - let file = self.file.clone(); - if let Some(file) = file { - self.set_file(&file); - } - } - fn get_drawlist(&self) -> String { - self.async_plug.get_drawlist(); - "".to_string() - } -} impl<T> Widget for Box<T> where T: Widget + ?Sized { fn get_coordinates(&self) -> &Coordinates { diff --git a/src/textview.rs b/src/textview.rs index f229828..304d664 100644 --- a/src/textview.rs +++ b/src/textview.rs @@ -15,6 +15,13 @@ pub struct TextView { } impl TextView { + pub fn new_blank() -> TextView { + TextView { + lines: vec![], + buffer: String::new(), + coordinates: Coordinates::new() + } + } pub fn new_from_file(file: &File) -> TextView { let file = std::fs::File::open(&file.path).unwrap(); let file = std::io::BufReader::new(file); |