diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2022-07-18 12:06:49 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2022-07-18 12:06:49 -0400 |
commit | 743354da056c65c6ce0910394230270ef793d8cc (patch) | |
tree | 22795339118dfdf2e819a03fa3b8081d87226339 | |
parent | eb8b155329b2c2689cc5b854f0b87f4448485c66 (diff) |
asynchronize delete operation
-rw-r--r-- | src/commands/delete_files.rs | 70 | ||||
-rw-r--r-- | src/commands/file_ops.rs | 10 | ||||
-rw-r--r-- | src/context/local_state.rs | 8 | ||||
-rw-r--r-- | src/context/worker_context.rs | 6 | ||||
-rw-r--r-- | src/event/app_event.rs | 6 | ||||
-rw-r--r-- | src/event/process_event.rs | 26 | ||||
-rw-r--r-- | src/io/file_operation.rs | 81 | ||||
-rw-r--r-- | src/io/io_observer.rs | 11 | ||||
-rw-r--r-- | src/io/io_worker.rs | 266 | ||||
-rw-r--r-- | src/io/mod.rs | 6 | ||||
-rw-r--r-- | src/key_command/command.rs | 4 | ||||
-rw-r--r-- | src/key_command/impl_comment.rs | 5 | ||||
-rw-r--r-- | src/key_command/impl_from_str.rs | 4 | ||||
-rw-r--r-- | src/ui/widgets/tui_worker.rs | 12 |
14 files changed, 279 insertions, 236 deletions
diff --git a/src/commands/delete_files.rs b/src/commands/delete_files.rs index b702771..c56118d 100644 --- a/src/commands/delete_files.rs +++ b/src/commands/delete_files.rs @@ -1,63 +1,14 @@ -use std::fs; use std::path; use termion::event::Key; use crate::context::AppContext; use crate::history::DirectoryHistory; +use crate::io::{FileOperation, FileOperationOptions, IoWorkerThread}; use crate::ui::widgets::TuiPrompt; use crate::ui::AppBackend; -use super::reload; - -fn trash_error_to_io_error(err: trash::Error) -> std::io::Error { - match err { - trash::Error::Unknown { description } => { - std::io::Error::new(std::io::ErrorKind::Other, description) - } - trash::Error::TargetedRoot => { - std::io::Error::new(std::io::ErrorKind::Other, "Targeted Root") - } - _ => std::io::Error::new(std::io::ErrorKind::Other, "Unknown Error"), - } -} - -pub fn remove_files<P>(paths: &[P]) -> std::io::Result<()> -where - P: AsRef<path::Path>, -{ - for path in paths { - if let Ok(metadata) = fs::symlink_metadata(path) { - if metadata.is_dir() { - fs::remove_dir_all(&path)?; - } else { - fs::remove_file(&path)?; - } - } - } - Ok(()) -} - -pub fn trash_files<P>(paths: &[P]) -> std::io::Result<()> -where - P: AsRef<path::Path>, -{ - for path in paths { - if let Err(e) = trash::delete(path) { - return Err(trash_error_to_io_error(e)); - } - } - Ok(()) -} - fn delete_files(context: &mut AppContext, backend: &mut AppBackend) -> std::io::Result<()> { - let delete_func = if context.config_ref().use_trash { - trash_files - } else { - remove_files - }; - - let tab_index = context.tab_context_ref().index; let paths = context .tab_context_ref() .curr_tab_ref() @@ -92,17 +43,16 @@ fn delete_files(context: &mut AppContext, backend: &mut AppBackend) -> std::io:: true }; if confirm_delete { - delete_func(&paths)?; + let file_op = FileOperation::Delete; + let options = FileOperationOptions { + overwrite: false, + skip_exist: false, + permanently: !context.config_ref().use_trash, + }; - // remove directory previews - for tab in context.tab_context_mut().iter_mut() { - for p in &paths { - tab.history_mut().remove(p.as_path()); - } - } - reload::reload(context, tab_index)?; - let msg = format!("Deleted {} files", paths_len); - context.message_queue_mut().push_success(msg); + let dest = path::PathBuf::new(); + let worker_thread = IoWorkerThread::new(file_op, paths, dest, options); + context.worker_context_mut().push_worker(worker_thread); } Ok(()) } diff --git a/src/commands/file_ops.rs b/src/commands/file_ops.rs index 9e9498d..ce9b787 100644 --- a/src/commands/file_ops.rs +++ b/src/commands/file_ops.rs @@ -3,9 +3,7 @@ use std::process::Command; use crate::context::{AppContext, LocalStateContext}; use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult}; -use crate::io::FileOp; - -use crate::io::{IoWorkerOptions, IoWorkerThread}; +use crate::io::{FileOperation, FileOperationOptions, IoWorkerThread}; pub fn cut(context: &mut AppContext) -> JoshutoResult { if let Some(list) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { @@ -13,7 +11,7 @@ pub fn cut(context: &mut AppContext) -> JoshutoResult { let mut local_state = LocalStateContext::new(); local_state.set_paths(selected.into_iter()); - local_state.set_file_op(FileOp::Cut); + local_state.set_file_op(FileOperation::Cut); context.set_local_state(local_state); } @@ -26,14 +24,14 @@ pub fn copy(context: &mut AppContext) -> JoshutoResult { let mut local_state = LocalStateContext::new(); local_state.set_paths(selected.into_iter()); - local_state.set_file_op(FileOp::Copy); + local_state.set_file_op(FileOperation::Copy); context.set_local_state(local_state); } Ok(()) } -pub fn paste(context: &mut AppContext, options: IoWorkerOptions) -> JoshutoResult { +pub fn paste(context: &mut AppContext, options: FileOperationOptions) -> JoshutoResult { match context.take_local_state() { Some(state) if !state.paths.is_empty() => { let dest = context.tab_context_ref().curr_tab_ref().cwd().to_path_buf(); diff --git a/src/context/local_state.rs b/src/context/local_state.rs index 71ca8f4..049d90d 100644 --- a/src/context/local_state.rs +++ b/src/context/local_state.rs @@ -1,22 +1,22 @@ -use crate::io::FileOp; +use crate::io::FileOperation; use std::iter::Iterator; use std::path; pub struct LocalStateContext { pub paths: Vec<path::PathBuf>, - pub file_op: FileOp, + pub file_op: FileOperation, } impl LocalStateContext { pub fn new() -> Self { Self { paths: Vec::new(), - file_op: FileOp::Copy, + file_op: FileOperation::Copy, } } - pub fn set_file_op(&mut self, operation: FileOp) { + pub fn set_file_op(&mut self, operation: FileOperation) { self.file_op = operation; } diff --git a/src/context/worker_context.rs b/src/context/worker_context.rs index fdd76fa..5bdf055 100644 --- a/src/context/worker_context.rs +++ b/src/context/worker_context.rs @@ -4,7 +4,7 @@ use std::sync::mpsc; use std::thread; use crate::event::AppEvent; -use crate::io::{IoWorkerObserver, IoWorkerProgress, IoWorkerThread}; +use crate::io::{FileOperationProgress, IoWorkerObserver, IoWorkerThread}; pub struct WorkerContext { // forks of applications @@ -49,7 +49,7 @@ impl WorkerContext { self.worker.as_ref() } - pub fn set_progress(&mut self, res: IoWorkerProgress) { + pub fn set_progress(&mut self, res: FileOperationProgress) { if let Some(s) = self.worker.as_mut() { s.set_progress(res); } @@ -77,7 +77,7 @@ impl WorkerContext { let worker_handle = thread::spawn(move || worker.start(wtx)); // relay worker info to event loop while let Ok(progress) = wrx.recv() { - let _ = tx.send(AppEvent::IoWorkerProgress(progress)); + let _ = tx.send(AppEvent::FileOperationProgress(progress)); } let result = worker_handle.join(); diff --git a/src/event/app_event.rs b/src/event/app_event.rs index fd232f6..a22b0f7 100644 --- a/src/event/app_event.rs +++ b/src/event/app_event.rs @@ -11,7 +11,7 @@ use termion::event::Event; use termion::input::TermRead; use crate::fs::JoshutoDirList; -use crate::io::IoWorkerProgress; +use crate::io::FileOperationProgress; use crate::preview::preview_file::FilePreview; #[derive(Debug)] @@ -21,8 +21,8 @@ pub enum AppEvent { // background IO worker events IoWorkerCreate, - IoWorkerProgress(IoWorkerProgress), - IoWorkerResult(io::Result<IoWorkerProgress>), + FileOperationProgress(FileOperationProgress), + IoWorkerResult(io::Result<FileOperationProgress>), // forked process events ChildProcessComplete(u32), diff --git a/src/event/process_event.rs b/src/event/process_event.rs index bf587a3..f8fe41a 100644 --- a/src/event/process_event.rs +++ b/src/event/process_event.rs @@ -11,7 +11,7 @@ use crate::context::AppContext; use crate::event::AppEvent; use crate::fs::JoshutoDirList; use crate::history::DirectoryHistory; -use crate::io::{FileOp, IoWorkerProgress}; +use crate::io::{FileOperation, FileOperationProgress}; use crate::key_command::{AppExecute, Command, CommandKeybind}; use crate::preview::preview_file::FilePreview; use crate::ui; @@ -56,7 +56,7 @@ pub fn get_input_while_composite<'a>( pub fn process_noninteractive(event: AppEvent, context: &mut AppContext) { match event { AppEvent::IoWorkerCreate => process_new_worker(context), - AppEvent::IoWorkerProgress(res) => process_worker_progress(context, res), + AppEvent::FileOperationProgress(res) => process_worker_progress(context, res), AppEvent::IoWorkerResult(res) => process_finished_worker(context, res), AppEvent::PreviewDir(Ok(dirlist)) => process_dir_preview(context, dirlist), AppEvent::PreviewFile(path, file_preview) => { @@ -81,13 +81,16 @@ pub fn process_new_worker(context: &mut AppContext) { } } -pub fn process_worker_progress(context: &mut AppContext, res: IoWorkerProgress) { +pub fn process_worker_progress(context: &mut AppContext, res: FileOperationProgress) { let worker_context = context.worker_context_mut(); worker_context.set_progress(res); worker_context.update_msg(); } -pub fn process_finished_worker(context: &mut AppContext, res: std::io::Result<IoWorkerProgress>) { +pub fn process_finished_worker( + context: &mut AppContext, + res: std::io::Result<FileOperationProgress>, +) { let worker_context = context.worker_context_mut(); let observer = worker_context.remove_worker().unwrap(); let options = context.config_ref().display_options_ref().clone(); @@ -95,12 +98,23 @@ pub fn process_finished_worker(context: &mut AppContext, res: std::io::Result<Io let _ = tab.history_mut().reload(observer.dest_path(), &options); let _ = tab.history_mut().reload(observer.src_path(), &options); } + + /* delete + // remove directory previews + for tab in context.tab_context_mut().iter_mut() { + for p in &paths { + tab.history_mut().remove(p.as_path()); + } + } + */ + observer.join(); match res { Ok(progress) => { let op = match progress.kind() { - FileOp::Copy => "copied", - FileOp::Cut => "moved", + FileOperation::Cut => "moved", + FileOperation::Copy => "copied", + FileOperation::Delete => "deleted", }; let processed_size = format::file_size_to_string(progress.bytes_processed()); let total_size = format::file_size_to_string(progress.total_bytes()); diff --git a/src/io/file_operation.rs b/src/io/file_operation.rs new file mode 100644 index 0000000..a0000f7 --- /dev/null +++ b/src/io/file_operation.rs @@ -0,0 +1,81 @@ +#[derive(Clone, Copy, Debug)] +pub enum FileOperation { + Cut, + Copy, + Delete, +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct FileOperationOptions { + // cut, copy + pub overwrite: bool, + pub skip_exist: bool, + + // delete + pub permanently: bool, +} + +impl std::fmt::Display for FileOperationOptions { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "overwrite={} skip_exist={}", + self.overwrite, self.skip_exist + ) + } +} + +#[derive(Clone, Debug)] +pub struct FileOperationProgress { + _kind: FileOperation, + _files_processed: usize, + _total_files: usize, + _bytes_processed: u64, + _total_bytes: u64, +} + +impl FileOperationProgress { + pub fn new( + _kind: FileOperation, + _files_processed: usize, + _total_files: usize, + _bytes_processed: u64, + _total_bytes: u64, + ) -> Self { + Self { + _kind, + _files_processed, + _total_files, + _bytes_processed, + _total_bytes, + } + } + + pub fn kind(&self) -> FileOperation { + self._kind + } + + pub fn files_processed(&self) -> usize { + self._files_processed + } + + pub fn set_files_processed(&mut self, files_processed: usize) { + self._files_processed = files_processed; + } + + pub fn total_files(&self) -> usize { + self._total_files + } + + pub fn bytes_processed(&self) -> u64 { + self._bytes_processed + } + + pub fn set_bytes_processed(&mut self, _bytes_processed: u64) { + self._bytes_processed = _bytes_processed; + } + + pub fn total_bytes(&self) -> u64 { + self._total_bytes + } +} diff --git a/src/io/io_observer.rs b/src/io/io_observer.rs index 4e9d3af..2df4842 100644 --- a/src/io/io_observer.rs +++ b/src/io/io_observer.rs @@ -1,13 +1,13 @@ use std::path; use std::thread; -use crate::io::{FileOp, IoWorkerProgress}; +use crate::io::{FileOperation, FileOperationProgress}; use crate::util::format; #[derive(Debug)] pub struct IoWorkerObserver { pub handle: thread::JoinHandle<()>, - pub progress: Option<IoWorkerProgress>, + pub progress: Option<FileOperationProgress>, msg: String, src: path::PathBuf, dest: path::PathBuf, @@ -27,7 +27,7 @@ impl IoWorkerObserver { pub fn join(self) -> bool { matches!(self.handle.join(), Ok(_)) } - pub fn set_progress(&mut self, progress: IoWorkerProgress) { + pub fn set_progress(&mut self, progress: FileOperationProgress) { self.progress = Some(progress); } pub fn update_msg(&mut self) { @@ -35,8 +35,9 @@ impl IoWorkerObserver { None => {} Some(progress) => { let op_str = match progress.kind() { - FileOp::Cut => "Moving", - FileOp::Copy => "Copying", + FileOperation::Cut => "Moving", + FileOperation::Copy => "Copying", + FileOperation::Delete => "Deleting", }; let processed_size = format::file_size_to_string(progress.bytes_processed()); let total_size = format::file_size_to_string(progress.total_bytes()); diff --git a/src/io/io_worker.rs b/src/io/io_worker.rs index 505e524..50d8035 100644 --- a/src/io/io_worker.rs +++ b/src/io/io_worker.rs @@ -4,99 +4,23 @@ use std::io; use std::path; use std::sync::mpsc; +use crate::io::{FileOperation, FileOperationOptions, FileOperationProgress}; use crate::util::name_resolution::rename_filename_conflict; -#[derive(Clone, Copy, Debug)] -pub enum FileOp { - Cut, - Copy, -} - -#[derive(Clone, Copy, Debug, Default)] -pub struct IoWorkerOptions { - pub overwrite: bool, - pub skip_exist: bool, -} - -impl std::fmt::Display for IoWorkerOptions { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "overwrite={} skip_exist={}", - self.overwrite, self.skip_exist - ) - } -} - -#[derive(Clone, Debug)] -pub struct IoWorkerProgress { - _kind: FileOp, - _files_processed: usize, - _total_files: usize, - _bytes_processed: u64, - _total_bytes: u64, -} - -impl IoWorkerProgress { - pub fn new( - _kind: FileOp, - _files_processed: usize, - _total_files: usize, - _bytes_processed: u64, - _total_bytes: u64, - ) -> Self { - Self { - _kind, - _files_processed, - _total_files, - _bytes_processed, - _total_bytes, - } - } - - pub fn kind(&self) -> FileOp { - self._kind - } - - pub fn files_processed(&self) -> usize { - self._files_processed - } - - pub fn set_files_processed(&mut self, files_processed: usize) { - self._files_processed = files_processed; - } - - pub fn total_files(&self) -> usize { - self._total_files - } - - pub fn bytes_processed(&self) -> u64 { - self._bytes_processed - } - - pub fn set_bytes_processed(&mut self, _bytes_processed: u64) { - self._bytes_processed = _bytes_processed; - } - - pub fn total_bytes(&self) -> u64 { - self._total_bytes - } -} - #[derive(Clone, Debug)] pub struct IoWorkerThread { - _kind: FileOp, - pub options: IoWorkerOptions, + _kind: FileOperation, + pub options: FileOperationOptions, pub paths: Vec<path::PathBuf>, pub dest: path::PathBuf, } impl IoWorkerThread { pub fn new( - _kind: FileOp, + _kind: FileOperation, paths: Vec<path::PathBuf>, dest: path::PathBuf, - options: IoWorkerOptions, + options: FileOperationOptions, ) -> Self { Self { _kind, @@ -106,88 +30,118 @@ impl IoWorkerThread { } } - pub fn kind(&self) -> FileOp { + pub fn kind(&self) -> FileOperation { self._kind } - pub fn start(&self, tx: mpsc::Sender<IoWorkerProgress>) -> io::Result<IoWorkerProgress> { + pub fn start( + &self, + tx: mpsc::Sender<FileOperationProgress>, + ) -> io::Result<FileOperationProgress> { match self.kind() { - FileOp::Cut => self.paste_cut(tx), - FileOp::Copy => self.paste_copy(tx), + FileOperation::Cut => self.paste_cut(tx), + FileOperation::Copy => self.paste_copy(tx), + FileOperation::Delete => self.delete(tx), } } - fn query_number_of_items(&self) -> io::Result<(usize, u64)> { - let mut total_bytes = 0; - let mut total_files = 0; - - let mut dirs: VecDeque<path::PathBuf> = VecDeque::new(); - for path in self.paths.iter() { - let metadata = path.symlink_metadata()?; - if metadata.is_dir() { - dirs.push_back(path.clone()); - } else { - let metadata = path.symlink_metadata()?; - total_bytes += metadata.len(); - total_files += 1; - } - } - - while let Some(dir) = dirs.pop_front() { - for entry in fs::read_dir(dir)? { - let path = entry?.path(); - if path.is_dir() { - dirs.push_back(path); - } else { - let metadata = path.symlink_metadata()?; - total_bytes += metadata.len(); - total_files += 1; - } - } - } - Ok((total_files, total_bytes)) - } - - fn paste_copy(&self, tx: mpsc::Sender<IoWorkerProgress>) -> io::Result<IoWorkerProgress> { - let (total_files, total_bytes) = self.query_number_of_items()?; - let mut progress = IoWorkerProgress::new(self.kind(), 0, total_files, 0, total_bytes); + fn paste_copy( + &self, + tx: mpsc::Sender<FileOperationProgress>, + ) -> io::Result<FileOperationProgress> { + let (total_files, total_bytes) = query_number_of_items(&self.paths)?; + let mut progress = FileOperationProgress::new(self.kind(), 0, total_files, 0, total_bytes); for path in self.paths.iter() { let _ = tx.send(progress.clone()); recursive_copy( - self.options, + &tx, path.as_path(), self.dest.as_path(), - tx.clone(), + self.options, &mut progress, )?; } Ok(progress) } - fn paste_cut(&self, tx: mpsc::Sender<IoWorkerProgress>) -> io::Result<IoWorkerProgress> { - let (total_files, total_bytes) = self.query_number_of_items()?; - let mut progress = IoWorkerProgress::new(self.kind(), 0, total_files, 0, total_bytes); + fn paste_cut( + &self, + tx: mpsc::Sender<FileOperationProgress>, + ) -> io::Result<FileOperationProgress> { + let (total_files, total_bytes) = query_number_of_items(&self.paths)?; + let mut progress = FileOperationProgress::new( + self.kind(), + total_files, + total_files, + total_bytes, + total_bytes, + ); for path in self.paths.iter() { let _ = tx.send(progress.clone()); recursive_cut( - self.options, + &tx, path.as_path(), self.dest.as_path(), - tx.clone(), + self.options, &mut progress, )?; } Ok(progress) } + + fn delete( + &self, + _tx: mpsc::Sender<FileOperationProgress>, + ) -> io::Result<FileOperationProgress> { + let (total_files, total_bytes) = query_number_of_items(&self.paths)?; + let progress = FileOperationProgress::new(self.kind(), 0, total_files, 0, total_bytes); + if self.options.permanently { + remove_files(&self.paths)?; + } else { + trash_files(&self.paths)?; + } + Ok(progress) + } +} + +fn query_number_of_items(paths: &[path::PathBuf]) -> io::Result<(usize, u64)> { + let mut total_bytes = 0; + let mut total_files = 0; + + let mut dirs: VecDeque<path::PathBuf> = VecDeque::new(); + for path in paths.iter() { + let metadata = path.symlink_metadata()?; + if metadata.is_dir() { + dirs.push_back(path.clone()); + } else { + let metadata = path.symlink_metadata()?; + total_bytes += metadata.len(); + total_files += 1; + } + } + + while let Some(dir) = dirs.pop_front() { + for entry in fs::read_dir(dir)? { + let path = entry?.path(); + if path.is_dir() { + dirs.push_back(path); + } else { + let metadata = path.symlink_metadata()?; + total_bytes += metadata.len(); + total_files += 1; + } + } + } + Ok((total_files, total_bytes)) } pub fn recursive_copy( - options: IoWorkerOptions, + tx: &mpsc::Sender<FileOperationProgress>, src: &path::Path, dest: &path::Path, - tx: mpsc::Sender<IoWorkerProgress>, - progress: &mut IoWorkerProgress, + options: FileOperationOptions, + progress: &mut FileOperationProgress, ) -> io::Result<()> { let mut dest_buf = dest.to_path_buf(); if let Some(s) = src.file_name() { @@ -210,10 +164,10 @@ pub fn recursive_copy( let entry = entry?; let entry_path = entry.path(); recursive_copy( - options, + tx, entry_path.as_path(), dest_buf.as_path(), - tx.clone(), + options, progress, )?; let _ = tx.send(progress.clone()); @@ -235,11 +189,11 @@ pub fn recursive_copy( } pub fn recursive_cut( - options: IoWorkerOptions, + tx: &mpsc::Sender<FileOperationProgress>, src: &path::Path, dest: &path::Path, - tx: mpsc::Sender<IoWorkerProgress>, - progress: &mut IoWorkerProgress, + options: FileOperationOptions, + progress: &mut FileOperationProgress, ) -> io::Result<()> { let mut dest_buf = dest.to_path_buf(); if let Some(s) = src.file_name() { @@ -264,10 +218,10 @@ pub fn recursive_cut( for entry in fs::read_dir(src)? { let entry_path = entry?.path(); recursive_cut( - options, + tx, entry_path.as_path(), dest_buf.as_path(), - tx.clone(), + options, progress, )?; let _ = tx.send(progress.clone()); @@ -290,3 +244,43 @@ pub fn recursive_cut( } } } + +fn trash_error_to_io_error(err: trash::Error) -> std::io::Error { + match err { + trash::Error::Unknown { description } => { + std::io::Error::new(std::io::ErrorKind::Other, description) + } + trash::Error::TargetedRoot => { + std::io::Error::new(std::io::ErrorKind::Other, "Targeted Root") + } + _ => std::io::Error::new(std::io::ErrorKind::Other, "Unknown Error"), + } +} + +fn remove_files<P>(paths: &[P]) -> std::io::Result<()> +where + P: AsRef<path::Path>, +{ + for path in paths { + if let Ok(metadata) = fs::symlink_metadata(path) { + if metadata.is_dir() { + fs::remove_dir_all(&path)?; + } else { + fs::remove_file(&path)?; + } + } + } + Ok(()) +} + +fn trash_files<P>(paths: &[P]) -> std::io::Result<()> +where + P: AsRef<path::Path>, +{ + for path in paths { + if let Err(e) = trash::delete(path) { + return Err(trash_error_to_io_error(e)); + } + } + Ok(()) +} diff --git a/src/io/mod.rs b/src/io/mod.rs index f577cc6..05f4cf8 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,5 +1,7 @@ +mod file_operation; mod io_observer; mod io_worker; -pub use io_observer::IoWorkerObserver; -pub use io_worker::{FileOp, IoWorkerOptions, IoWorkerProgress, IoWorkerThread}; +pub use file_operation::*; +pub use io_observer::*; +pub use io_worker::*; diff --git a/src/key_command/command.rs b/src/key_command/command.rs index 495cff5..4d4e0ba 100644 --- a/src/key_command/command.rs +++ b/src/key_command/command.rs @@ -2,7 +2,7 @@ use std::path; use crate::commands::quit::QuitAction; use crate::config::option::{LineNumberStyle, SelectOption, SortType}; -use crate::io::IoWorkerOptions; +use crate::io::FileOperationOptions; #[derive(Clone, Debug)] #[allow(clippy::enum_variant_names)] @@ -17,7 +17,7 @@ pub enum Command { CutFiles, CopyFiles, - PasteFiles(IoWorkerOptions), + PasteFiles(FileOperationOptions), CopyFileName, CopyFileNameWithoutExtension, CopyFilePath, diff --git a/src/key_command/impl_comment.rs b/src/key_command/impl_comment.rs index bd5e4e6..c441a6b 100644 --- a/src/key_command/impl_comment.rs +++ b/src/key_command/impl_comment.rs @@ -1,5 +1,5 @@ use crate::config::option::SortType; -use crate::io::IoWorkerOptions; +use crate::io::FileOperationOptions; use super::{Command, CommandComment}; @@ -27,9 +27,10 @@ impl CommandComment for Command { Self::CutFiles => "Cut selected files", Self::CopyFiles => "Copy selected files", - Self::PasteFiles(IoWorkerOptions { + Self::PasteFiles(FileOperationOptions { overwrite, skip_exist, + .. }) => match (overwrite, skip_exist) { (true, false) => "Paste, overwrite", (false, true) => "Paste, skip existing files", diff --git a/src/key_command/impl_from_str.rs b/src/key_command/impl_from_str.rs index c09fe66..74c92e4 100644 --- a/src/key_command/impl_from_str.rs +++ b/src/key_command/impl_from_str.rs @@ -6,7 +6,7 @@ use shellexpand::tilde_with_context; use crate::commands::quit::QuitAction; use crate::config::option::{LineNumberStyle, SelectOption, SortType}; use crate::error::{JoshutoError, JoshutoErrorKind}; -use crate::io::IoWorkerOptions; +use crate::io::FileOperationOptions; use crate::HOME_DIR; @@ -200,7 +200,7 @@ impl std::str::FromStr for Command { }, } } else if command == CMD_PASTE_FILES { - let mut options = IoWorkerOptions::default(); + let mut options = FileOperationOptions::default(); for arg in arg.split_whitespace() { match arg { "--overwrite=true" => options.overwrite = true, diff --git a/src/ui/widgets/tui_worker.rs b/src/ui/widgets/tui_worker.rs index f9e544d..06fcd7a 100644 --- a/src/ui/widgets/tui_worker.rs +++ b/src/ui/widgets/tui_worker.rs @@ -4,7 +4,7 @@ use tui::style::{Color, Modifier, Style}; use tui::widgets::Widget; use crate::context::WorkerContext; -use crate::io::FileOp; +use crate::io::FileOperation; use crate::util::format; pub struct TuiWorker<'a> { @@ -23,8 +23,9 @@ impl<'a> Widget for TuiWorker<'a> { Some(io_obs) => { if let Some(progress) = io_obs.progress.as_ref() { let op_str = match progress.kind() { - FileOp::Copy => "Copying", - FileOp::Cut => "Moving", + FileOperation::Cut => "Moving", + FileOperation::Copy => "Copying", + FileOperation::Delete => "Deleting", }; let processed_size = format::file_size_to_string(progress.bytes_processed()); @@ -61,8 +62,9 @@ impl<'a> Widget for TuiWorker<'a> { let style = Style::default(); for (i, worker) in self.context.iter().enumerate() { let op_str = match worker.kind() { - FileOp::Copy => "Copy", - FileOp::Cut => "Move", + FileOperation::Cut => "Move", + FileOperation::Copy => "Copy", + FileOperation::Delete => "Delete", }; let msg = format!( "{:02} {} {} items {:?}", |