added custom quick action creator based on quick actions

This commit is contained in:
rabite 2019-07-01 17:24:30 +02:00
parent 17abbbd59f
commit 366b9c6f3d
5 changed files with 189 additions and 13 deletions

View File

@ -0,0 +1,84 @@
#!/bin/sh
errecho() {
echo ${@} >&2
}
check_dir() {
DIR=${1}
[ -d ${DIR} ] ||
mkdir -p ${DIR} ||
(echo "Can't create directory: ${DIR}" && exit 1)
}
populate_file() {
FILE=${1}
# Don't try to overwrite existing file
test -e ${FILE} && return
cat > ${FILE} << EOF
#!/bin/sh
# Selected files are stored here
FILES=\${@}
# You can interate over them one by one
for FILE in \${FILES}; do
echo \$FILE
done
# Or process them all at once
echo "\${FILES}"
EOF
}
## Starting point
FILE=${1}
MIME=`hunter -m $FILE`
STATUS=$?
# MIME detection failed, bail out unless type is base
[ $STATUS != 0 ] && [ $type != "uni" ] &&
echo $MIME &&
exit 1
# Laziy not using XGD here because of OSX
ACTDIR="$HOME/.config/hunter/actions/"
MIME_BASE=`echo $MIME | cut -d "/" -f 1`
MIME_SUB=`echo $MIME | cut -d "/" -f 2`
case $type in
uni)
AFILE="${ACTDIR}/${name}.sh"
check_dir "${ACTDIR}"
populate_file "${AFILE}"
$EDITOR "${AFILE}"
test -e "${AFILE}" && chmod +x "${AFILE}"
;;
base)
BASEDIR="${ACTDIR}/$MIME_BASE"
AFILE="${BASEDIR}/${name}.sh"
check_dir "${BASEDIR}"
populate_file "${AFILE}"
$EDITOR "${AFILE}"
test -e ${AFILE} && chmod +x "${ACTDIR}/$name"
;;
sub)
SUBDIR="${ACTDIR}/${MIME_BASE}/${MIME_SUB}"
AFILE="${SUBDIR}/${name}.sh"
check_dir ${SUBDIR}
populate_file "${AFILE}"
$EDITOR "${AFILE}"
test -e ${AFILE} && chmod+ +x ${AFILE}
;;
esac

View File

@ -103,7 +103,9 @@ pub enum HError {
#[fail(display = "Failed to parse integer!")]
ParseIntError(std::num::ParseIntError),
#[fail(display = "{}", _0)]
Media(MediaError)
Media(MediaError),
#[fail(display = "{}", _0)]
Mime(MimeError),
}
impl HError {
@ -331,3 +333,22 @@ impl From<std::num::ParseIntError> for HError {
err
}
}
// MIME Errors
#[derive(Fail, Debug, Clone)]
pub enum MimeError {
#[fail(display = "Need a file to determine MIME type")]
NoFileProvided,
#[fail(display = "File access failed! Error: {}", _0)]
AccessFailed(Box<HError>),
#[fail(display = "No MIME type found for this file",)]
NoMimeFound
}
impl From<MimeError> for HError {
fn from(e: MimeError) -> Self {
HError::Mime(e)
}
}

View File

@ -69,9 +69,10 @@ mod mediaview;
use widget::{Widget, WidgetCore};
use term::ScreenExt;
use fail::{HResult, HError};
use fail::{HResult, HError, MimeError};
use file_browser::FileBrowser;
use tabview::TabView;
use trait_ext::PathBufMime;
fn reset_screen(core: &mut WidgetCore) -> HResult<()> {
@ -136,8 +137,7 @@ fn parse_args() -> HResult<()> {
.short("a")
.long("animation-off")
.help("Turn off animations")
.takes_value(false),
)
.takes_value(false))
.arg(
Arg::with_name("show-hidden")
.short("h")
@ -150,18 +150,32 @@ fn parse_args() -> HResult<()> {
.short("i")
.long("icons")
.help("Show icons for different file types")
.takes_value(false),
)
.takes_value(false))
// For "Add Action" action
.arg(
Arg::with_name("mime")
.short("m")
.long("mime")
.help("Print MIME type of file")
.takes_value(false))
.arg(
Arg::with_name("path")
.index(1)
.help("Start in <path>")
)
.help("Start in <path>"))
.get_matches();
let path = args.value_of("path");
// Just print MIME and quit
if args.is_present("mime") {
get_mime(path)
.map_err(|e| eprintln!("{}", e)).
ok();
// If we get heres something went wrong.
std::process::exit(1)
}
if let Some(path) = path {
std::env::set_current_dir(&path).ok();
}
@ -169,3 +183,18 @@ fn parse_args() -> HResult<()> {
crate::config::set_argv_config(args).ok();
Ok(())
}
fn get_mime(path: Option<&str>) -> HResult<()> {
let path = path.ok_or(MimeError::NoFileProvided)?;
let path = std::path::PathBuf::from(path);
path.get_mime()
.map(|mime| println!("{}", mime))
.map(|_| std::process::exit(0))
.map_err(|e| eprintln!("{}", e))
.map_err(|_| std::process::exit(1))
}

View File

@ -349,17 +349,22 @@ impl QuickAction {
.iter()
.fold(Ok(vec![]), |mut acc, query| {
// If error occured/input was cancelled just skip querying
// Turn into try_fold?
if acc.is_err() { return acc; }
match core.minibuffer(query) {
Err(HError::MiniBufferEmptyInput) => {
acc.as_mut().map(|acc| acc.push((OsString::from(query),
OsString::from("")))).ok();
acc.as_mut()
.map(|acc| acc.push((OsString::from(query),
OsString::from(""))))
.ok();
acc
}
Ok(input) => {
acc.as_mut().map(|acc| acc.push((OsString::from(query),
OsString::from(input)))).ok();
acc.as_mut()
.map(|acc| acc.push((OsString::from(query),
OsString::from(input))))
.ok();
acc
}
Err(err) => Err(err)
@ -505,7 +510,8 @@ impl QuickPath for PathBuf {
.collect::<Vec<&str>>()
.iter()
.skip(1)
.map(|q| q.to_string())
// Remove ! in queries from sync actions
.map(|q| q.trim_end_matches("!").to_string())
.collect())
.unwrap_or_else(|| vec![])
}

View File

@ -1,3 +1,17 @@
use std::path::PathBuf;
use crate::fail::{HResult, MimeError};
use crate::files::File;
// This makes using short-circuiting iterators more convenient
pub trait ExtractResult<T> {
fn extract(self) -> T;
}
@ -10,3 +24,25 @@ impl<T> ExtractResult<T> for Result<T,T> {
}
}
}
// To get MIME from Path without hassle
pub trait PathBufMime {
fn get_mime(&self) -> HResult<String>;
}
impl PathBufMime for PathBuf {
fn get_mime(&self) -> HResult<String> {
let mut file = File::new_from_path(&self, None)
.map_err(|e| MimeError::AccessFailed(Box::new(e)))?;
file.meta_sync()
.map_err(|e| MimeError::AccessFailed(Box::new(e)))?;;
file.get_mime()
.map(|mime| {
Ok(format!("{}", mime))
})
.ok_or(MimeError::NoMimeFound)?
}
}