diff options
author | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2019-04-14 17:57:50 -0400 |
---|---|---|
committer | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2019-04-14 17:57:50 -0400 |
commit | 71e0c7faf3cc283b2b24e70631e5b18a7a7525cd (patch) | |
tree | b27794c91a930ae2a1bc5cdc6a468b9b4d553134 | |
parent | 5a820a7a275bf5cacd2c545c0a0ac533789ec349 (diff) |
rework error handling system
rather than letting each command separately handle errors, we return a
Result<(), JoshutoError> instead and allow for run.rs to handle all errors
-rw-r--r-- | src/commands/change_directory.rs | 28 | ||||
-rw-r--r-- | src/commands/cursor_move.rs | 45 | ||||
-rw-r--r-- | src/commands/delete_files.rs | 12 | ||||
-rw-r--r-- | src/commands/file_operations.rs | 330 | ||||
-rw-r--r-- | src/commands/mod.rs | 4 | ||||
-rw-r--r-- | src/commands/new_directory.rs | 25 | ||||
-rw-r--r-- | src/commands/open_file.rs | 20 | ||||
-rw-r--r-- | src/commands/parent_directory.rs | 21 | ||||
-rw-r--r-- | src/commands/paste_files.rs | 222 | ||||
-rw-r--r-- | src/commands/quit.rs | 24 | ||||
-rw-r--r-- | src/commands/reload_dir.rs | 8 | ||||
-rw-r--r-- | src/commands/rename_file.rs | 32 | ||||
-rw-r--r-- | src/commands/search.rs | 29 | ||||
-rw-r--r-- | src/commands/selection.rs | 13 | ||||
-rw-r--r-- | src/commands/set_mode.rs | 8 | ||||
-rw-r--r-- | src/commands/show_hidden.rs | 8 | ||||
-rw-r--r-- | src/commands/tab_operations.rs | 42 | ||||
-rw-r--r-- | src/commands/tab_switch.rs | 20 | ||||
-rw-r--r-- | src/error.rs | 3 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/run.rs | 109 |
21 files changed, 652 insertions, 352 deletions
diff --git a/src/commands/change_directory.rs b/src/commands/change_directory.rs index 8406940..0e7fd1f 100644 --- a/src/commands/change_directory.rs +++ b/src/commands/change_directory.rs @@ -1,10 +1,13 @@ use std::path; -use crate::commands::{JoshutoCommand, JoshutoRunnable}; +use crate::commands; + use crate::context::JoshutoContext; +use crate::error::JoshutoError; use crate::preview; use crate::ui; use crate::window::JoshutoView; +use commands::{JoshutoCommand, JoshutoRunnable}; #[derive(Clone, Debug)] pub struct ChangeDirectory { @@ -23,20 +26,13 @@ impl ChangeDirectory { path: &path::PathBuf, context: &mut JoshutoContext, view: &JoshutoView, - ) { - if !path.exists() { - ui::wprint_err(&view.bot_win, "Error: No such file or directory"); - return; - } + ) -> Result<(), JoshutoError> { let curr_tab = &mut context.tabs[context.curr_tab_index]; match std::env::set_current_dir(path.as_path()) { - Ok(_) => { - curr_tab.curr_path = path.clone(); - } + Ok(_) => curr_tab.curr_path = path.clone(), Err(e) => { - ui::wprint_err(&view.bot_win, e.to_string().as_str()); - return; + return Err(JoshutoError::IO(e)); } } @@ -79,6 +75,7 @@ impl ChangeDirectory { &context.username, &context.hostname, ); + Ok(()) } } @@ -91,13 +88,18 @@ impl std::fmt::Display for ChangeDirectory { } impl JoshutoRunnable for ChangeDirectory { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { - Self::change_directory(&self.path, context, view); + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { + let res = Self::change_directory(&self.path, context, view); preview::preview_file( &mut context.tabs[context.curr_tab_index], &view, &context.config_t, ); ncurses::doupdate(); + res } } diff --git a/src/commands/cursor_move.rs b/src/commands/cursor_move.rs index 57e629d..f9be9fb 100644 --- a/src/commands/cursor_move.rs +++ b/src/commands/cursor_move.rs @@ -1,5 +1,6 @@ use crate::commands::{JoshutoCommand, JoshutoRunnable}; use crate::context::JoshutoContext; +use crate::error::JoshutoError; use crate::preview; use crate::window::JoshutoView; @@ -60,7 +61,11 @@ impl std::fmt::Display for CursorMoveInc { } impl JoshutoRunnable for CursorMoveInc { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { let mut movement: Option<usize> = None; { let curr_tab = context.curr_tab_mut(); @@ -69,8 +74,9 @@ impl JoshutoRunnable for CursorMoveInc { } } if let Some(s) = movement { - CursorMove::cursor_move(s, context, view); + CursorMove::cursor_move(s, context, view) } + Ok(()) } } @@ -97,7 +103,11 @@ impl std::fmt::Display for CursorMoveDec { } impl JoshutoRunnable for CursorMoveDec { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { let mut movement: Option<usize> = None; { let curr_tab = context.curr_tab_mut(); @@ -114,6 +124,7 @@ impl JoshutoRunnable for CursorMoveDec { if let Some(s) = movement { CursorMove::cursor_move(s, context, view); } + Ok(()) } } @@ -138,7 +149,11 @@ impl std::fmt::Display for CursorMovePageUp { } impl JoshutoRunnable for CursorMovePageUp { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { let movement: Option<usize> = { let curr_tab = context.curr_tab_mut(); if let Some(curr_list) = curr_tab.curr_list.as_ref() { @@ -154,6 +169,7 @@ impl JoshutoRunnable for CursorMovePageUp { if let Some(s) = movement { CursorMove::cursor_move(s, context, view); } + Ok(()) } } @@ -178,7 +194,11 @@ impl std::fmt::Display for CursorMovePageDown { } impl JoshutoRunnable for CursorMovePageDown { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { let movement: Option<usize> = { let curr_tab = &mut context.tabs[context.curr_tab_index]; if let Some(curr_list) = curr_tab.curr_list.as_ref() { @@ -199,6 +219,7 @@ impl JoshutoRunnable for CursorMovePageDown { if let Some(s) = movement { CursorMove::cursor_move(s, context, view); } + Ok(()) } } @@ -223,7 +244,11 @@ impl std::fmt::Display for CursorMoveHome { } impl JoshutoRunnable for CursorMoveHome { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { let movement: Option<usize> = { let curr_tab = context.curr_tab_mut(); if let Some(curr_list) = curr_tab.curr_list.as_ref() { @@ -240,6 +265,7 @@ impl JoshutoRunnable for CursorMoveHome { if let Some(s) = movement { CursorMove::cursor_move(s, context, view); } + Ok(()) } } @@ -264,7 +290,11 @@ impl std::fmt::Display for CursorMoveEnd { } impl JoshutoRunnable for CursorMoveEnd { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { let movement: Option<usize> = { let curr_tab = context.curr_tab_mut(); if let Some(curr_list) = curr_tab.curr_list.as_ref() { @@ -278,5 +308,6 @@ impl JoshutoRunnable for CursorMoveEnd { if let Some(s) = movement { CursorMove::cursor_move(s, context, view); } + Ok(()) } } diff --git a/src/commands/delete_files.rs b/src/commands/delete_files.rs index f450e57..8f6cacb 100644 --- a/src/commands/delete_files.rs +++ b/src/commands/delete_files.rs @@ -4,6 +4,7 @@ use std::path; use crate::commands::{self, JoshutoCommand, JoshutoRunnable}; use crate::config::keymap; use crate::context::JoshutoContext; +use crate::error::JoshutoError; use crate::preview; use crate::ui; use crate::window::JoshutoView; @@ -42,7 +43,11 @@ impl std::fmt::Display for DeleteFiles { } impl JoshutoRunnable for DeleteFiles { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { ui::wprint_msg(&view.bot_win, "Delete selected files? (Y/n)"); ncurses::timeout(-1); ncurses::doupdate(); @@ -54,9 +59,7 @@ impl JoshutoRunnable for DeleteFiles { match Self::remove_files(paths) { Ok(_) => ui::wprint_msg(&view.bot_win, "Deleted files"), Err(e) => { - ui::wprint_err(&view.bot_win, e.to_string().as_str()); - ncurses::doupdate(); - return; + return Err(JoshutoError::IO(e)); } } } @@ -83,5 +86,6 @@ impl JoshutoRunnable for DeleteFiles { let curr_tab = &mut context.tabs[context.curr_tab_index]; preview::preview_file(curr_tab, &view, &context.config_t); ncurses::doupdate(); + Ok(()) } } diff --git a/src/commands/file_operations.rs b/src/commands/file_operations.rs index da602e2..1e986e0 100644 --- a/src/commands/file_operations.rs +++ b/src/commands/file_operations.rs @@ -6,19 +6,31 @@ use std::time; use crate::commands::{self, JoshutoCommand, JoshutoRunnable, ProgressInfo}; use crate::context::JoshutoContext; +use crate::error::JoshutoError; use crate::structs::JoshutoDirList; use crate::window::JoshutoView; lazy_static! { - static ref SELECTED_FILES: Mutex<Vec<path::PathBuf>> = Mutex::new(vec![]); + static ref SELECTED_FILES: Mutex<Option<Vec<path::PathBuf>>> = Mutex::new(None); static ref FILE_OPERATION: Mutex<FileOp> = Mutex::new(FileOp::Copy); static ref TAB_SRC: atomic::AtomicUsize = atomic::AtomicUsize::new(0); } +enum FileOp { + Cut, + Copy, +} + +#[derive(Clone, Debug)] +pub struct CopyOptions { + pub overwrite: bool, + pub skip_exist: bool, +} + pub struct FileOperationThread { pub tab_src: usize, pub tab_dest: usize, - pub handle: thread::JoinHandle<i32>, + pub handle: thread::JoinHandle<Result<(), std::io::Error>>, pub recv: mpsc::Receiver<ProgressInfo>, } @@ -41,23 +53,14 @@ fn set_tab_src(tab_index: usize) { } fn repopulated_selected_files(dirlist: &JoshutoDirList) -> bool { - if let Some(contents) = commands::collect_selected_paths(dirlist) { - let mut data = SELECTED_FILES.lock().unwrap(); - *data = contents; - return true; + match commands::collect_selected_paths(dirlist) { + Some(s) => { + let mut data = SELECTED_FILES.lock().unwrap(); + *data = Some(s); + true + } + None => false, } - false -} - -enum FileOp { - Cut, - Copy, -} - -#[derive(Clone, Debug)] -pub struct CopyOptions { - pub overwrite: bool, - pub skip_exist: bool, } #[derive(Clone, Debug)] @@ -81,7 +84,7 @@ impl std::fmt::Display for CutFiles { } impl JoshutoRunnable for CutFiles { - fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) { + fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) -> Result<(), JoshutoError> { let curr_tab = context.curr_tab_ref(); if let Some(s) = curr_tab.curr_list.as_ref() { if repopulated_selected_files(s) { @@ -89,6 +92,7 @@ impl JoshutoRunnable for CutFiles { set_tab_src(context.curr_tab_index); } } + Ok(()) } } @@ -113,7 +117,7 @@ impl std::fmt::Display for CopyFiles { } impl JoshutoRunnable for CopyFiles { - fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) { + fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) -> Result<(), JoshutoError> { let curr_tab = context.curr_tab_ref(); if let Some(s) = curr_tab.curr_list.as_ref() { if repopulated_selected_files(s) { @@ -121,6 +125,7 @@ impl JoshutoRunnable for CopyFiles { set_tab_src(context.curr_tab_index); } } + Ok(()) } } @@ -128,6 +133,43 @@ pub struct PasteFiles { options: fs_extra::dir::CopyOptions, } +impl JoshutoCommand for PasteFiles {} + +impl std::fmt::Display for PasteFiles { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "{} overwrite={} skip_exist={}", + Self::command(), + self.options.overwrite, + self.options.skip_exist, + ) + } +} + +impl std::fmt::Debug for PasteFiles { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.write_str(Self::command()) + } +} + +impl JoshutoRunnable for PasteFiles { + fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) -> Result<(), JoshutoError> { + let file_operation = FILE_OPERATION.lock().unwrap(); + + let thread = match *file_operation { + FileOp::Copy => self.copy_paste(context), + FileOp::Cut => self.cut_paste(context), + }; + + if let Ok(s) = thread { + ncurses::timeout(-1); + context.threads.push(s); + } + Ok(()) + } +} + impl PasteFiles { pub fn new(options: fs_extra::dir::CopyOptions) -> Self { PasteFiles { options } @@ -136,86 +178,58 @@ impl PasteFiles { "paste_files" } - #[cfg(target_os = "linux")] - fn cut(&self, context: &mut JoshutoContext) -> Result<FileOperationThread, std::io::Error> { - use std::os::linux::fs::MetadataExt; + fn same_fs_cut( + &self, + context: &mut JoshutoContext, + ) -> Result<FileOperationThread, std::io::Error> { + let options = self.options.clone(); - let tab_dest = context.curr_tab_index; - let tab_src_index = TAB_SRC.load(atomic::Ordering::SeqCst); + let (tx, rx) = mpsc::channel(); - let options = self.options.clone(); + let tab_dest = context.curr_tab_index; + let tab_src = TAB_SRC.load(atomic::Ordering::SeqCst); let mut destination = context.tabs[tab_dest].curr_path.clone(); - let dest_ino = destination.metadata()?.st_dev(); - let path_ino; - { - let paths = SELECTED_FILES.lock().unwrap(); - if paths.len() == 0 { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "no files selected", - )); - } - path_ino = paths[0].metadata()?.st_dev(); - } + let handle = thread::spawn(move || { + let paths: Option<Vec<path::PathBuf>> = SELECTED_FILES.lock().unwrap().take(); + match paths { + None => {} + Some(s) => { + let mut progress_info = ProgressInfo { + bytes_finished: 1, + total_bytes: s.len() as u64 + 1, + }; - let (tx, rx) = mpsc::channel(); - let handle = if dest_ino == path_ino { - thread::spawn(move || { - let mut paths = SELECTED_FILES.lock().unwrap(); - let mut progress_info = ProgressInfo { - bytes_finished: 1, - total_bytes: paths.len() as u64 + 1, - }; - - for path in (*paths).iter() { - let file_name = path.file_name().unwrap().to_os_string(); - - destination.push(file_name.clone()); - - if destination.exists() { - if !options.skip_exist { - for i in 0.. { - if !destination.exists() { - break; + for path in &s { + let file_name = path.file_name().unwrap().to_os_string(); + + destination.push(file_name.clone()); + if destination.exists() { + if !options.skip_exist { + for i in 0.. { + if !destination.exists() { + break; + } + destination.pop(); + let mut file_name = file_name.clone(); + file_name.push(&format!("_{}", i)); + destination.push(file_name); } - destination.pop(); - let mut file_name = file_name.clone(); - file_name.push(&format!("_{}", i)); - destination.push(file_name); } - std::fs::rename(&path, &destination); } - } else { - std::fs::rename(&path, &destination); + std::fs::rename(&path, &destination)?; + destination.pop(); + + progress_info.bytes_finished += 1; + tx.send(progress_info.clone()).unwrap(); } - destination.pop(); - progress_info.bytes_finished += 1; - tx.send(progress_info.clone()).unwrap(); } - paths.clear(); - 0 - }) - } else { - thread::spawn(move || { - let mut paths = SELECTED_FILES.lock().unwrap(); + } + return Ok(()); + }); - let handle = |process_info: fs_extra::TransitProcess| { - let progress_info = ProgressInfo { - bytes_finished: process_info.copied_bytes, - total_bytes: process_info.total_bytes, - }; - tx.send(progress_info).unwrap(); - fs_extra::dir::TransitProcessResult::ContinueOrAbort - }; - - fs_extra::move_items_with_progress(&paths, &destination, &options, handle).unwrap(); - paths.clear(); - 0 - }) - }; let thread = FileOperationThread { - tab_src: tab_src_index, + tab_src, tab_dest, handle, recv: rx, @@ -223,75 +237,77 @@ impl PasteFiles { Ok(thread) } - #[cfg(not(target_os = "linux"))] - fn cut(&self, context: &mut JoshutoContext) -> Result<FileOperationThread, std::io::Error> { - let tab_dest = context.curr_tab_index; - let tab_src_index = TAB_SRC.load(atomic::Ordering::SeqCst); - - let mut destination = context.tabs[tab_dest].curr_path.clone(); - let options = self.options.clone(); + #[cfg(target_os = "linux")] + fn cut_paste( + &self, + context: &mut JoshutoContext, + ) -> Result<FileOperationThread, std::io::Error> { + use std::os::linux::fs::MetadataExt; + let src_ino; { let paths = SELECTED_FILES.lock().unwrap(); - if paths.len() == 0 { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "no files selected", - )); + match *paths { + Some(ref s) => { + if s.len() == 0 { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "no files selected", + )); + } + src_ino = s[0].metadata()?.st_dev(); + } + None => { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "no files selected", + )); + } } } - let (tx, rx) = mpsc::channel(); - let handle = thread::spawn(move || { - let mut paths = SELECTED_FILES.lock().unwrap(); - - let handle = |process_info: fs_extra::TransitProcess| { - let progress_info = ProgressInfo { - bytes_finished: process_info.copied_bytes, - total_bytes: process_info.total_bytes, - }; - tx.send(progress_info).unwrap(); - fs_extra::dir::TransitProcessResult::ContinueOrAbort - }; - - fs_extra::move_items_with_progress(&paths, &destination, &options, handle).unwrap(); - paths.clear(); - 0 - }); - let thread = FileOperationThread { - tab_src: tab_src_index, - tab_dest, - handle, - recv: rx, - }; - Ok(thread) + let tab_dest = context.curr_tab_index; + let destination = &context.tabs[tab_dest].curr_path; + + let dest_ino = destination.metadata()?.st_dev(); + if dest_ino == src_ino { + self.same_fs_cut(context) + } else { + self.same_fs_cut(context) + } } - fn copy(&self, context: &mut JoshutoContext) -> Result<FileOperationThread, std::io::Error> { + fn copy_paste( + &self, + context: &mut JoshutoContext, + ) -> Result<FileOperationThread, std::io::Error> { let tab_dest = context.curr_tab_index; - let tab_src_index = TAB_SRC.load(atomic::Ordering::SeqCst); - let destination = context.tabs[tab_dest].curr_path.clone(); + + let tab_src = TAB_SRC.load(atomic::Ordering::SeqCst); let options = self.options.clone(); let (tx, rx) = mpsc::channel(); let handle = thread::spawn(move || { let paths = SELECTED_FILES.lock().unwrap(); - - let handle = |process_info: fs_extra::TransitProcess| { - let progress_info = ProgressInfo { - bytes_finished: process_info.copied_bytes, - total_bytes: process_info.total_bytes, - }; - tx.send(progress_info).unwrap(); - fs_extra::dir::TransitProcessResult::ContinueOrAbort - }; - fs_extra::copy_items_with_progress(&paths, &destination, &options, handle); - 0 + match *paths { + Some(ref s) => { + let progress_info = ProgressInfo { + bytes_finished: 0, + total_bytes: 0, + }; + match tx.send(progress_info) { + Ok(_) => {} + Err(e) => {} + } + return Ok(()); + } + None => return Ok(()), + } }); let thread = FileOperationThread { - tab_src: tab_src_index, + tab_src, tab_dest, handle, recv: rx, @@ -299,39 +315,3 @@ impl PasteFiles { Ok(thread) } } - -impl JoshutoCommand for PasteFiles {} - -impl std::fmt::Display for PasteFiles { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "{} overwrite={} skip_exist={}", - Self::command(), - self.options.overwrite, - self.options.skip_exist, - ) - } -} - -impl std::fmt::Debug for PasteFiles { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.write_str(Self::command()) - } -} - -impl JoshutoRunnable for PasteFiles { - fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) { - let file_operation = FILE_OPERATION.lock().unwrap(); - - let thread = match *file_operation { - FileOp::Copy => self.copy(context), - FileOp::Cut => self.cut(context), - }; - - if let Ok(s) = thread { - ncurses::timeout(-1); - context.threads.push(s); - } - } -} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 7cfa311..57694c5 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -41,6 +41,7 @@ use std::fmt; use std::path::PathBuf; use crate::context::JoshutoContext; +use crate::error::JoshutoError; use crate::structs; use crate::window::JoshutoView; @@ -51,7 +52,8 @@ pub enum CommandKeybind { } pub trait JoshutoRunnable { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView); + fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) + -> Result<(), JoshutoError>; } pub trait JoshutoCommand: JoshutoRunnable + std::fmt::Display + std::fmt::Debug {} diff --git a/src/commands/new_directory.rs b/src/commands/new_directory.rs index 243cf6a..b3d1c2d 100644 --- a/src/commands/new_directory.rs +++ b/src/commands/new_directory.rs @@ -2,6 +2,7 @@ use std::path; use crate::commands::{JoshutoCommand, JoshutoRunnable, ReloadDirList}; use crate::context::JoshutoContext; +use crate::error::JoshutoError; use crate::textfield::JoshutoTextField; use crate::ui; use crate::window::JoshutoView; @@ -27,35 +28,33 @@ impl std::fmt::Display for NewDirectory { } impl JoshutoRunnable for NewDirectory { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { let (term_rows, term_cols) = ui::getmaxyx(); const PROMPT: &str = ":mkdir "; - let user_input: Option<String>; - - { + let user_input: Option<String> = { let textfield = JoshutoTextField::new( 1, term_cols, (term_rows as usize - 1, 0), PROMPT.to_string(), ); - user_input = textfield.readline_with_initial("", ""); - } + textfield.readline_with_initial("", "") + }; if let Some(user_input) = user_input { let path = path::PathBuf::from(user_input); match std::fs::create_dir_all(&path) { - Ok(_) => { - ReloadDirList::reload(context, view); - } - Err(e) => { - ui::wprint_err(&view.bot_win, e.to_string().as_str()); - } + Ok(_) => ReloadDirList::reload(context, view), + Err(e) => return Err(JoshutoError::IO(e)), } } - ncurses::doupdate(); + Ok(()) } } diff --git a/src/commands/open_file.rs b/src/commands/open_file.rs index ad71b51..1d8801e 100644 --- a/src/commands/open_file.rs +++ b/src/commands/open_file.rs @@ -4,6 +4,7 @@ use std::path::{Path, PathBuf}; use crate::commands::{self, JoshutoCommand, JoshutoRunnable}; use crate::config::mimetype; use crate::context::JoshutoContext; +use crate::error::JoshutoError; use crate::preview; use crate::textfield::JoshutoTextField; use crate::ui; @@ -109,7 +110,11 @@ impl std::fmt::Display for OpenFile { } impl JoshutoRunnable for OpenFile { - fn execute(&self, context: &mut JoshutoContext, view: &JoshutoView) { + fn execute( + &self, + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { let mut path: Option<PathBuf> = None; if let Some(curr_list) = context.tabs[context.curr_tab_index].curr_list.as_ref() { if let Some(entry) = curr_list.get_curr_ref() { @@ -137,16 +142,14 @@ impl JoshutoRunnable for OpenFile { None => None, }; if let Some(paths) = paths { - if !paths.is_empty() { - Self::open_file(&paths); - } else { - ui::wprint_msg(&view.bot_win, "No files selected: 0"); - } + Self::open_file(&paths); } else { - ui::wprint_msg(&view.bot_win, "No files selected: None"); + let err = std::io::Error::new(std::io::ErrorKind::NotFound, "No files selected"); + return Err(JoshutoError::IO(err)); } } ncurses::doupdate(); + Ok(()) } } @@ -234,11 +237,12 @@ impl std::fmt::Display for OpenFileWith { } impl JoshutoRunnable for OpenFileWith { - fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) { + fn execute(&self, context: &mut JoshutoContext, _: &JoshutoView) -> Result<(), JoshutoError> { if let Some(s) = context.tabs[context.curr_tab_index].curr_list.as_ref() { if let Some(paths) = commands::collect_selected_paths(s) { Self::open_with(&paths); } } + Ok(()) } } diff --git a/src/commands/parent_directory.rs b/src/commands/parent_directory.rs index fe219df..59a6122 100644 --- a/src/commands/parent_directory.rs +++ b/src/commands/parent_directory.rs @@ -1,5 +1,6 @@ use crate::commands::{JoshutoCommand, JoshutoRunnable}; use crate::context::JoshutoContext; +use crate::error::JoshutoError; use crate::preview; use crate::ui; use crate::window::JoshutoView; @@ -15,9 +16,12 @@ impl ParentDirectory { "parent_directory" } - pub fn parent_directory(context: &mut JoshutoContext, view: &JoshutoView) { + pub fn parent_directory( + context: &mut JoshutoContext, + view: &JoshutoView, + ) -> Result<(), JoshutoError> { if !context.curr_tab_mut().curr_path.pop() { - return; + return Ok(()); } match std::env::set_current_dir(&context.curr_tab_ref().curr_path) { @@ -54,12 +58,13 @@ impl ParentDirectory { &context.hostname, |