diff options
author | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2020-08-30 15:20:03 -0400 |
---|---|---|
committer | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2020-08-30 15:20:03 -0400 |
commit | e7218c81d90ae07d7f56dce0c3032db15b11d118 (patch) | |
tree | 63c3b63345ec73031b26c1b900957ad06b69aec6 /src/commands | |
parent | a592bfe51c0cbb7744f14586520827cb06da8c8d (diff) |
rework and fix issues
- fixed bug where io tasks would not run when user is in a textfield or prompt
- fixed bug where cut doesn't work
- rework structs to have private fields and public functions
- move IOWorkerObserver into seperate file
- move code from TuiView to TuiFolderView
Diffstat (limited to 'src/commands')
-rw-r--r-- | src/commands/change_directory.rs | 2 | ||||
-rw-r--r-- | src/commands/command_line.rs | 2 | ||||
-rw-r--r-- | src/commands/cursor_move.rs | 4 | ||||
-rw-r--r-- | src/commands/delete_files.rs | 19 | ||||
-rw-r--r-- | src/commands/file_ops/copy.rs | 12 | ||||
-rw-r--r-- | src/commands/file_ops/cut.rs | 7 | ||||
-rw-r--r-- | src/commands/new_directory.rs | 2 | ||||
-rw-r--r-- | src/commands/open_file.rs | 179 | ||||
-rw-r--r-- | src/commands/shell.rs | 4 | ||||
-rw-r--r-- | src/commands/show_hidden.rs | 2 | ||||
-rw-r--r-- | src/commands/sort.rs | 4 | ||||
-rw-r--r-- | src/commands/tab_switch.rs | 2 |
12 files changed, 111 insertions, 128 deletions
diff --git a/src/commands/change_directory.rs b/src/commands/change_directory.rs index 022d306..7559c52 100644 --- a/src/commands/change_directory.rs +++ b/src/commands/change_directory.rs @@ -36,7 +36,7 @@ impl ChangeDirectory { context .tab_context_mut() .curr_tab_mut() - .history + .history_mut() .populate_to_root(&path, &sort_options)?; Ok(()) diff --git a/src/commands/command_line.rs b/src/commands/command_line.rs index e83ded3..52a5925 100644 --- a/src/commands/command_line.rs +++ b/src/commands/command_line.rs @@ -27,7 +27,7 @@ impl CommandLine { .prompt(":") .prefix(self.prefix.as_str()) .suffix(self.suffix.as_str()) - .get_input(backend, &context); + .get_input(backend, context); if let Some(s) = user_input { let trimmed = s.trim_start(); diff --git a/src/commands/cursor_move.rs b/src/commands/cursor_move.rs index 078d470..6a4ec19 100644 --- a/src/commands/cursor_move.rs +++ b/src/commands/cursor_move.rs @@ -30,7 +30,7 @@ pub fn cursor_move(new_index: usize, context: &mut JoshutoContext) -> JoshutoRes context .tab_context_mut() .curr_tab_mut() - .history + .history_mut() .create_or_soft_update(path.as_path(), &sort_options)?; } } @@ -154,7 +154,7 @@ impl JoshutoRunnable for CursorMovePageUp { }; if let Some(s) = movement { - cursor_move(s, context); + cursor_move(s, context)?; } Ok(()) } diff --git a/src/commands/delete_files.rs b/src/commands/delete_files.rs index 69069fe..25a13f8 100644 --- a/src/commands/delete_files.rs +++ b/src/commands/delete_files.rs @@ -22,7 +22,10 @@ impl DeleteFiles { "delete_files" } - pub fn remove_files(paths: &[&path::Path]) -> std::io::Result<()> { + pub fn remove_files<'a, I>(paths: I) -> std::io::Result<()> + where + I: Iterator<Item = &'a path::Path>, + { for path in paths { if let Ok(metadata) = fs::symlink_metadata(path) { if metadata.is_dir() { @@ -53,7 +56,7 @@ impl DeleteFiles { let ch = { let prompt_str = format!("Delete {} files? (Y/n)", paths_len); let mut prompt = TuiPrompt::new(&prompt_str); - prompt.get_key(backend, &context) + prompt.get_key(backend, context) }; if ch == Key::Char('y') || ch == Key::Char('\n') { @@ -61,19 +64,19 @@ impl DeleteFiles { let ch = { let prompt_str = "Are you sure? (y/N)"; let mut prompt = TuiPrompt::new(prompt_str); - prompt.get_key(backend, &context) + prompt.get_key(backend, context) }; if ch == Key::Char('y') { - Self::remove_files(&paths)?; + Self::remove_files(paths.iter().map(|p| p.as_path()))?; ReloadDirList::reload(tab_index, context)?; let msg = format!("Deleted {} files", paths_len); - context.message_queue.push_back(msg); + context.push_msg(msg); } } else { - Self::remove_files(&paths)?; + Self::remove_files(paths.iter().map(|p| p.as_path()))?; ReloadDirList::reload(tab_index, context)?; let msg = format!("Deleted {} files", paths_len); - context.message_queue.push_back(msg); + context.push_msg(msg); } } Ok(()) @@ -95,7 +98,7 @@ impl JoshutoRunnable for DeleteFiles { let options = context.config_t.sort_option.clone(); let curr_path = context.tab_context_ref().curr_tab_ref().pwd().to_path_buf(); for tab in context.tab_context_mut().iter_mut() { - tab.history.reload(&curr_path, &options)?; + tab.history_mut().reload(&curr_path, &options)?; } LoadChild::load_child(context)?; Ok(()) diff --git a/src/commands/file_ops/copy.rs b/src/commands/file_ops/copy.rs index 6632e2a..138aac3 100644 --- a/src/commands/file_ops/copy.rs +++ b/src/commands/file_ops/copy.rs @@ -29,17 +29,7 @@ impl std::fmt::Display for CopyFiles { impl JoshutoRunnable for CopyFiles { fn execute(&self, context: &mut JoshutoContext, _: &mut TuiBackend) -> JoshutoResult<()> { if let Some(list) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { - let mut selected: Vec<&path::Path> = list - .iter() - .filter(|e| e.is_selected()) - .map(|e| e.file_path()) - .collect(); - if selected.is_empty() { - selected = match list.get_curr_ref() { - Some(s) => vec![s.file_path()], - None => vec![], - } - } + let selected = list.get_selected_paths(); let mut local_state = LocalStateContext::new(); local_state.set_paths(selected.into_iter()); diff --git a/src/commands/file_ops/cut.rs b/src/commands/file_ops/cut.rs index 0fcbc0e..244da2f 100644 --- a/src/commands/file_ops/cut.rs +++ b/src/commands/file_ops/cut.rs @@ -27,13 +27,10 @@ impl std::fmt::Display for CutFiles { impl JoshutoRunnable for CutFiles { fn execute(&self, context: &mut JoshutoContext, _: &mut TuiBackend) -> JoshutoResult<()> { if let Some(list) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { - let iter = list - .iter() - .filter(|e| e.is_selected()) - .map(|e| e.file_path()); + let selected = list.get_selected_paths(); let mut local_state = LocalStateContext::new(); - local_state.set_paths(iter); + local_state.set_paths(selected.into_iter()); local_state.set_file_op(FileOp::Cut); context.set_local_state(local_state); diff --git a/src/commands/new_directory.rs b/src/commands/new_directory.rs index 401e2a2..b2372ae 100644 --- a/src/commands/new_directory.rs +++ b/src/commands/new_directory.rs @@ -36,7 +36,7 @@ impl JoshutoRunnable for NewDirectory { let options = context.config_t.sort_option.clone(); let curr_path = context.tab_context_ref().curr_tab_ref().pwd().to_path_buf(); for tab in context.tab_context_mut().iter_mut() { - tab.history.reload(&curr_path, &options)?; + tab.history_mut().reload(&curr_path, &options)?; } LoadChild::load_child(context)?; diff --git a/src/commands/open_file.rs b/src/commands/open_file.rs index 94e14dd..ce66aa5 100644 --- a/src/commands/open_file.rs +++ b/src/commands/open_file.rs @@ -1,3 +1,5 @@ +use std::path; + use crate::commands::{ChangeDirectory, JoshutoCommand, JoshutoRunnable}; use crate::config::mimetype::JoshutoMimetypeEntry; use crate::context::JoshutoContext; @@ -20,71 +22,36 @@ impl OpenFile { "open_file" } - 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) = entry.file_path().extension() { + pub fn get_options<'a>(path: &path::Path) -> Vec<&'a JoshutoMimetypeEntry> { + let mut options: Vec<&JoshutoMimetypeEntry> = Vec::new(); + if let Some(file_ext) = 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); + options.extend(ext_entries); } } - mimetype_options + options } - - fn open(context: &mut JoshutoContext, backend: &mut TuiBackend) -> std::io::Result<()> { - let mut dirpath = None; - let mut selected_entries = None; - - match context.tab_context_ref().curr_tab_ref().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().to_path_buf(); - dirpath = Some(path); + /* + pub fn get_options<'a>(entry: &JoshutoDirEntry) -> Vec<&'a JoshutoMimetypeEntry> { + let mut mimetype_options: Vec<&JoshutoMimetypeEntry> = Vec::new(); + + 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); } - 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); - } + } + #[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); } - None => return Ok(()), - }, - } - - if let Some(path) = dirpath { - ChangeDirectory::cd(path.as_path(), context)?; - LoadChild::load_child(context)?; - } else if let Some(entries) = selected_entries { - let options = Self::get_options(entries[0]); - let entry_paths: Vec<&str> = entries.iter().map(|e| e.file_name()).collect(); - if !options.is_empty() { - let res = if options[0].get_fork() { - options[0].execute_with(entry_paths.as_slice()) - } else { - backend.terminal_drop(); - let res = options[0].execute_with(entry_paths.as_slice()); - backend.terminal_restore()?; - res - }; - return res; - } else { - OpenFileWith::open_with(context, backend, &entries)?; } + mimetype_options } - Ok(()) - } + */ } impl JoshutoCommand for OpenFile {} @@ -97,7 +64,46 @@ impl std::fmt::Display for OpenFile { impl JoshutoRunnable for OpenFile { fn execute(&self, context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> { - Self::open(context, backend)?; + if let Some(entry) = context + .tab_context_ref() + .curr_tab_ref() + .curr_list_ref() + .and_then(|s| s.get_curr_ref()) + { + if entry.file_path().is_dir() { + let path = entry.file_path().to_path_buf(); + ChangeDirectory::cd(path.as_path(), context)?; + LoadChild::load_child(context)?; + } else { + let paths: Vec<path::PathBuf> = + match context.tab_context_ref().curr_tab_ref().curr_list_ref() { + Some(a) => a.get_selected_paths(), + None => vec![], + }; + if paths.is_empty() { + return Err(JoshutoError::new( + JoshutoErrorKind::IONotFound, + String::from("No files selected"), + )); + } + let files: Vec<&std::ffi::OsStr> = + paths.iter().filter_map(|e| e.file_name()).collect(); + let options = Self::get_options(paths[0].as_path()); + + if !options.is_empty() { + if options[0].get_fork() { + options[0].execute_with(files.as_slice()) + } else { + backend.terminal_drop(); + let res = options[0].execute_with(files.as_slice()); + backend.terminal_restore()?; + res + }; + } else { + OpenFileWith::open_with(context, backend, options, files)?; + } + } + } Ok(()) } } @@ -113,48 +119,46 @@ impl OpenFileWith { "open_file_with" } - pub fn open_with( - context: &JoshutoContext, + pub fn open_with<S>( + context: &mut JoshutoContext, backend: &mut TuiBackend, - entries: &[&JoshutoDirEntry], - ) -> std::io::Result<()> { + options: Vec<&JoshutoMimetypeEntry>, + files: Vec<S>, + ) -> std::io::Result<()> + where + S: AsRef<std::ffi::OsStr>, + { const PROMPT: &str = "open_with "; - let mimetype_options: Vec<&JoshutoMimetypeEntry> = OpenFile::get_options(&entries[0]); - let user_input: Option<String> = { - let menu_options: Vec<String> = mimetype_options + let menu_options: Vec<String> = options .iter() .enumerate() .map(|(i, e)| format!(" {} | {}", i, e)) .collect(); - let menu_options_str: Vec<&str> = menu_options.iter().map(|e| e.as_str()).collect(); - let menu_widget = TuiMenu::new(&menu_options_str); TuiTextField::default() .prompt(":") .prefix(PROMPT) - .menu(menu_widget) - .get_input(backend, &context) + .menu_items(menu_options.iter().map(|s| s.as_str())) + .get_input(backend, context) }; - let entry_paths: Vec<&str> = entries.iter().map(|e| e.file_name()).collect(); - match user_input.as_ref() { Some(user_input) if user_input.starts_with(PROMPT) => { let user_input = &user_input[PROMPT.len()..]; match user_input.parse::<usize>() { - Ok(n) if n >= mimetype_options.len() => Err(std::io::Error::new( + Ok(n) if n >= options.len() => Err(std::io::Error::new( std::io::ErrorKind::InvalidData, "option does not exist".to_string(), )), Ok(n) => { - let mimetype_entry = &mimetype_options[n]; + let mimetype_entry = &options[n]; if mimetype_entry.get_fork() { - mimetype_entry.execute_with(entry_paths.as_slice()) + mimetype_entry.execute_with(files.as_slice()) } else { backend.terminal_drop(); - let res = mimetype_entry.execute_with(entry_paths.as_slice()); + let res = mimetype_entry.execute_with(files.as_slice()); backend.terminal_restore()?; res } @@ -166,7 +170,7 @@ impl OpenFileWith { backend.terminal_drop(); let res = JoshutoMimetypeEntry::new(String::from(cmd)) .args(args_iter) - .execute_with(entry_paths.as_slice()); + .execute_with(files.as_slice()); backend.terminal_restore()?; res } @@ -190,30 +194,21 @@ impl std::fmt::Display for OpenFileWith { impl JoshutoRunnable for OpenFileWith { fn execute(&self, context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> { - let selected_entries = { + let paths: Vec<path::PathBuf> = match context.tab_context_ref().curr_tab_ref().curr_list_ref() { + Some(a) => a.get_selected_paths(), 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 selected_entries.is_empty() { + }; + if paths.is_empty() { return Err(JoshutoError::new( JoshutoErrorKind::IONotFound, String::from("No files selected"), )); } - Self::open_with(context, backend, &selected_entries)?; + let files: Vec<&std::ffi::OsStr> = paths.iter().filter_map(|e| e.file_name()).collect(); + let options = OpenFile::get_options(paths[0].as_path()); + + Self::open_with(context, backend, options, files)?; Ok(()) } } diff --git a/src/commands/shell.rs b/src/commands/shell.rs index 5a0c31d..69406b9 100644 --- a/src/commands/shell.rs +++ b/src/commands/shell.rs @@ -61,9 +61,7 @@ impl JoshutoRunnable for ShellCommand { backend.terminal_drop(); let res = self.shell_command(context); ReloadDirList::soft_reload(context.tab_context_ref().get_index(), context)?; - context - .message_queue - .push_back(format!("Finished: {}", self.words.join(" "))); + context.push_msg(format!("Finished: {}", self.words.join(" "))); backend.terminal_restore()?; res?; Ok(()) diff --git a/src/commands/show_hidden.rs b/src/commands/show_hidden.rs index 4ee105b..e4cfcb6 100644 --- a/src/commands/show_hidden.rs +++ b/src/commands/show_hidden.rs @@ -19,7 +19,7 @@ impl ToggleHiddenFiles { context.config_t.sort_option.show_hidden = opposite; for tab in context.tab_context_mut().iter_mut() { - tab.history.depreciate_all_entries(); + tab.history_mut().depreciate_all_entries(); if let Some(s) = tab.curr_list_mut() { s.depreciate(); } diff --git a/src/commands/sort.rs b/src/commands/sort.rs index e2dbe16..c264c4b 100644 --- a/src/commands/sort.rs +++ b/src/commands/sort.rs @@ -33,7 +33,7 @@ impl JoshutoRunnable for Sort { fn execute(&self, context: &mut JoshutoContext, _: &mut TuiBackend) -> JoshutoResult<()> { context.config_t.sort_option.sort_method = self.sort_method; for tab in context.tab_context_mut().iter_mut() { - tab.history.depreciate_all_entries(); + tab.history_mut().depreciate_all_entries(); } ReloadDirList::soft_reload(context.tab_context_ref().get_index(), context)?; LoadChild::load_child(context)?; @@ -65,7 +65,7 @@ impl JoshutoRunnable for SortReverse { fn execute(&self, context: &mut JoshutoContext, _: &mut TuiBackend) -> JoshutoResult<()> { context.config_t.sort_option.reverse = !context.config_t.sort_option.reverse; for tab in context.tab_context_mut().iter_mut() { - tab.history.depreciate_all_entries(); + tab.history_mut().depreciate_all_entries(); } ReloadDirList::soft_reload(context.tab_context_ref().get_index(), context)?; LoadChild::load_child(context)?; diff --git a/src/commands/tab_switch.rs b/src/commands/tab_switch.rs index ed2548c..f277110 100644 --- a/src/commands/tab_switch.rs +++ b/src/commands/tab_switch.rs @@ -28,7 +28,7 @@ impl TabSwitch { context .tab_context_mut() .curr_tab_mut() - .history + .history_mut() .create_or_soft_update(path.as_path(), &options); Ok(()) } |