diff options
author | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2019-08-03 10:32:50 -0400 |
---|---|---|
committer | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2019-08-03 10:38:22 -0400 |
commit | 8105aa532c7fca7160ba3ce9303ba7613c59d277 (patch) | |
tree | 1cd680e77463bdce2b4b8381a0dcd1ec5b35e17e | |
parent | 0b8747eb37d6d943d90e15ed82858d99d1800425 (diff) |
Make xdg_open toggleable
- xdg_open option automatically opens file
rather than asking user what to do
- fix crash when trying to open something in an
empty directory
-rw-r--r-- | config/joshuto.toml | 1 | ||||
-rw-r--r-- | src/commands/change_directory.rs | 4 | ||||
-rw-r--r-- | src/commands/open_file.rs | 102 | ||||
-rw-r--r-- | src/config/config.rs | 5 | ||||
-rw-r--r-- | src/config/keymap.rs | 16 | ||||
-rw-r--r-- | src/config/mimetype.rs | 18 | ||||
-rw-r--r-- | src/history.rs | 3 | ||||
-rw-r--r-- | src/preview.rs | 21 |
8 files changed, 103 insertions, 67 deletions
diff --git a/config/joshuto.toml b/config/joshuto.toml index af5be15..de8c952 100644 --- a/config/joshuto.toml +++ b/config/joshuto.toml @@ -6,6 +6,7 @@ column_ratio = [1, 4, 4] scroll_offset = 6 show_preview = true +xdg_open = false max_preview_size = 2097152 # 2MB # lexical, mtime, natural diff --git a/src/commands/change_directory.rs b/src/commands/change_directory.rs index 3ec1946..d62964e 100644 --- a/src/commands/change_directory.rs +++ b/src/commands/change_directory.rs @@ -33,7 +33,9 @@ impl ChangeDirectory { std::mem::swap(&mut curr_tab.curr_list, &mut curr_list); - curr_tab.history.insert(curr_list.file_path().clone(), curr_list); + curr_tab + .history + .insert(curr_list.file_path().clone(), curr_list); curr_tab.curr_path = path.clone(); curr_tab diff --git a/src/commands/open_file.rs b/src/commands/open_file.rs index c5c1c90..419cefe 100644 --- a/src/commands/open_file.rs +++ b/src/commands/open_file.rs @@ -1,9 +1,9 @@ use std::path::{Path, PathBuf}; use crate::commands::{JoshutoCommand, JoshutoRunnable}; -use crate::config::mimetype; +use crate::config::mimetype::JoshutoMimetypeEntry; use crate::context::JoshutoContext; -use crate::error::JoshutoResult; +use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult}; use crate::history::DirectoryHistory; use crate::textfield::JoshutoTextField; use crate::ui; @@ -24,8 +24,8 @@ impl OpenFile { "open_file" } - pub fn get_options<'a>(path: &Path) -> Vec<&'a mimetype::JoshutoMimetypeEntry> { - let mut mimetype_options: Vec<&mimetype::JoshutoMimetypeEntry> = Vec::new(); + pub fn get_options<'a>(path: &Path) -> Vec<&'a JoshutoMimetypeEntry> { + let mut mimetype_options: Vec<&JoshutoMimetypeEntry> = Vec::new(); /* extensions have priority */ if let Some(file_ext) = path.extension() { @@ -67,7 +67,18 @@ impl OpenFile { let err = std::io::Error::new(std::io::ErrorKind::NotFound, "No files selected"); return Err(err); } - Self::open_file(&paths); + let mimetype_options = Self::get_options(&paths[0]); + if !mimetype_options.is_empty() { + mimetype_options[0].execute_with(&paths); + } else if context.config_t.xdg_open { + ncurses::savetty(); + ncurses::endwin(); + open::that(paths[0]).unwrap(); + ncurses::resetty(); + ncurses::refresh(); + } else { + OpenFileWith::open_with(&paths); + } let curr_tab = &mut context.tabs[context.curr_tab_index]; if curr_tab.curr_list.need_update() { curr_tab @@ -99,21 +110,6 @@ impl OpenFile { curr_tab.curr_path = path.to_path_buf().clone(); Ok(()) } - - fn open_file(paths: &[&PathBuf]) { - let mimetype_options = Self::get_options(&paths[0]); - - ncurses::savetty(); - ncurses::endwin(); - if mimetype_options.is_empty() { - open::that(&paths[0]).unwrap(); - } else { - mimetype_options[0].execute_with(paths); - } - ncurses::resetty(); - ncurses::refresh(); - ncurses::doupdate(); - } } impl JoshutoCommand for OpenFile {} @@ -142,11 +138,10 @@ impl OpenFileWith { "open_file_with" } - pub fn open_with(paths: &[&PathBuf]) { + pub fn open_with(paths: &[&PathBuf]) -> JoshutoResult<()> { const PROMPT: &str = ":open_with "; - let mimetype_options: Vec<&mimetype::JoshutoMimetypeEntry> = - OpenFile::get_options(&paths[0]); + let mimetype_options: Vec<&JoshutoMimetypeEntry> = OpenFile::get_options(&paths[0]); let user_input: Option<String>; { let (term_rows, term_cols) = ui::getmaxyx(); @@ -174,30 +169,42 @@ impl OpenFileWith { } ncurses::doupdate(); - if let Some(user_input) = user_input { - if user_input.is_empty() { - return; - } - match user_input.parse::<usize>() { - Ok(s) => { - if s < mimetype_options.len() { - ncurses::savetty(); - ncurses::endwin(); - mimetype_options[s].execute_with(paths); - ncurses::resetty(); - ncurses::refresh(); + match user_input.as_ref() { + None => Ok(()), + Some(user_input) if user_input.is_empty() => Ok(()), + Some(user_input) => match user_input.parse::<usize>() { + Ok(n) => { + if n < mimetype_options.len() { + mimetype_options[n].execute_with(paths); + Ok(()) + } else { + Err(JoshutoError::new( + JoshutoErrorKind::IOInvalidData, + "option does not exist".to_owned(), + )) } } Err(_) => { - let args: Vec<String> = - user_input.split_whitespace().map(String::from).collect(); - ncurses::savetty(); - ncurses::endwin(); - unix::open_with_args(paths, &args); - ncurses::resetty(); - ncurses::refresh(); + let mut args_iter = user_input.split_whitespace(); + match args_iter.next() { + Some(s) => { + let command = String::from(s); + let args = args_iter.map(String::from).collect(); + let entry = JoshutoMimetypeEntry { + id: 0, + command, + args, + fork: true, + silent: false, + confirm_exit: true, + }; + entry.execute_with(paths); + } + None => {} + } + Ok(()) } - } + }, } } } @@ -213,6 +220,15 @@ impl std::fmt::Display for OpenFileWith { impl JoshutoRunnable for OpenFileWith { fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) -> JoshutoResult<()> { let curr_list = &context.tabs[context.curr_tab_index].curr_list; + match curr_list.index { + None => { + return Err(JoshutoError::new( + JoshutoErrorKind::IONotFound, + String::from("No files selected"), + )) + } + Some(_) => {} + } let paths = curr_list.get_selected_paths(); Self::open_with(&paths); Ok(()) diff --git a/src/config/config.rs b/src/config/config.rs index f093d79..f4f962e 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -61,6 +61,8 @@ pub struct JoshutoRawConfig { tilde_in_titlebar: bool, #[serde(default = "default_true")] show_preview: bool, + #[serde(default)] + xdg_open: bool, #[serde(default = "default_max_preview_size")] max_preview_size: u64, column_ratio: Option<[usize; 3]>, @@ -89,6 +91,7 @@ impl Flattenable<JoshutoConfig> for JoshutoRawConfig { scroll_offset: self.scroll_offset, tilde_in_titlebar: self.tilde_in_titlebar, show_preview: self.show_preview, + xdg_open: self.xdg_open, max_preview_size: self.max_preview_size, column_ratio, sort_option, @@ -101,6 +104,7 @@ pub struct JoshutoConfig { pub scroll_offset: usize, pub tilde_in_titlebar: bool, pub show_preview: bool, + pub xdg_open: bool, pub max_preview_size: u64, pub sort_option: sort::SortOption, pub column_ratio: (usize, usize, usize), @@ -121,6 +125,7 @@ impl std::default::Default for JoshutoConfig { scroll_offset: default_scroll_offset(), tilde_in_titlebar: default_true(), show_preview: default_true(), + xdg_open: false, max_preview_size: default_max_preview_size(), sort_option, column_ratio: default_column_ratio(), diff --git a/src/config/keymap.rs b/src/config/keymap.rs index 6916d49..8735a00 100644 --- a/src/config/keymap.rs +++ b/src/config/keymap.rs @@ -55,6 +55,14 @@ const fn default_tab() -> i32 { } #[derive(Debug, Deserialize)] +struct JoshutoMapCommand { + pub command: String, + #[serde(default)] + pub args: Vec<String>, + pub keys: Vec<i32>, +} + +#[derive(Debug, Deserialize)] struct JoshutoRawKeymapping { #[serde(default)] keymaps: JoshutoKeyMapping, @@ -126,14 +134,6 @@ impl ConfigStructure for JoshutoKeyMapping { } #[derive(Debug, Deserialize)] -struct JoshutoMapCommand { - pub command: String, - #[serde(default)] - pub args: Vec<String>, - pub keys: Vec<i32>, -} - -#[derive(Debug, Deserialize)] struct JoshutoRawCommandMapping { #[serde(skip)] keymaps: JoshutoKeyMapping, diff --git a/src/config/mimetype.rs b/src/config/mimetype.rs index 2b20e3d..891a201 100644 --- a/src/config/mimetype.rs +++ b/src/config/mimetype.rs @@ -14,16 +14,16 @@ const fn default_false() -> bool { #[derive(Debug, Deserialize)] pub struct JoshutoMimetypeEntry { - id: usize, - command: String, + pub id: usize, + pub command: String, #[serde(default)] - args: Vec<String>, + pub args: Vec<String>, #[serde(default = "default_false")] - fork: bool, + pub fork: bool, #[serde(default = "default_false")] - silent: bool, + pub silent: bool, #[serde(default = "default_false")] - confirm_exit: bool, + pub confirm_exit: bool, } impl JoshutoMimetypeEntry { @@ -66,15 +66,19 @@ impl JoshutoMimetypeEntry { match command.spawn() { Ok(mut handle) => { if !self.get_fork() { + ncurses::savetty(); + ncurses::endwin(); match handle.wait() { Ok(_) => { if self.get_confirm_exit() { - println!(" --- Press any key to continue --- "); + println!(" --- Press ENTER to continue --- "); std::io::stdin().bytes().next(); } } Err(e) => eprintln!("{}", e), } + ncurses::resetty(); + ncurses::refresh(); } } Err(e) => eprintln!("{}", e), diff --git a/src/history.rs b/src/history.rs index 7333af7..e843d29 100644 --- a/src/history.rs +++ b/src/history.rs @@ -43,7 +43,8 @@ impl DirectoryHistory for JoshutoHistory { } } Entry::Vacant(entry) => { - let mut dirlist = JoshutoDirList::new(curr.to_path_buf().clone(), sort_option)?; + let mut dirlist = + JoshutoDirList::new(curr.to_path_buf().clone(), sort_option)?; if let Some(i) = get_index_of_value(&dirlist.contents, &ancestor) { dirlist.index = Some(i); } diff --git a/src/preview.rs b/src/preview.rs index 282ae43..0f97a22 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -47,15 +47,21 @@ fn preview_directory( path: &path::Path, win: &JoshutoPanel, config_t: &JoshutoConfig, -) { +) -> std::io::Result<()> { match history.entry(path.to_path_buf().clone()) { Entry::Occupied(mut entry) => { - ui::display_contents( - win, - entry.get_mut(), - config_t, - &ui::SECONDARY_DISPLAY_OPTION, - ); + let mut dirlist = entry.get_mut(); + if dirlist.need_update() { + dirlist.reload_contents(&config_t.sort_option)? + } else { + let metadata = std::fs::symlink_metadata(dirlist.file_path())?; + + let modified = metadata.modified()?; + if modified > dirlist.metadata.modified { + dirlist.reload_contents(&config_t.sort_option)? + } + } + ui::display_contents(win, dirlist, config_t, &ui::SECONDARY_DISPLAY_OPTION); } Entry::Vacant(entry) => { if let Ok(s) = JoshutoDirList::new(path.to_path_buf().clone(), &config_t.sort_option) { @@ -69,6 +75,7 @@ fn preview_directory( } } win.queue_for_refresh(); + Ok(()) } fn preview_file(entry: &JoshutoDirEntry, win: &JoshutoPanel) { |