summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsushi-shi <47691267+sushi-shi@users.noreply.github.com>2022-03-02 21:31:06 +0300
committerGitHub <noreply@github.com>2022-03-02 13:31:06 -0500
commit32ccec90bb41e83651a803229068007c6bb31a93 (patch)
tree3205afc6a36f7a089dc6171cd4cc93421e13f62d
parent7c6bb9ca1b3d7fb61a4cfc5c997ae0e247bd5acc (diff)
Try all options when opening files (#150)
-rw-r--r--src/commands/open_file.rs59
-rw-r--r--src/config/mimetype/entry.rs9
-rw-r--r--src/fs/dirlist.rs20
3 files changed, 40 insertions, 48 deletions
diff --git a/src/commands/open_file.rs b/src/commands/open_file.rs
index 3da11db..846e641 100644
--- a/src/commands/open_file.rs
+++ b/src/commands/open_file.rs
@@ -26,54 +26,53 @@ pub fn get_options<'a>(path: &path::Path) -> Vec<&'a AppMimetypeEntry> {
pub fn open(context: &mut AppContext, backend: &mut TuiBackend) -> JoshutoResult {
let config = context.config_ref();
- if let Some(entry) = context
- .tab_context_ref()
- .curr_tab_ref()
- .curr_list_ref()
- .and_then(|s| s.curr_entry_ref())
- {
- if entry.file_path().is_dir() {
+ let curr_list = context.tab_context_ref().curr_tab_ref().curr_list_ref();
+ let entry = curr_list.and_then(|s| s.curr_entry_ref());
+
+ match entry {
+ None => (),
+ Some(entry) if entry.file_path().is_dir() => {
let path = entry.file_path().to_path_buf();
change_directory::cd(path.as_path(), context)?;
reload::soft_reload(context.tab_context_ref().index, context)?;
- } else {
- let paths = context
- .tab_context_ref()
- .curr_tab_ref()
- .curr_list_ref()
- .map_or(vec![], |s| s.get_selected_paths());
-
- if paths.is_empty() {
- return Err(JoshutoError::new(
+ }
+ Some(_) if context.args.choosefiles.is_some() => {
+ context.quit = QuitType::ChooseFiles;
+ }
+ Some(_) => {
+ let paths = curr_list.map_or_else(Vec::new, |s| s.get_selected_paths());
+ let path = paths.get(0).ok_or_else(|| {
+ JoshutoError::new(
JoshutoErrorKind::Io(io::ErrorKind::NotFound),
String::from("No files selected"),
- ));
- }
- let files: Vec<&std::ffi::OsStr> = paths.iter().filter_map(|e| e.file_name()).collect();
+ )
+ })?;
- let options = get_options(paths[0].as_path());
+ let files: Vec<&std::ffi::OsStr> = paths.iter().filter_map(|e| e.file_name()).collect();
+ let option = get_options(path)
+ .into_iter()
+ .find(|option| option.program_exists());
- if context.args.choosefiles.is_some() {
- context.quit = QuitType::ChooseFiles;
- } else if !options.is_empty() {
- if options[0].get_fork() {
- options[0].execute_with(files.as_slice())?;
+ if let Some(option) = option {
+ if option.get_fork() {
+ option.execute_with(files.as_slice())?;
} else {
backend.terminal_drop();
- let res = options[0].execute_with(files.as_slice());
+ let result = option.execute_with(files.as_slice());
backend.terminal_restore()?;
- res?;
+ result?;
}
} else if config.xdg_open {
if config.xdg_open_fork {
- open::that_in_background(paths[0].as_path());
+ open::that_in_background(path);
} else {
backend.terminal_drop();
- open::that(paths[0].as_path())?;
+ let result = open::that(path);
backend.terminal_restore()?;
+ result?;
}
} else {
- open_with_helper(context, backend, options, files)?;
+ open_with_helper(context, backend, get_options(path), files)?;
}
}
}
diff --git a/src/config/mimetype/entry.rs b/src/config/mimetype/entry.rs
index 6a85b0e..bf65e59 100644
--- a/src/config/mimetype/entry.rs
+++ b/src/config/mimetype/entry.rs
@@ -1,4 +1,5 @@
use serde_derive::Deserialize;
+use std::env;
use std::fmt;
use std::io::Read;
use std::process;
@@ -106,6 +107,14 @@ impl AppMimetypeEntry {
self._confirm_exit
}
+ // TODO: Windows support
+ pub fn program_exists(&self) -> bool {
+ let program = self.get_command();
+ env::var_os("PATH")
+ .map(|path| env::split_paths(&path).any(|dir| dir.join(program).is_file()))
+ .unwrap_or(false)
+ }
+
pub fn execute_with<I, S>(&self, paths: I) -> std::io::Result<()>
where
I: IntoIterator<Item = S>,
diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs
index 1147651..719ca71 100644
--- a/src/fs/dirlist.rs
+++ b/src/fs/dirlist.rs
@@ -174,31 +174,15 @@ impl JoshutoDirList {
}
pub fn curr_entry_ref(&self) -> Option<&JoshutoDirEntry> {
- self.get_curr_ref_(self.index?)
+ self.contents.get(self.index?)
}
pub fn curr_entry_mut(&mut self) -> Option<&mut JoshutoDirEntry> {
- self.get_curr_mut_(self.index?)
+ self.contents.get_mut(self.index?)
}
/// Returns the index of the first entry to be printed in a UI dir list
pub fn first_index_for_viewport(&self) -> usize {
self.viewport_index
}
-
- fn get_curr_mut_(&mut self, index: usize) -> Option<&mut JoshutoDirEntry> {
- if index < self.contents.len() {
- Some(&mut self.contents[index])
- } else {
- None
- }
- }
-
- fn get_curr_ref_(&self, index: usize) -> Option<&JoshutoDirEntry> {
- if index < self.contents.len() {
- Some(&self.contents[index])
- } else {
- None
- }
- }
}