summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-02-16 15:01:46 +0100
committerrabite <rabite@posteo.de>2019-02-16 15:01:46 +0100
commit6802a764799120a715e1498d5b14aba69439b055 (patch)
tree522c1244713317668b6a9320235e684e579dafa3
parentf77178938cb015ce25fe522fa580efe6b429653e (diff)
async v3-beta
-rw-r--r--Cargo.toml2
-rw-r--r--src/file_browser.rs3
-rw-r--r--src/files.rs22
-rw-r--r--src/main.rs5
-rw-r--r--src/miller_columns.rs6
-rw-r--r--src/preview.rs442
-rw-r--r--src/textview.rs7
7 files changed, 268 insertions, 219 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 471ad1a..e4abf86 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,8 @@ dirs-2 = "1.1.0"
users = "0.8"
chrono = "0.4"
libc = "*"
+failure = "0.1.5"
+failure_derive = "0.1.1"
#[profile.release]
#debug = true
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);