summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiayi Zhao <jeff.no.zhao@gmail.com>2019-04-14 17:57:50 -0400
committerJiayi Zhao <jeff.no.zhao@gmail.com>2019-04-14 17:57:50 -0400
commit71e0c7faf3cc283b2b24e70631e5b18a7a7525cd (patch)
treeb27794c91a930ae2a1bc5cdc6a468b9b4d553134
parent5a820a7a275bf5cacd2c545c0a0ac533789ec349 (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.rs28
-rw-r--r--src/commands/cursor_move.rs45
-rw-r--r--src/commands/delete_files.rs12
-rw-r--r--src/commands/file_operations.rs330
-rw-r--r--src/commands/mod.rs4
-rw-r--r--src/commands/new_directory.rs25
-rw-r--r--src/commands/open_file.rs20
-rw-r--r--src/commands/parent_directory.rs21
-rw-r--r--src/commands/paste_files.rs222
-rw-r--r--src/commands/quit.rs24
-rw-r--r--src/commands/reload_dir.rs8
-rw-r--r--src/commands/rename_file.rs32
-rw-r--r--src/commands/search.rs29
-rw-r--r--src/commands/selection.rs13
-rw-r--r--src/commands/set_mode.rs8
-rw-r--r--src/commands/show_hidden.rs8
-rw-r--r--src/commands/tab_operations.rs42
-rw-r--r--src/commands/tab_switch.rs20
-rw-r--r--src/error.rs3
-rw-r--r--src/main.rs1
-rw-r--r--src/run.rs109
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,