diff options
33 files changed, 392 insertions, 429 deletions
@@ -19,6 +19,7 @@ rand = "^0" rustyline = "^4" serde = "^1" serde_derive = "^1" +shell-words = "^1" structopt = "^0" termion = "^1" toml = "^0" @@ -38,10 +39,10 @@ xdg = "^2" # whoami = "*" # xdg = "*" -[dependencies.wordexp] -version = "^0" -git = "https://github.com/kamiyaa/wordexp-rs" -branch="dev" +# [dependencies.wordexp] +# version = "^0" +# git = "https://github.com/kamiyaa/wordexp-rs" +# branch="dev" # path = "lib/wordexp-rs" [features] diff --git a/src/commands/bulk_rename.rs b/src/commands/bulk_rename.rs index 2fff733..dc60c67 100644 --- a/src/commands/bulk_rename.rs +++ b/src/commands/bulk_rename.rs @@ -56,8 +56,8 @@ impl BulkRename { for path in &paths { let file_name = path.file_name().unwrap(); let file_name_as_bytes = file_name.to_str().unwrap().as_bytes(); - file.write(file_name_as_bytes)?; - file.write(&[b'\n'])?; + file.write_all(file_name_as_bytes)?; + file.write_all(&[b'\n'])?; } } diff --git a/src/commands/file_ops/copy.rs b/src/commands/file_ops/copy.rs index a7edbef..7e05752 100644 --- a/src/commands/file_ops/copy.rs +++ b/src/commands/file_ops/copy.rs @@ -1,9 +1,10 @@ use crate::commands::{JoshutoCommand, JoshutoRunnable}; use crate::context::JoshutoContext; use crate::error::JoshutoResult; +use crate::io::FileOp; use crate::ui::TuiBackend; -use super::local_state::{FileOp, LocalState}; +use super::local_state::LocalState; #[derive(Clone, Debug)] pub struct CopyFiles; @@ -28,13 +29,9 @@ impl std::fmt::Display for CopyFiles { impl JoshutoRunnable for CopyFiles { fn execute(&self, context: &mut JoshutoContext, _: &mut TuiBackend) -> JoshutoResult<()> { let curr_tab = context.curr_tab_ref(); - match curr_tab.curr_list_ref() { - Some(list) => { - LocalState::repopulated_selected_files(list)?; - LocalState::set_file_op(FileOp::Copy); - LocalState::set_tab_src(context.curr_tab_index); - } - None => {} + if let Some(list) = curr_tab.curr_list_ref() { + LocalState::repopulate(list)?; + LocalState::set_file_op(FileOp::Copy); } Ok(()) } diff --git a/src/commands/file_ops/cut.rs b/src/commands/file_ops/cut.rs index 42ec7f2..772e091 100644 --- a/src/commands/file_ops/cut.rs +++ b/src/commands/file_ops/cut.rs @@ -1,9 +1,10 @@ use crate::commands::{JoshutoCommand, JoshutoRunnable}; use crate::context::JoshutoContext; use crate::error::JoshutoResult; +use crate::io::FileOp; use crate::ui::TuiBackend; -use super::local_state::{FileOp, LocalState}; +use super::local_state::LocalState; #[derive(Clone, Debug)] pub struct CutFiles; @@ -28,13 +29,9 @@ impl std::fmt::Display for CutFiles { impl JoshutoRunnable for CutFiles { fn execute(&self, context: &mut JoshutoContext, _: &mut TuiBackend) -> JoshutoResult<()> { let curr_tab = context.curr_tab_ref(); - match curr_tab.curr_list_ref() { - Some(list) => { - LocalState::repopulated_selected_files(list)?; - LocalState::set_file_op(FileOp::Cut); - LocalState::set_tab_src(context.curr_tab_index); - } - None => {} + if let Some(list) = curr_tab.curr_list_ref() { + LocalState::repopulate(list)?; + LocalState::set_file_op(FileOp::Cut); } Ok(()) } diff --git a/src/commands/file_ops/local_state.rs b/src/commands/file_ops/local_state.rs index 12ffa6c..f8a4782 100644 --- a/src/commands/file_ops/local_state.rs +++ b/src/commands/file_ops/local_state.rs @@ -1,35 +1,33 @@ use lazy_static::lazy_static; -use std::path; -use std::sync::{atomic, Mutex}; - use crate::fs::JoshutoDirList; +use crate::io::FileOp; +use std::path; +use std::sync::Mutex; lazy_static! { - 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); + static ref LOCAL_STATE: Mutex<LocalState> = Mutex::new(LocalState::new()); } -#[derive(Clone, Debug)] -pub enum FileOp { - Cut, - Copy, +pub struct LocalState { + pub paths: Vec<path::PathBuf>, + pub file_op: FileOp, } -pub struct LocalState; - impl LocalState { - pub fn set_file_op(operation: FileOp) { - let mut data = FILE_OPERATION.lock().unwrap(); - *data = operation; + pub fn new() -> Self { + Self { + paths: Vec::new(), + file_op: FileOp::Copy, + } } - pub fn set_tab_src(tab_index: usize) { - TAB_SRC.store(tab_index, atomic::Ordering::Release); + pub fn set_file_op(operation: FileOp) { + let mut data = LOCAL_STATE.lock().unwrap(); + (*data).file_op = operation; } - pub fn repopulated_selected_files(dirlist: &JoshutoDirList) -> std::io::Result<()> { + pub fn repopulate(dirlist: &JoshutoDirList) -> std::io::Result<()> { let selected = dirlist.get_selected_paths(); if selected.is_empty() { Err(std::io::Error::new( @@ -39,17 +37,16 @@ impl LocalState { } else { let selected_clone: Vec<path::PathBuf> = selected.iter().map(|p| (*p).clone()).collect(); - let mut data = SELECTED_FILES.lock().unwrap(); - *data = Some(selected_clone); + let mut data = LOCAL_STATE.lock().unwrap(); + (*data).paths = selected_clone; Ok(()) } } - pub fn take_selected_files() -> Option<Vec<path::PathBuf>> { - SELECTED_FILES.lock().unwrap().take() - } - - pub fn get_file_operation() -> FileOp { - (*FILE_OPERATION.lock().unwrap()).clone() + pub fn take() -> LocalState { + let mut m = LOCAL_STATE.lock().unwrap(); + let mut v = LocalState::new(); + std::mem::swap(&mut (*m), &mut v); + v } } diff --git a/src/commands/file_ops/mod.rs b/src/commands/file_ops/mod.rs index e4a0da3..1ed8030 100644 --- a/src/commands/file_ops/mod.rs +++ b/src/commands/file_ops/mod.rs @@ -1,11 +1,8 @@ mod copy; mod cut; mod local_state; -mod name_resolution; mod paste; -mod paste_copy; -mod paste_cut; -pub use self::copy::CopyFiles; -pub use self::cut::CutFiles; -pub use self::paste::PasteFiles; +pub use copy::CopyFiles; +pub use cut::CutFiles; +pub use paste::PasteFiles; diff --git a/src/commands/file_ops/paste.rs b/src/commands/file_ops/paste.rs index 74136c6..019a558 100644 --- a/src/commands/file_ops/paste.rs +++ b/src/commands/file_ops/paste.rs @@ -1,15 +1,13 @@ use crate::commands::{JoshutoCommand, JoshutoRunnable}; use crate::context::JoshutoContext; -use crate::error::JoshutoResult; -use crate::io::Options; +use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult}; +use crate::io::{IOWorkerOptions, IOWorkerThread}; use crate::ui::TuiBackend; -use super::local_state::{FileOp, LocalState}; -use super::paste_copy::paste_copy; -use super::paste_cut::paste_cut; +use super::local_state::LocalState; pub struct PasteFiles { - options: Options, + options: IOWorkerOptions, } impl JoshutoCommand for PasteFiles {} @@ -34,19 +32,25 @@ impl std::fmt::Debug for PasteFiles { impl JoshutoRunnable for PasteFiles { fn execute(&self, context: &mut JoshutoContext, _: &mut TuiBackend) -> JoshutoResult<()> { - let file_operation = LocalState::get_file_operation(); - let thread = match file_operation { - FileOp::Copy => paste_copy(context, self.options.clone()), - FileOp::Cut => paste_cut(context, self.options.clone()), - }; - let thread = thread?; - context.add_new_worker(thread); + let state = LocalState::take(); + if state.paths.is_empty() { + Err(JoshutoError::new( + JoshutoErrorKind::IOInvalidData, + "no files selected".to_string(), + ))?; + } + let tab_dest = context.curr_tab_index; + let dest = context.tabs[tab_dest].curr_path.clone(); + let mut options = self.options.clone(); + options.kind = state.file_op; + let worker_thread = IOWorkerThread::new(options, state.paths, dest); + context.push_worker_thread(worker_thread); Ok(()) } } impl PasteFiles { - pub fn new(options: Options) -> Self { + pub fn new(options: IOWorkerOptions) -> Self { PasteFiles { options } } pub const fn command() -> &'static str { diff --git a/src/commands/file_ops/paste_copy.rs b/src/commands/file_ops/paste_copy.rs deleted file mode 100644 index 5fad0e4..0000000 --- a/src/commands/file_ops/paste_copy.rs +++ /dev/null @@ -1,82 +0,0 @@ -use std::fs; -use std::path::Path; -use std::sync::mpsc; -use std::thread; - -use crate::context::JoshutoContext; -use crate::io::{IOWorkerThread, Options}; - -use super::local_state::LocalState; -use super::name_resolution::rename_filename_conflict; - -pub fn recursive_copy(dest: &Path, src: &Path, options: &Options) -> std::io::Result<u64> { - let mut dest_buf = dest.to_path_buf(); - if let Some(s) = src.file_name() { - dest_buf.push(s); - } - rename_filename_conflict(&mut dest_buf); - let file_type = fs::symlink_metadata(src)?.file_type(); - if file_type.is_dir() { - fs::create_dir(dest_buf.as_path())?; - let mut total = 0; - for entry in fs::read_dir(src)? { - let entry = entry?; - let entry_path = entry.path(); - total += recursive_copy(dest_buf.as_path(), entry_path.as_path(), options)?; - } - Ok(total) - } else if file_type.is_file() { - fs::copy(src, dest_buf) - } else if file_type.is_symlink() { - let link_path = fs::read_link(src)?; - std::os::unix::fs::symlink(link_path, dest_buf)?; - Ok(0) - } else { - Ok(0) - } -} - -pub fn paste_copy( - context: &mut JoshutoContext, - options: Options, -) -> std::io::Result<IOWorkerThread> { - let paths = LocalState::take_selected_files() - .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "no files selected"))?; - if paths.is_empty() { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "no files selected", - )); - } - - let tab_dest = context.curr_tab_index; - let thread_dest = context.tabs[tab_dest].curr_path.clone(); - let dest = thread_dest.clone(); - let src = paths[0].parent().unwrap().to_path_buf(); - - let (tx_start, rx_start) = mpsc::channel(); - let (tx, rx) = mpsc::channel(); - - let handle: thread::JoinHandle<std::io::Result<u64>> = - thread::spawn(move || match rx_start.recv() { - Ok(_) => { - let mut total = 0; - for path in paths { - total += recursive_copy(thread_dest.as_path(), path.as_path(), &options)?; - tx.send(total); - } - Ok(total) - } - Err(_) => Ok(0), - }); - - let thread = IOWorkerThread { - src, - dest, - handle, - tx_start, - rx, - }; - - Ok(thread) -} diff --git a/src/commands/file_ops/paste_cut.rs b/src/commands/file_ops/paste_cut.rs deleted file mode 100644 index 6ae1569..0000000 --- a/src/commands/file_ops/paste_cut.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::fs; -use std::path::Path; -use std::sync::mpsc; -use std::thread; - -use crate::context::JoshutoContext; -use crate::io::{IOWorkerThread, Options}; - -use super::local_state::LocalState; -use super::name_resolution::rename_filename_conflict; - -pub fn recursive_cut(dest: &Path, src: &Path, options: &Options) -> std::io::Result<u64> { - let mut dest_buf = dest.to_path_buf(); - if let Some(s) = src.file_name() { - dest_buf.push(s); - } - rename_filename_conflict(&mut dest_buf); - let metadata = fs::symlink_metadata(src)?; - let file_type = metadata.file_type(); - if file_type.is_dir() { - match fs::rename(src, dest_buf.as_path()) { - Ok(_) => Ok(metadata.len()), - Err(_) => { - let mut total = 0; - fs::create_dir(dest_buf.as_path())?; - for entry in fs::read_dir(src)? { - let entry = entry?; - let entry_path = entry.path(); - total += recursive_cut(dest_buf.as_path(), entry_path.as_path(), options)?; - } - fs::remove_dir(src)?; - Ok(total) - } - } - } else if file_type.is_file() { - if fs::rename(src, dest_buf.as_path()).is_err() { - fs::copy(src, dest_buf.as_path())?; - fs::remove_file(src)?; - } - Ok(metadata.len()) - } else if file_type.is_symlink() { - let link_path = fs::read_link(src)?; - std::os::unix::fs::symlink(link_path, dest_buf)?; - fs::remove_file(src)?; - Ok(metadata.len()) - } else { - Ok(0) - } -} - -pub fn paste_cut( - context: &mut JoshutoContext, - options: Options, -) -> std::io::Result<IOWorkerThread> { - let paths = LocalState::take_selected_files() - .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "no files selected"))?; - if paths.is_empty() { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "no files selected", - )); - } - - let tab_dest = context.curr_tab_index; - let thread_dest = context.tabs[tab_dest].curr_path.clone(); - let dest = thread_dest.clone(); - let src = paths[0].parent().unwrap().to_path_buf(); - - let (tx_start, rx_start) = mpsc::channel(); - let (tx, rx) = mpsc::channel(); - - let handle: thread::JoinHandle<std::io::Result<u64>> = - thread::spawn(move || match rx_start.recv() { - Ok(_) => { - let mut total = 0; - for path in paths { - total += recursive_cut(thread_dest.as_path(), path.as_path(), &options)?; - tx.send(total); - } - Ok(total) - } - Err(_) => Ok(0), - }); - - let thread = IOWorkerThread { - src, - dest, - handle, - tx_start, - rx, - }; - - Ok(thread) -} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index f276d8d..6c5940d 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -40,7 +40,7 @@ pub use self::selection::SelectFiles; pub use self::set_mode::SetMode; pub use self::shell::ShellCommand; pub use self::show_hidden::ToggleHiddenFiles; -pub use self::sort::{Sort,SortReverse}; +pub use self::sort::{Sort, SortReverse}; pub use self::tab_operations::{CloseTab, NewTab}; pub use self::tab_switch::TabSwitch; @@ -49,7 +49,7 @@ use std::path::PathBuf; use crate::config::JoshutoCommandMapping; use crate::context::JoshutoContext; use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult}; -use crate::io::Options; +use crate::io::IOWorkerOptions; use crate::ui::TuiBackend; use crate::util::sort::SortType; @@ -78,7 +78,7 @@ pub trait JoshutoCommand: JoshutoRunnable + std::fmt::Display + std::fmt::Debug pub fn parse_command(s: &str) -> JoshutoResult<Box<dyn JoshutoCommand>> { let (command, arg) = match s.find(' ') { - Some(i) => (&s[..i], s[i+1..].trim_start()), + Some(i) => (&s[..i], s[i + 1..].trim_start()), None => (s, ""), }; @@ -94,10 +94,13 @@ pub fn parse_command(s: &str) -> JoshutoResult<Box<dyn JoshutoCommand>> { }, ".." => Ok(Box::new(self::ParentDirectory::new())), arg => Ok(Box::new(self::ChangeDirectory::new(PathBuf::from(arg)))), - } + }, "close_tab" => Ok(Box::new(self::CloseTab::new())), "copy_files" => Ok(Box::new(self::CopyFiles::new())), - "console" => Ok(Box::new(self::CommandLine::new(arg.to_owned(), "".to_owned()))), + "console" => Ok(Box::new(self::CommandLine::new( + arg.to_owned(), + "".to_owned(), + ))), "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())), @@ -111,7 +114,7 @@ pub fn parse_command(s: &str) -> JoshutoResult<Box<dyn JoshutoCommand>> { e.to_string(), )), }, - } + }, "cursor_move_up" => match arg { "" => Ok(Box::new(self::CursorMoveUp::new(1))), arg => match arg.parse::<usize>() { @@ -121,7 +124,7 @@ pub fn parse_command(s: &str) -> JoshutoResult<Box<dyn JoshutoCommand>> { e.to_string(), )), }, - } + }, "cut_files" => Ok(Box::new(self::CutFiles::new())), "delete_files" => Ok(Box::new(self::DeleteFiles::new())), "force_quit" => Ok(Box::new(self::ForceQuit::new())), @@ -131,13 +134,13 @@ pub fn parse_command(s: &str) -> JoshutoResult<Box<dyn JoshutoCommand>> { format!("{}: missing additional parameter", command), )), arg => Ok(Box::new(self::NewDirectory::new(PathBuf::from(arg)))), - } + }, "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())), "paste_files" => { - let mut options = Options::default(); + let mut options = IOWorkerOptions::default(); for arg in arg.split_whitespace() { match arg { "--overwrite" => options.overwrite = true, @@ -157,7 +160,7 @@ pub fn parse_command(s: &str) -> JoshutoResult<Box<dyn JoshutoCommand>> { "rename" => match arg { "" => Err(JoshutoError::new( JoshutoErrorKind::IOInvalidData, - format!("rename_file: Expected 1, got 0"), + format!("{}: Expected 1, got 0", command), )), arg => { let path: PathBuf = PathBuf::from(arg); @@ -193,7 +196,17 @@ pub fn parse_command(s: &str) -> JoshutoResult<Box<dyn JoshutoCommand>> { Ok(Box::new(self::SelectFiles::new(toggle, all))) } "set_mode" => Ok(Box::new(self::SetMode::new())), - "shell" => Ok(Box::new(self::ShellCommand::new(arg.to_owned()))), + "shell" => match shell_words::split(arg) { + Ok(s) if !s.is_empty() => Ok(Box::new(self::ShellCommand::new(s))), + Ok(_) => Err(JoshutoError::new( + JoshutoErrorKind::IOInvalidData, + format!("sort: args {}", arg), + )), + Err(e) => Err(JoshutoError::new( + JoshutoErrorKind::IOInvalidData, + format!("{}: {}", arg, e), + )), + }, "sort" => match arg { "reverse" => Ok(Box::new(self::SortReverse::new())), arg => match SortType::parse(arg) { @@ -215,8 +228,8 @@ pub fn parse_command(s: &str) -> JoshutoResult<Box<dyn JoshutoCommand>> { JoshutoErrorKind::IOInvalidData, format!("{}: {}", command, e.to_string()), )), - } - } + }, + }, "toggle_hidden" => Ok(Box::new(self::ToggleHiddenFiles::new())), inp => Err(JoshutoError::new( JoshutoErrorKind::UnknownCommand, diff --git a/src/commands/open_file.rs b/src/commands/open_file.rs index 5c3c966..f7af489 100644 --- a/src/commands/open_file.rs +++ b/src/commands/open_file.rs @@ -1,5 +1,3 @@ -use std::path::Path; - use crate::commands::{ChangeDirectory, JoshutoCommand, JoshutoRunnable}; use crate::config::mimetype::JoshutoMimetypeEntry; use crate::context::JoshutoContext; diff --git a/src/commands/quit.rs b/src/commands/quit.rs index 45283c1..2da6f6b 100644 --- a/src/commands/quit.rs +++ b/src/commands/quit.rs @@ -15,7 +15,7 @@ impl Quit { } pub fn quit(context: &mut JoshutoContext) -> JoshutoResult<()> { - if context.worker_busy { + if context.worker.is_busy() { Err(JoshutoError::new( JoshutoErrorKind::IOOther, String::from("operations running in background, use force_quit to quit"), diff --git a/src/commands/shell.rs b/src/commands/shell.rs index 19e901d..b9cbd1c 100644 --- a/src/commands/shell.rs +++ b/src/commands/shell.rs @@ -1,26 +1,48 @@ use std::process; -use crate::commands::{self, JoshutoCommand, JoshutoRunnable}; +use crate::commands::{JoshutoCommand, JoshutoRunnable, ReloadDirList}; use crate::context::JoshutoContext; use crate::error::JoshutoResult; -use crate::ui::widgets::TuiTextField; use crate::ui::TuiBackend; #[derive(Clone, Debug)] pub struct ShellCommand { - pub command: String, + pub words: Vec<String>, } impl ShellCommand { - pub fn new(command: String) -> Self { - Self { command } + pub fn new(words: Vec<String>) -> Self { + Self { words } } pub const fn command() -> &'static str { "console" } - pub fn shell_command(command: &str) -> std::io::Result<()> { - let mut command = process::Command::new("sh").arg("-c").arg(command).spawn()?; + pub fn shell_command(&self, context: &mut JoshutoContext) -> std::io::Result<()> { + let mut command = process::Command::new(self.words[0].clone()); + for word in self.words.iter().skip(1) { + match word.as_str() { + "%s" => { + let curr_tab = context.curr_tab_ref(); + if let Some(curr_list) = curr_tab.curr_list_ref() { + let mut i = 0; + for entry in curr_list.selected_entries().map(|e| e.file_name()) { + command.arg(entry); + i += 1; + } + if i == 0 { + if let Some(entry) = curr_list.get_curr_ref() { + command.arg(entry.file_name()); + } + } + } + } + s => { + command.arg(s); + } + }; + } + command.status()?; Ok(()) } } @@ -29,14 +51,18 @@ impl JoshutoCommand for ShellCommand {} impl std::fmt::Display for ShellCommand { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}: sh -c '{}'", Self::command(), self.command) + write!(f, "{}: {:?}", Self::command(), self.words.join(" ")) } } impl JoshutoRunnable for ShellCommand { fn execute(&self, context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> { backend.terminal_drop(); - let res = Self::shell_command(self.command.as_str()); + let res = self.shell_command(context); + ReloadDirList::soft_reload(context.curr_tab_index, context)?; + context + .message_queue + .push_back(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 0a22c53..6dd7736 100644 --- a/src/commands/show_hidden.rs +++ b/src/commands/show_hidden.rs @@ -20,9 +20,8 @@ impl ToggleHiddenFiles { for tab in &mut context.tabs { tab.history.depreciate_all_entries(); - match tab.curr_list_mut() { - Some(s) => s.depreciate(), - None => {} + if let Some(s) = tab.curr_list_mut() { + s.depreciate(); } } } diff --git a/src/commands/sort.rs b/src/commands/sort.rs index 93882f6..4f9601c 100644 --- a/src/commands/sort.rs +++ b/src/commands/sort.rs @@ -72,4 +72,3 @@ impl JoshutoRunnable for SortReverse { Ok(()) } } - diff --git a/src/config/keymap.rs b/src/config/keymap.rs index 328132d..e79069b 100644 --- a/src/config/keymap.rs +++ b/src/config/keymap.rs @@ -6,7 +6,7 @@ use termion::event::Key; use super::{parse_to_config_file, ConfigStructure, Flattenable}; use crate::commands::{self, CommandKeybind, JoshutoCommand}; -use crate::io::Options; +use crate::io::IOWorkerOptions; use crate::util::key_mapping::str_to_key; use crate::KEYMAP_FILE; @@ -136,7 +136,7 @@ impl JoshutoCommandMapping { let keys = [Key::Char('y'), Key::Char('y')]; insert_keycommand(&mut m, cmd, &keys)?; - let cmd = Box::new(commands::PasteFiles::new(Options::default())); + let cmd = Box::new(commands::PasteFiles::new(IOWorkerOptions::default())); let keys = [Key::Char('p'), Key::Char('p')]; insert_keycommand(&mut m, cmd, &keys)?; diff --git a/src/config/mimetype.rs b/src/config/mimetype.rs index 189dd29..9b82f08 100644 --- a/src/config/mimetype.rs +++ b/src/config/mimetype.rs @@ -2,7 +2,6 @@ use serde_derive::Deserialize; use std::collections::HashMap; use std::fmt; use std::io::Read; -use std::path::Path; use std::process; use super::{parse_config_file, ConfigStructure}; @@ -83,9 +82,10 @@ impl JoshutoMimetypeEntry { } pub fn execute_with<I, S>(&self, paths: I) -> std::io::Result<()> - where - I: IntoIterator<Item = S>, - S: AsRef<std::ffi::OsStr>, { + where + I: IntoIterator<Item = S>, + S: AsRef<std::ffi::OsStr>, + { let program = String::from(self.get_command()); let mut command = process::Command::new(program); diff --git a/src/config/theme.rs b/src/config/theme.rs index 02f9a03..fe88a5d 100644 --- a/src/config/theme.rs +++ b/src/config/theme.rs @@ -1,7 +1,7 @@ use serde_derive::Deserialize; use std::collections::HashMap; -use tui::style::{Color, Modifier, Style}; +use tui::style::{Color, Modifier}; use crate::THEME_FILE; diff --git a/src/context.rs b/src/context.rs index 6801e69..5b7e2d3 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,21 +1,62 @@ use std::collections::VecDeque; +use std::sync::mpsc; +use std::thread; use crate::config; -use crate::io::IOWorkerThread; +use crate::io::{IOWorkerObserver, IOWorkerThread}; use crate::tab::JoshutoTab; -use crate::util::event::Events; +use crate::util::event::{Event, Events}; + +pub struct JoshutoContextWorker { + queue: VecDeque<IOWorkerThread>, + pub observer: Option<IOWorkerObserver>, +} + +impl JoshutoContextWorker { + pub fn is_empty(&self) -> bool { + sel |