summaryrefslogtreecommitdiffstats
path: root/src/commands/open_file.rs
diff options
context:
space:
mode:
authorJiayi Zhao <jeff.no.zhao@gmail.com>2020-03-20 13:08:26 -0400
committerJiayi Zhao <jeff.no.zhao@gmail.com>2020-03-20 14:00:05 -0400
commit8fc59f0a0c3729d201f844738db5275035f59f2d (patch)
tree6deeba8db7275387f44b5bdb03c1f801efe437ab /src/commands/open_file.rs
parent84e912b7779faaaeb09d1085e09630a548c7fb54 (diff)
add initial support for detecting mimetypes
Diffstat (limited to 'src/commands/open_file.rs')
-rw-r--r--src/commands/open_file.rs96
1 files changed, 68 insertions, 28 deletions
diff --git a/src/commands/open_file.rs b/src/commands/open_file.rs
index 5d1e7de..66c514c 100644
--- a/src/commands/open_file.rs
+++ b/src/commands/open_file.rs
@@ -4,6 +4,7 @@ use crate::commands::{ChangeDirectory, JoshutoCommand, JoshutoRunnable};
use crate::config::mimetype::JoshutoMimetypeEntry;
use crate::context::JoshutoContext;
use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult};
+use crate::fs::{JoshutoDirEntry, JoshutoMetadata};
use crate::ui::widgets::{TuiMenu, TuiTextField};
use crate::ui::TuiBackend;
use crate::util::load_child::LoadChild;
@@ -21,45 +22,70 @@ impl OpenFile {
"open_file"
}
- pub fn get_options<'a>(path: &Path) -> Vec<&'a JoshutoMimetypeEntry> {
+ pub fn get_options<'a>(entry: &JoshutoDirEntry) -> Vec<&'a JoshutoMimetypeEntry> {
let mut mimetype_options: Vec<&JoshutoMimetypeEntry> = Vec::new();
/* extensions have priority */
- if let Some(file_ext) = path.extension() {
+ if let Some(file_ext) = entry.file_path().extension() {
if let Some(file_ext) = file_ext.to_str() {
let ext_entries = MIMETYPE_T.get_entries_for_ext(file_ext);
mimetype_options.extend(ext_entries);
}
}
+ #[cfg(feature = "file_mimetype")]
+ {
+ if let Some(mimetype) = entry.metadata.mimetype.as_ref() {
+ let mime_entries = MIMETYPE_T.get_entries_for_mimetype(mimetype.as_str());
+ mimetype_options.extend(mime_entries);
+ }
+ }
mimetype_options
}
fn open(context: &mut JoshutoContext, backend: &mut TuiBackend) -> std::io::Result<()> {
let mut dirpath = None;
- let mut filepaths = None;
-
- if let Some(curr_list) = context.tabs[context.curr_tab_index].curr_list_ref() {
- if let Some(index) = curr_list.index {
- let child_path = curr_list.contents[index].file_path();
- if child_path.is_dir() {
- dirpath = Some(child_path.clone());
- } else {
- filepaths = Some(curr_list.get_selected_paths());
- }
+ let mut selected_entries = None;
+
+ {
+ let curr_tab = context.curr_tab_ref();
+ match curr_tab.curr_list_ref() {
+ None => return Ok(()),
+ Some(curr_list) => match curr_list.get_curr_ref() {
+ Some(entry) if entry.file_path().is_dir() => {
+ let path = entry.file_path().clone();
+ dirpath = Some(path);
+ }
+ Some(entry) => {
+ let vec: Vec<&JoshutoDirEntry> = curr_list.selected_entries().collect();
+ if vec.is_empty() {
+ selected_entries = Some(vec![entry]);
+ } else {
+ selected_entries = Some(vec);
+ }
+ }
+ None => return Ok(()),
+ },
}
}
+
if let Some(path) = dirpath {
ChangeDirectory::cd(path.as_path(), context)?;
LoadChild::load_child(context)?;
- } else if let Some(paths) = filepaths {
- let options = Self::get_options(paths[0]);
+ } else if let Some(entries) = selected_entries {
+ let options = Self::get_options(entries[0]);
+ let entry_paths: Vec<&Path> = entries.iter().map(|e| e.file_path().as_path()).collect();
if !options.is_empty() {
- backend.terminal_drop();
- let res = options[0].execute_with(&paths);
- backend.terminal_restore()?;
+ let res = if options[0].get_fork() {
+ backend.terminal_drop();
+ let res = options[0].execute_with(entry_paths.as_slice());
+ backend.terminal_restore()?;
+ res
+ } else {
+ options[0].execute_with(entry_paths.as_slice())
+ };
return res;
} else {
- OpenFileWith::open_with(context, backend, &paths)?;
+ OpenFileWith::open_with(context, backend, &entries)?;
}
}
Ok(())
@@ -95,11 +121,11 @@ impl OpenFileWith {
pub fn open_with(
context: &JoshutoContext,
backend: &mut TuiBackend,
- paths: &[&PathBuf],
+ entries: &[&JoshutoDirEntry],
) -> std::io::Result<()> {
const PROMPT: &str = "open_with ";
- let mimetype_options: Vec<&JoshutoMimetypeEntry> = OpenFile::get_options(&paths[0]);
+ let mimetype_options: Vec<&JoshutoMimetypeEntry> = OpenFile::get_options(&entries[0]);
let user_input: Option<String> = {
let menu_options: Vec<String> = mimetype_options
@@ -116,6 +142,7 @@ impl OpenFileWith {
.menu(&mut menu_widget);
textfield.get_input(backend, &context)
};
+ let entry_paths: Vec<&Path> = entries.iter().map(|e| e.file_path().as_path()).collect();
match user_input.as_ref() {
Some(user_input) if user_input.starts_with(PROMPT) => {
@@ -129,10 +156,10 @@ impl OpenFileWith {
Ok(n) => {
let mimetype_entry = &mimetype_options[n];
if mimetype_entry.get_fork() {
- mimetype_entry.execute_with(paths)
+ mimetype_entry.execute_with(entry_paths.as_slice())
} else {
backend.terminal_drop();
- let res = mimetype_entry.execute_with(paths);
+ let res = mimetype_entry.execute_with(entry_paths.as_slice());
backend.terminal_restore()?;
res
}
@@ -144,7 +171,7 @@ impl OpenFileWith {
backend.terminal_drop();
let res = JoshutoMimetypeEntry::new(String::from(cmd))
.args(args_iter)
- .execute_with(paths);
+ .execute_with(entry_paths.as_slice());
backend.terminal_restore()?;
res
}
@@ -168,18 +195,31 @@ impl std::fmt::Display for OpenFileWith {
impl JoshutoRunnable for OpenFileWith {
fn execute(&self, context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> {
- let paths = match &context.tabs[context.curr_tab_index].curr_list_ref() {
- Some(curr_list) => curr_list.get_selected_paths(),
- None => vec![],
+ let selected_entries = {
+ let curr_tab = context.curr_tab_ref();
+ match curr_tab.curr_list_ref() {
+ None => vec![],
+ Some(curr_list) => match curr_list.get_curr_ref() {
+ Some(entry) => {
+ let vec: Vec<&JoshutoDirEntry> = curr_list.selected_entries().collect();
+ if vec.is_empty() {
+ vec![entry]
+ } else {
+ vec
+ }
+ }
+ None => vec![],
+ },
+ }
};
- if paths.is_empty() {
+ if selected_entries.is_empty() {
return Err(JoshutoError::new(
JoshutoErrorKind::IONotFound,
String::from("No files selected"),
));
}
- Self::open_with(context, backend, &paths)?;
+ Self::open_with(context, backend, &selected_entries)?;
Ok(())
}
}