summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.rs8
-rw-r--r--src/fail.rs3
-rw-r--r--src/files.rs6
-rw-r--r--src/imgview.rs22
-rw-r--r--src/main.rs3
-rw-r--r--src/mediaview.rs60
-rw-r--r--src/preview.rs24
-rw-r--r--src/widget.rs13
8 files changed, 97 insertions, 42 deletions
diff --git a/src/config.rs b/src/config.rs
index 24bc995..e969f1a 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -77,6 +77,7 @@ pub struct Config {
pub icons: bool,
pub media_autoplay: bool,
pub media_mute: bool,
+ pub media_previewer: String
}
@@ -95,7 +96,8 @@ impl Config {
cd_cmd: "find -type d | fzf".to_string(),
icons: false,
media_autoplay: false,
- media_mute: false
+ media_mute: false,
+ media_previewer: "hunter-media".to_string()
}
}
@@ -128,6 +130,10 @@ impl Config {
Ok(("media_autoplay", "off")) => { config.media_autoplay = false; },
Ok(("media_mute", "on")) => { config.media_mute = true; },
Ok(("media_mute", "off")) => { config.media_mute = false; },
+ Ok(("media_previewer", cmd)) => {
+ let cmd = cmd.to_string();
+ config.select_cmd = cmd;
+ }
_ => { HError::config_error::<Config>(line.to_string()).log(); }
}
config
diff --git a/src/fail.rs b/src/fail.rs
index 0102fa0..b3351ba 100644
--- a/src/fail.rs
+++ b/src/fail.rs
@@ -10,6 +10,7 @@ use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use crate::foldview::LogEntry;
+use crate::mediaview::MediaError;
pub type HResult<T> = Result<T, HError>;
@@ -101,6 +102,8 @@ pub enum HError {
UTF8ParseError(std::str::Utf8Error),
#[fail(display = "Failed to parse integer!")]
ParseIntError(std::num::ParseIntError),
+ #[fail(display = "{}", _0)]
+ Media(MediaError)
}
impl HError {
diff --git a/src/files.rs b/src/files.rs
index 44f5470..a4bbbcc 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -424,9 +424,9 @@ impl Files {
file.path = new_path.into();
file.reload_meta()?;
},
- DebouncedEvent::Error(err, path) => {
- dbg!(err);
- dbg!(path);
+ DebouncedEvent::Error(err, _path) => {
+ // Never seen this happen. Should reload affected dirs
+ HError::log::<()>(&format!("{}", err))?;
},
_ => {},
}
diff --git a/src/imgview.rs b/src/imgview.rs
index d84fc03..93e1832 100644
--- a/src/imgview.rs
+++ b/src/imgview.rs
@@ -4,6 +4,8 @@ use crate::fail::HResult;
use std::path::{Path, PathBuf};
+use crate::mediaview::MediaError;
+
impl std::cmp::PartialEq for ImgView {
fn eq(&self, other: &Self) -> bool {
self.core == other.core &&
@@ -31,18 +33,34 @@ impl ImgView {
pub fn encode_file(&mut self) -> HResult<()> {
let (xsize, ysize) = self.core.coordinates.size_u();
+ let (xpos, ypos) = self.core.coordinates.position_u();
let file = &self.file;
+ let media_previewer = self.core.config().media_previewer;
- let output = std::process::Command::new("preview-gen")
+ let output = std::process::Command::new(&media_previewer)
.arg(format!("{}", (xsize)))
.arg(format!("{}", (ysize+1)))
+ .arg(format!("{}", xpos))
+ .arg(format!("{}", ypos))
.arg("image")
.arg(format!("true"))
.arg(format!("true"))
.arg(file.to_string_lossy().to_string())
- .output()?
+ .output()
+ .map_err(|e| {
+ let msg = format!("Couldn't run {}{}{}! Error: {:?}",
+ crate::term::color_red(),
+ media_previewer,
+ crate::term::normal_color(),
+ &e.kind());
+
+ self.core.show_status(&msg).ok();
+
+ MediaError::NoPreviewer(msg)
+ })?
.stdout;
+
let output = std::str::from_utf8(&output)?;
let output = output.lines()
.map(|l| l.to_string())
diff --git a/src/main.rs b/src/main.rs
index bc949fe..57d2dbd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -59,10 +59,7 @@ mod icon;
mod quick_actions;
mod trait_ext;
mod config_installer;
-
-#[cfg(feature = "img")]
mod imgview;
-#[cfg(feature = "video")]
mod mediaview;
diff --git a/src/mediaview.rs b/src/mediaview.rs
index f502591..2f9153c 100644
--- a/src/mediaview.rs
+++ b/src/mediaview.rs
@@ -1,5 +1,6 @@
use lazy_static;
use termion::event::Key;
+use failure::{self, Fail};
use crate::widget::{Widget, WidgetCore};
use crate::coordinates::Coordinates;
@@ -14,6 +15,18 @@ use std::sync::{Arc, Mutex, RwLock,
use std::io::{BufRead, BufReader, Write};
use std::process::Child;
+#[derive(Fail, Debug, Clone)]
+pub enum MediaError {
+ #[fail(display = "{}", _0)]
+ NoPreviewer(String)
+}
+
+impl From<MediaError> for HError {
+ fn from(e: MediaError) -> HError {
+ HError::Media(e)
+ }
+}
+
impl std::cmp::PartialEq for MediaView {
fn eq(&self, other: &Self) -> bool {
self.core == other.core
@@ -61,8 +74,23 @@ impl MediaType {
impl MediaView {
pub fn new_from_file(core: WidgetCore,
file: &Path,
- media_type: MediaType) -> MediaView {
+ media_type: MediaType) -> HResult<MediaView> {
+ // Check if previewer is present, or bail out to show message
+ let media_previewer = core.config().media_previewer;
+ if crate::minibuffer::find_bins(&media_previewer).is_err() {
+ let msg = format!("Couldn't find previewer: {}{}{}!",
+ crate::term::color_red(),
+ media_previewer,
+ crate::term::normal_color());
+
+
+ core.show_status(&msg).log();
+
+ return Err(MediaError::NoPreviewer(msg))?;
+ }
+
let (xsize, ysize) = core.coordinates.size_u();
+ let (xpos, ypos) = core.coordinates.position_u();
let (tx_cmd, rx_cmd) = channel();
let imgview = ImgView {
@@ -71,6 +99,7 @@ impl MediaView {
file: file.to_path_buf()
};
+ // Stuff that gets moved into the closure
let imgview = Arc::new(Mutex::new(imgview));
let thread_imgview = imgview.clone();
@@ -82,7 +111,8 @@ impl MediaView {
let process = Arc::new(Mutex::new(None));
let cprocess = process.clone();
let ctype = media_type.clone();
-
+ let ccore = core.clone();
+ let media_previewer = core.config().media_previewer;
let run_preview = Box::new(move | auto,
mute,
@@ -93,18 +123,32 @@ impl MediaView {
return Ok(());
}
- let mut previewer = std::process::Command::new("preview-gen")
+
+ let mut previewer = std::process::Command::new(&media_previewer)
.arg(format!("{}", (xsize)))
// Leave space for position/seek bar
.arg(format!("{}", (ysize-1)))
+ .arg(format!("{}", xpos))
+ .arg(format!("{}", ypos))
.arg(format!("{}", ctype.to_str()))
.arg(format!("{}", auto))
.arg(format!("{}", mute))
.arg(&path)
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
- .stderr(std::process::Stdio::inherit())
- .spawn()?;
+ .stderr(std::process::Stdio::piped())
+ .spawn()
+ .map_err(|e| {
+ let msg = format!("Couldn't run {}{}{}! Error: {:?}",
+ crate::term::color_red(),
+ media_previewer,
+ crate::term::normal_color(),
+ &e.kind());
+
+ ccore.show_status(&msg).log();
+
+ MediaError::NoPreviewer(msg)
+ })?;
let mut stdout = BufReader::new(previewer.stdout.take()?);
let mut stdin = previewer.stdin.take()?;
@@ -174,7 +218,7 @@ impl MediaView {
});
- MediaView {
+ Ok(MediaView {
core: core.clone(),
imgview: imgview,
file: file.to_path_buf(),
@@ -186,7 +230,7 @@ impl MediaView {
stale: stale,
process: process,
preview_runner: Some(run_preview)
- }
+ })
}
pub fn start_video(&mut self) -> HResult<()> {
@@ -308,7 +352,7 @@ impl MediaView {
// Since GStreamer sucks, just create a new instace
let mut view = MediaView::new_from_file(self.core.clone(),
&self.file.clone(),
- self.media_type.clone());
+ self.media_type.clone())?;
// Insert buffer to prevent flicker
let buffer = self.imgview.lock()?.buffer.clone();
diff --git a/src/preview.rs b/src/preview.rs
index 3d7a022..ac5ee60 100644
--- a/src/preview.rs
+++ b/src/preview.rs
@@ -12,10 +12,7 @@ use crate::widget::{Widget, WidgetCore};
use crate::coordinates::Coordinates;
use crate::fail::{HResult, HError, ErrorLog};
use crate::dirty::Dirtyable;
-
-#[cfg(feature = "img")]
use crate::imgview::ImgView;
-#[cfg(feature = "video")]
use crate::mediaview::MediaView;
@@ -201,9 +198,7 @@ impl PartialEq for Previewer {
enum PreviewWidget {
FileList(ListView<Files>),
TextView(TextView),
- #[cfg(feature = "img")]
ImgView(ImgView),
- #[cfg(feature = "video")]
MediaView(MediaView)
}
@@ -370,26 +365,23 @@ impl Previewer {
let is_gif = mime.subtype() == "gif";
match mime_type {
- #[cfg(feature = "video")]
_ if mime_type == "video" || is_gif => {
let media_type = crate::mediaview::MediaType::Video;
let mediaview = MediaView::new_from_file(core.clone(),
&file.path,
- media_type);
+ media_type)?;
return Ok(PreviewWidget::MediaView(mediaview));
}
- #[cfg(feature = "img")]
"image" => {
let imgview = ImgView::new_from_file(core.clone(),
&file.path())?;
return Ok(PreviewWidget::ImgView(imgview));
}
- #[cfg(feature = "video")]
"audio" => {
let media_type = crate::mediaview::MediaType::Audio;
let mediaview = MediaView::new_from_file(core.clone(),
&file.path,
- media_type);
+ media_type)?;
return Ok(PreviewWidget::MediaView(mediaview));
}
"text" if mime.subtype() == "plain" => {
@@ -578,9 +570,7 @@ impl Widget for PreviewWidget {
match self {
PreviewWidget::FileList(widget) => widget.get_core(),
PreviewWidget::TextView(widget) => widget.get_core(),
- #[cfg(feature = "img")]
PreviewWidget::ImgView(widget) => widget.get_core(),
- #[cfg(feature = "video")]
PreviewWidget::MediaView(widget) => widget.get_core()
}
}
@@ -588,9 +578,7 @@ impl Widget for PreviewWidget {
match self {
PreviewWidget::FileList(widget) => widget.get_core_mut(),
PreviewWidget::TextView(widget) => widget.get_core_mut(),
- #[cfg(feature = "img")]
PreviewWidget::ImgView(widget) => widget.get_core_mut(),
- #[cfg(feature = "video")]
PreviewWidget::MediaView(widget) => widget.get_core_mut()
}
}
@@ -598,9 +586,7 @@ impl Widget for PreviewWidget {
match self {
PreviewWidget::FileList(widget) => widget.set_coordinates(coordinates),
PreviewWidget::TextView(widget) => widget.set_coordinates(coordinates),
- #[cfg(feature = "img")]
PreviewWidget::ImgView(widget) => widget.set_coordinates(coordinates),
- #[cfg(feature = "video")]
PreviewWidget::MediaView(widget) => widget.set_coordinates(coordinates),
}
}
@@ -608,9 +594,7 @@ impl Widget for PreviewWidget {
match self {
PreviewWidget::FileList(widget) => widget.refresh(),
PreviewWidget::TextView(widget) => widget.refresh(),
- #[cfg(feature = "img")]
PreviewWidget::ImgView(widget) => widget.refresh(),
- #[cfg(feature = "video")]
PreviewWidget::MediaView(widget) => widget.refresh()
}
}
@@ -618,9 +602,7 @@ impl Widget for PreviewWidget {
match self {
PreviewWidget::FileList(widget) => widget.get_drawlist(),
PreviewWidget::TextView(widget) => widget.get_drawlist(),
- #[cfg(feature = "img")]
PreviewWidget::ImgView(widget) => widget.get_drawlist(),
- #[cfg(feature = "video")]
PreviewWidget::MediaView(widget) => widget.get_drawlist()
}
}
@@ -629,9 +611,7 @@ impl Widget for PreviewWidget {
match self {
PreviewWidget::FileList(widget) => widget.on_key(key),
PreviewWidget::TextView(widget) => widget.on_key(key),
- #[cfg(feature = "img")]
PreviewWidget::ImgView(widget) => widget.on_key(key),
- #[cfg(feature = "video")]
PreviewWidget::MediaView(widget) => widget.on_key(key)
}
}
diff --git a/src/widget.rs b/src/widget.rs
index 6cb19eb..8e2019d 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -192,9 +192,16 @@ impl WidgetCore {
}
pub fn config(&self) -> Config {
- self.config.read().unwrap().get()
- .map(|config| config.clone())
- .unwrap_or(Config::new())
+ self.get_conf()
+ .unwrap_or_else(|_| Config::new())
+ }
+
+ fn get_conf(&self) -> HResult<Config> {
+ let conf = self.config
+ .read()?
+ .get()?
+ .clone();
+ Ok(conf)
}
}