mirror of https://github.com/bobwen-dev/hunter
added custom quick action creator based on quick actions
This commit is contained in:
parent
17abbbd59f
commit
366b9c6f3d
|
@ -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
|
23
src/fail.rs
23
src/fail.rs
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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![])
|
||||
}
|
||||
|
|
|
@ -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)?
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue