summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiayi Zhao <jeff.no.zhao@gmail.com>2019-04-28 08:11:06 -0400
committerJiayi Zhao <jeff.no.zhao@gmail.com>2019-04-28 08:16:42 -0400
commitb3e9d955b0a60b55a9edeed93e00ce2772f5b467 (patch)
tree31b92eea0e2a3e4f506d7df7932b72f865fbc187
parent6f0ae400152d02f43ffd2911040302c97d84178f (diff)
from_args has been changed from option to result
- attempt to fix progress bars
-rw-r--r--src/commands/cursor_move.rs1
-rw-r--r--src/commands/file_operations.rs15
-rw-r--r--src/commands/mod.rs253
-rw-r--r--src/config/keymap.rs4
-rw-r--r--src/error.rs28
-rw-r--r--src/run.rs4
6 files changed, 161 insertions, 144 deletions
diff --git a/src/commands/cursor_move.rs b/src/commands/cursor_move.rs
index 049657a..dbea053 100644
--- a/src/commands/cursor_move.rs
+++ b/src/commands/cursor_move.rs
@@ -3,7 +3,6 @@ use crate::context::JoshutoContext;
use crate::error::JoshutoError;
use crate::window::JoshutoView;
-
pub fn cursor_move(mut new_index: usize, context: &mut JoshutoContext, view: &JoshutoView) {
let curr_tab = &mut context.tabs[context.curr_tab_index];
diff --git a/src/commands/file_operations.rs b/src/commands/file_operations.rs
index bb6df9f..ca0836d 100644
--- a/src/commands/file_operations.rs
+++ b/src/commands/file_operations.rs
@@ -301,14 +301,15 @@ fn fs_cut_thread(
let handle = |process_info: fs_extra::TransitProcess| {
let progress_info = ProgressInfo {
- bytes_finished: process_info.copied_bytes,
- total_bytes: process_info.total_bytes,
- };
+ bytes_finished: process_info.copied_bytes,
+ total_bytes: process_info.total_bytes,
+ };
tx.send(progress_info.clone()).unwrap();
fs_extra::dir::TransitProcessResult::ContinueOrAbort
};
- match fs_extra::move_items_with_progress(&cpath, &destination, &options, handle) {
+ match fs_extra::move_items_with_progress(&cpath, &destination, &options, handle)
+ {
Err(e) => {
let err =
std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e));
@@ -370,9 +371,9 @@ fn fs_copy_thread(
let handle = |process_info: fs_extra::TransitProcess| {
let progress_info = ProgressInfo {
- bytes_finished: process_info.copied_bytes,
- total_bytes: process_info.total_bytes,
- };
+ bytes_finished: process_info.copied_bytes,
+ total_bytes: process_info.total_bytes,
+ };
tx.send(progress_info.clone()).unwrap();
fs_extra::dir::TransitProcessResult::ContinueOrAbort
};
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index 2f72640..7108b9f 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -18,7 +18,7 @@ mod tab_switch;
pub use self::change_directory::ChangeDirectory;
pub use self::cursor_move::{
CursorMoveDown, CursorMoveEnd, CursorMoveHome, CursorMovePageDown, CursorMovePageUp,
- CursorMoveUp
+ CursorMoveUp,
};
pub use self::delete_files::DeleteFiles;
pub use self::file_operations::{CopyFiles, CutFiles, FileOperationThread, PasteFiles};
@@ -37,11 +37,10 @@ pub use self::tab_operations::{CloseTab, NewTab};
pub use self::tab_switch::TabSwitch;
use std::collections::HashMap;
-use std::fmt;
use std::path::PathBuf;
use crate::context::JoshutoContext;
-use crate::error::JoshutoError;
+use crate::error::{JoshutoError, KeymapError};
use crate::window::JoshutoView;
#[derive(Debug)]
@@ -58,7 +57,7 @@ pub trait JoshutoRunnable {
pub trait JoshutoCommand: JoshutoRunnable + std::fmt::Display + std::fmt::Debug {}
impl std::fmt::Display for CommandKeybind {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
CommandKeybind::SimpleKeybind(s) => write!(f, "{}", s),
CommandKeybind::CompositeKeybind(_) => write!(f, "..."),
@@ -72,68 +71,63 @@ pub struct ProgressInfo {
pub total_bytes: u64,
}
-pub fn from_args(command: &str, args: Option<&Vec<String>>) -> Option<Box<JoshutoCommand>> {
+pub fn from_args(
+ command: &str,
+ args: Option<&Vec<String>>,
+) -> Result<Box<JoshutoCommand>, KeymapError> {
match command {
- "cd" => {
- if let Some(args) = args {
- match wordexp::wordexp(args[0].as_str(), 0) {
- Ok(mut exp_strs) => {
- if let Some(exp_str) = exp_strs.next() {
- let path = PathBuf::from(exp_str);
- return Some(Box::new(self::ChangeDirectory::new(path)));
- }
- }
- Err(_) => {
- eprintln!("Failed to parse: {:?}", args[0]);
- }
- }
- }
- None
- }
- "close_tab" => Some(Box::new(self::CloseTab::new())),
- "copy_files" => Some(Box::new(self::CopyFiles::new())),
- "cursor_move_down" => {
- if let Some(args) = args {
- if !args.is_empty() {
- match args[0].parse::<usize>() {
- Ok(s) => {
- return Some(Box::new(self::CursorMoveUp::new(s)));
- }
- Err(e) => {
- eprintln!("{}", e);
- }
- }
- }
- }
- None
- }
- "cursor_move_up" => {
- if let Some(args) = args {
- if !args.is_empty() {
- match args[0].parse::<usize>() {
- Ok(s) => {
- return Some(Box::new(self::CursorMoveDown::new(s)));
- }
- Err(e) => {
- eprintln!("{}", e);
- }
+ "cd" => match args {
+ Some(args) if !args.is_empty() => match wordexp::wordexp(args[0].as_str(), 0) {
+ Ok(mut exp_strs) => match exp_strs.next() {
+ Some(exp_str) => {
+ Ok(Box::new(self::ChangeDirectory::new(PathBuf::from(exp_str))))
}
- }
- }
- None
- }
- "cursor_move_home" => Some(Box::new(self::CursorMoveHome::new())),
- "cursor_move_end" => Some(Box::new(self::CursorMoveEnd::new())),
- "cursor_move_page_up" => Some(Box::new(self::CursorMovePageUp::new())),
- "cursor_move_page_down" => Some(Box::new(self::CursorMovePageDown::new())),
- "cut_files" => Some(Box::new(self::CutFiles::new())),
- "delete_files" => Some(Box::new(self::DeleteFiles::new())),
- "force_quit" => Some(Box::new(self::ForceQuit::new())),
- "mkdir" => Some(Box::new(self::NewDirectory::new())),
- "new_tab" => Some(Box::new(self::NewTab::new())),
- "open_file" => Some(Box::new(self::OpenFile::new())),
- "open_file_with" => Some(Box::new(self::OpenFileWith::new())),
- "parent_directory" => Some(Box::new(self::ParentDirectory::new())),
+ None => Err(KeymapError::new(
+ Some("cd"),
+ format!("Failed to parse: {}", args[0]),
+ )),
+ },
+ Err(_) => Err(KeymapError::new(
+ Some("cd"),
+ format!("Failed to parse: {}", args[0]),
+ )),
+ },
+ _ => match dirs::home_dir() {
+ Some(s) => Ok(Box::new(self::ChangeDirectory::new(s))),
+ None => Err(KeymapError::new(
+ Some("cd"),
+ String::from("Cannot find home directory"),
+ )),
+ },
+ },
+ "close_tab" => Ok(Box::new(self::CloseTab::new())),
+ "copy_files" => Ok(Box::new(self::CopyFiles::new())),
+ "cursor_move_down" => match args {
+ Some(args) if !args.is_empty() => match args[0].parse::<usize>() {
+ Ok(s) => Ok(Box::new(self::CursorMoveDown::new(s))),
+ Err(e) => Err(KeymapError::new(Some("cursor_move_down"), e.to_string())),
+ },
+ _ => Ok(Box::new(self::CursorMoveDown::new(1))),
+ },
+ "cursor_move_up" => match args {
+ Some(args) if !args.is_empty() => match args[0].parse::<usize>() {
+ Ok(s) => Ok(Box::new(self::CursorMoveUp::new(s))),
+ Err(e) => Err(KeymapError::new(Some("cursor_move_up"), e.to_string())),
+ },
+ _ => Ok(Box::new(self::CursorMoveUp::new(1))),
+ },
+ "cursor_move_home" => Ok(Box::new(self::CursorMoveHome::new())),
+ "cursor_move_end" => Ok(Box::new(self::CursorMoveEnd::new())),
+ "cursor_move_page_up" => Ok(Box::new(self::CursorMovePageUp::new())),
+ "cursor_move_page_down" => Ok(Box::new(self::CursorMovePageDown::new())),
+ "cut_files" => Ok(Box::new(self::CutFiles::new())),
+ "delete_files" => Ok(Box::new(self::DeleteFiles::new())),
+ "force_quit" => Ok(Box::new(self::ForceQuit::new())),
+ "mkdir" => Ok(Box::new(self::NewDirectory::new())),
+ "new_tab" => Ok(Box::new(self::NewTab::new())),
+ "open_file" => Ok(Box::new(self::OpenFile::new())),
+ "open_file_with" => Ok(Box::new(self::OpenFileWith::new())),
+ "parent_directory" => Ok(Box::new(self::ParentDirectory::new())),
"paste_files" => {
let mut options = fs_extra::dir::CopyOptions::new();
if let Some(args) = args {
@@ -141,50 +135,43 @@ pub fn from_args(command: &str, args: Option<&Vec<String>>) -> Option<Box<Joshut
let splitarg: Vec<&str> = arg.split('=').collect();
if splitarg.len() == 2 {
match splitarg[0] {
- "overwrite" => {
- if let Ok(s) = splitarg[1].parse::<bool>() {
- options.overwrite = s;
- } else {
- eprintln!("Failed to parse: {}", arg);
- }
+ "overwrite" => match splitarg[1].parse::<bool>() {
+ Ok(s) => options.overwrite = s,
+ _ => eprintln!("Failed to parse: {}", arg),
+ },
+ "skip_exist" => match splitarg[1].parse::<bool>() {
+ Ok(s) => options.skip_exist = s,
+ _ => eprintln!("Failed to parse: {}", arg),
+ },
+ _ => {
+ return Err(KeymapError::new(
+ Some("paste_files"),
+ format!("unknown option {}", arg),
+ ));
}
- "skip_exist" => {
- if let Ok(s) = splitarg[1].parse::<bool>() {
- options.skip_exist = s;
- } else {
- eprintln!("Failed to parse: {}", arg);
- }
- }
- _ => {}
}
}
}
}
- Some(Box::new(self::PasteFiles::new(options)))
+ Ok(Box::new(self::PasteFiles::new(options)))
}
- "quit" => Some(Box::new(self::Quit::new())),
- "reload_dir_list" => Some(Box::new(self::ReloadDirList::new())),
+ "quit" => Ok(Box::new(self::Quit::new())),
+ "reload_dir_list" => Ok(Box::new(self::ReloadDirList::new())),
"rename_file" => {
- let method: RenameFileMethod;
- if let Some(args) = args {
- if !args.is_empty() {
- method = match args[0].as_str() {
- "prepend" => self::RenameFileMethod::Prepend,
- "overwrite" => self::RenameFileMethod::Overwrite,
- "append" => self::RenameFileMethod::Append,
- _ => self::RenameFileMethod::Append,
- };
- } else {
- method = self::RenameFileMethod::Append;
- }
- } else {
- method = self::RenameFileMethod::Append;
- }
- Some(Box::new(self::RenameFile::new(method)))
+ let method: RenameFileMethod = match args {
+ Some(args) if !args.is_empty() => match args[0].as_str() {
+ "prepend" => self::RenameFileMethod::Prepend,
+ "overwrite" => self::RenameFileMethod::Overwrite,
+ "append" => self::RenameFileMethod::Append,
+ _ => self::RenameFileMethod::Append,
+ },
+ _ => self::RenameFileMethod::Append,
+ };
+ Ok(Box::new(self::RenameFile::new(method)))
}
- "search" => Some(Box::new(self::Search::new())),
- "search_next" => Some(Box::new(self::SearchNext::new())),
- "search_prev" => Some(Box::new(self::SearchPrev::new())),
+ "search" => Ok(Box::new(self::Search::new())),
+ "search_next" => Ok(Box::new(self::SearchNext::new())),
+ "search_prev" => Ok(Box::new(self::SearchPrev::new())),
"select_files" => {
let mut toggle = false;
let mut all = false;
@@ -193,45 +180,49 @@ pub fn from_args(command: &str, args: Option<&Vec<String>>) -> Option<Box<Joshut
let splitarg: Vec<&str> = arg.split('=').collect();
if splitarg.len() == 2 {
match splitarg[0] {
- "toggle" => {
- if let Ok(s) = splitarg[1].parse::<bool>() {
- toggle = s;
- } else {
- eprintln!("Failed to parse: {}", arg);
+ "toggle" => match splitarg[1].parse::<bool>() {
+ Ok(s) => toggle = s,
+ _ => {
+ return Err(KeymapError::new(
+ Some("select_files"),
+ format!("unknown option {}", arg),
+ ));
}
- }
- "all" => {
- if let Ok(s) = splitarg[1].parse::<bool>() {
- all = s;
- } else {
- eprintln!("Failed to parse: {}", arg);
+ },
+ "all" => match splitarg[1].parse::<bool>() {
+ Ok(s) => all = s,
+ _ => {
+ return Err(KeymapError::new(
+ Some("select_files"),
+ format!("unknown option {}", arg),
+ ));
}
+ },
+ _ => {
+ return Err(KeymapError::new(
+ Some("select_files"),
+ format!("unknown option {}", arg),
+ ));
}
- _ => {}
- }
- }
- }
- }
- Some(Box::new(self::SelectFiles::new(toggle, all)))
- }
- "set_mode" => Some(Box::new(self::SetMode::new())),
- "tab_switch" => {
- if let Some(args) = args {
- if !args.is_empty() {
- match args[0].parse::<i32>() {
- Ok(s) => {
- return Some(Box::new(self::TabSwitch::new(s)));
- }
- Err(e) => {
- eprintln!("{}", e);
}
}
}
}
- None
+ Ok(Box::new(self::SelectFiles::new(toggle, all)))
}
- "toggle_hidden" => Some(Box::new(self::ToggleHiddenFiles::new())),
- _ => None,
+ "set_mode" => Ok(Box::new(self::SetMode::new())),
+ "tab_switch" => match args {
+ Some(args) if !args.is_empty() => match args[0].parse::<i32>() {
+ Ok(s) => Ok(Box::new(self::TabSwitch::new(s))),
+ Err(e) => Err(KeymapError::new(Some("tab_switch"), e.to_string())),
+ },
+ _ => Err(KeymapError::new(
+ Some("tab_switch"),
+ String::from("No option provided"),
+ )),
+ },
+ "toggle_hidden" => Ok(Box::new(self::ToggleHiddenFiles::new())),
+ inp @ _ => Err(KeymapError::new(None, format!("Unknown command: {}", inp))),
}
}
diff --git a/src/config/keymap.rs b/src/config/keymap.rs
index 9fb2e7d..4b4e64d 100644
--- a/src/config/keymap.rs
+++ b/src/config/keymap.rs
@@ -32,8 +32,8 @@ impl Flattenable<JoshutoKeymap> for JoshutoRawKeymap {
if let Some(maps) = self.mapcommand {
for mapcommand in maps {
match commands::from_args(mapcommand.command.as_str(), mapcommand.args.as_ref()) {
- Some(command) => insert_keycommand(&mut keymaps, command, &mapcommand.keys[..]),
- None => eprintln!("Unknown command: {}", mapcommand.command),
+ Ok(command) => insert_keycommand(&mut keymaps, command, &mapcommand.keys[..]),
+ Err(e) => eprintln!("{}", e),
}
}
}
diff --git a/src/error.rs b/src/error.rs
index a964132..bae1e0c 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,3 +1,31 @@
pub enum JoshutoError {
IO(std::io::Error),
}
+
+/*
+pub enum KeymapErrorKind {
+ Parse,
+ UnknownArgument,
+ UnknownCommand,
+}
+*/
+
+pub struct KeymapError {
+ pub command: Option<&'static str>,
+ pub error: String,
+}
+
+impl KeymapError {
+ pub fn new(command: Option<&'static str>, error: String) -> Self {
+ KeymapError { command, error }
+ }
+}
+
+impl std::fmt::Display for KeymapError {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match self.command {
+ Some(s) => write!(f, "{}: {}", s, self.error),
+ None => write!(f, "{}", self.error),
+ }
+ }
+}
diff --git a/src/run.rs b/src/run.rs
index f070392..82ab20e 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -193,9 +193,7 @@ pub fn run(config_t: config::JoshutoConfig, keymap_t: config::JoshutoKeymap) {
match keymap_t.keymaps.get(&ch) {
Some(CommandKeybind::CompositeKeybind(m)) => match recurse_get_keycommand(&m) {
- Some(s) => {
- keycommand = s;
- }
+ Some(s) => keycommand = s,
None => continue,
},
Some(CommandKeybind::SimpleKeybind(s)) => {