summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/keymap.toml10
-rw-r--r--docs/README.md4
-rw-r--r--docs/configuration/keymap.toml.md2
-rw-r--r--src/commands/delete_files.rs1
-rw-r--r--src/commands/file_ops.rs13
-rw-r--r--src/event/process_event.rs1
-rw-r--r--src/io/file_operation.rs13
-rw-r--r--src/io/io_observer.rs1
-rw-r--r--src/io/io_worker.rs29
-rw-r--r--src/key_command/command.rs1
-rw-r--r--src/key_command/constants.rs5
-rw-r--r--src/key_command/impl_appcommand.rs1
-rw-r--r--src/key_command/impl_appexecute.rs2
-rw-r--r--src/key_command/impl_comment.rs1
-rw-r--r--src/key_command/impl_from_str.rs2
-rw-r--r--src/ui/widgets/tui_worker.rs8
16 files changed, 76 insertions, 18 deletions
diff --git a/config/keymap.toml b/config/keymap.toml
index bbc7705..36eef74 100644
--- a/config/keymap.toml
+++ b/config/keymap.toml
@@ -52,16 +52,16 @@ keymap = [
{ keys = [ "c", "d" ], command = ":cd " },
{ keys = [ "d", "d" ], command = "cut_files" },
{ keys = [ "y", "y" ], command = "copy_files" },
- { keys = [ "p", "p" ], command = "paste_files" },
- { keys = [ "p", "o" ], command = "paste_files --overwrite=true" },
-
{ keys = [ "y", "n" ], command = "copy_filename" },
{ keys = [ "y", "." ], command = "copy_filename_without_extension" },
{ keys = [ "y", "p" ], command = "copy_filepath" },
{ keys = [ "y", "d" ], command = "copy_dirpath" },
- { keys = [ "delete" ], command = "delete_files" },
- { keys = [ "d", "D" ], command = "delete_files" },
+ { keys = [ "delete" ], command = "delete_files --foreground=true" },
+ { keys = [ "d", "D" ], command = "delete_files --foreground=true" },
+
+ { keys = [ "p", "p" ], command = "paste_files" },
+ { keys = [ "p", "o" ], command = "paste_files --overwrite=true" },
{ keys = [ "a" ], command = "rename_append" },
{ keys = [ "A" ], command = "rename_prepend" },
diff --git a/docs/README.md b/docs/README.md
index 0a6c0b7..91d65ce 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2,6 +2,8 @@
These docs should help you get set up and understand how Joshuto works.
+ - [command line arguments](/docs/command_arguments.md)
- [configuration](/docs/configuration/)
- - [contributing](/docs/contributing.md)
+ - [image previews](/docs/image_previews.md)
- [misc](/docs/misc.md)
+ - [contributing](/docs/contributing.md)
diff --git a/docs/configuration/keymap.toml.md b/docs/configuration/keymap.toml.md
index 1086f04..e1fb758 100644
--- a/docs/configuration/keymap.toml.md
+++ b/docs/configuration/keymap.toml.md
@@ -179,8 +179,10 @@ function joshuto() {
- `mkdir`: create a new directory (usually used as `:mkdir `)
- `cut_files`: store selected files (or current file if none were selected) to be moved later
- `copy_files`: store selected files (or current file if none were selected) to be copied later
+ - `symlink_files`: store selected files (or current file if none were selected) to be symlinked later
- `paste_files`: move/copy files stored from a previous `cut_files` or `copy_files` command
- `delete_files`: delete selected files (or current file if none were selected).
+ - `--foreground=true`: will delete files in the foreground
- will ***permanently*** delete files if `use_trash` is `false` in
[joshuto.toml](https://github.com/kamiyaa/joshuto)/wiki/Configuration#joshutotoml)
- if `use_trash` is `true`, this might cause issues with deleting files
diff --git a/src/commands/delete_files.rs b/src/commands/delete_files.rs
index 272fd1a..987c45e 100644
--- a/src/commands/delete_files.rs
+++ b/src/commands/delete_files.rs
@@ -53,7 +53,6 @@ fn delete_files(
let options = FileOperationOptions {
overwrite: false,
skip_exist: false,
- symlink: false,
permanently: !context.config_ref().use_trash,
};
diff --git a/src/commands/file_ops.rs b/src/commands/file_ops.rs
index ce9b787..c50129b 100644
--- a/src/commands/file_ops.rs
+++ b/src/commands/file_ops.rs
@@ -31,6 +31,19 @@ pub fn copy(context: &mut AppContext) -> JoshutoResult {
Ok(())
}
+pub fn link(context: &mut AppContext) -> JoshutoResult {
+ if let Some(list) = context.tab_context_ref().curr_tab_ref().curr_list_ref() {
+ let selected = list.get_selected_paths();
+
+ let mut local_state = LocalStateContext::new();
+ local_state.set_paths(selected.into_iter());
+ local_state.set_file_op(FileOperation::Symlink);
+
+ context.set_local_state(local_state);
+ }
+ Ok(())
+}
+
pub fn paste(context: &mut AppContext, options: FileOperationOptions) -> JoshutoResult {
match context.take_local_state() {
Some(state) if !state.paths.is_empty() => {
diff --git a/src/event/process_event.rs b/src/event/process_event.rs
index 8eb6136..84ef44b 100644
--- a/src/event/process_event.rs
+++ b/src/event/process_event.rs
@@ -112,6 +112,7 @@ pub fn process_finished_worker(
let op = match progress.kind() {
FileOperation::Cut => "moved",
FileOperation::Copy => "copied",
+ FileOperation::Symlink => "symlinked",
FileOperation::Delete => "deleted",
};
let processed_size = format::file_size_to_string(progress.bytes_processed());
diff --git a/src/io/file_operation.rs b/src/io/file_operation.rs
index 14693ec..9d39716 100644
--- a/src/io/file_operation.rs
+++ b/src/io/file_operation.rs
@@ -2,15 +2,26 @@
pub enum FileOperation {
Cut,
Copy,
+ Symlink,
Delete,
}
+impl std::fmt::Display for FileOperation {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match self {
+ Self::Cut => write!(f, "Cut"),
+ Self::Copy => write!(f, "Copy"),
+ Self::Symlink => write!(f, "Symlink"),
+ Self::Delete => write!(f, "Delete"),
+ }
+ }
+}
+
#[derive(Clone, Copy, Debug, Default)]
pub struct FileOperationOptions {
// cut, copy
pub overwrite: bool,
pub skip_exist: bool,
- pub symlink: bool,
// delete
pub permanently: bool,
diff --git a/src/io/io_observer.rs b/src/io/io_observer.rs
index 2df4842..44d4248 100644
--- a/src/io/io_observer.rs
+++ b/src/io/io_observer.rs
@@ -37,6 +37,7 @@ impl IoWorkerObserver {
let op_str = match progress.kind() {
FileOperation::Cut => "Moving",
FileOperation::Copy => "Copying",
+ FileOperation::Symlink => "Symlinking",
FileOperation::Delete => "Deleting",
};
let processed_size = format::file_size_to_string(progress.bytes_processed());
diff --git a/src/io/io_worker.rs b/src/io/io_worker.rs
index 87c5bad..f9d86d9 100644
--- a/src/io/io_worker.rs
+++ b/src/io/io_worker.rs
@@ -4,6 +4,9 @@ use std::io;
use std::path;
use std::sync::mpsc;
+#[cfg(unix)]
+use std::os::unix;
+
use crate::io::{FileOperation, FileOperationOptions, FileOperationProgress};
use crate::util::name_resolution::rename_filename_conflict;
@@ -41,6 +44,7 @@ impl IoWorkerThread {
match self.kind() {
FileOperation::Cut => self.paste_cut(tx),
FileOperation::Copy => self.paste_copy(tx),
+ FileOperation::Symlink => self.paste_link(tx),
FileOperation::Delete => self.delete(tx),
}
}
@@ -83,6 +87,31 @@ impl IoWorkerThread {
Ok(progress)
}
+ fn paste_link(
+ &self,
+ tx: mpsc::Sender<FileOperationProgress>,
+ ) -> io::Result<FileOperationProgress> {
+ let total_files = self.paths.len();
+ let total_bytes = total_files as u64;
+ let mut progress = FileOperationProgress::new(self.kind(), 0, total_files, 0, total_bytes);
+
+ #[cfg(unix)]
+ for src in self.paths.iter() {
+ let _ = tx.send(progress.clone());
+ let mut dest_buf = self.dest.to_path_buf();
+ if let Some(s) = src.file_name() {
+ dest_buf.push(s);
+ }
+ if !self.options.overwrite {
+ rename_filename_conflict(&mut dest_buf);
+ }
+ unix::fs::symlink(src, &dest_buf)?;
+ progress.set_files_processed(progress.files_processed() + 1);
+ progress.set_bytes_processed(progress.bytes_processed() + 1);
+ }
+ Ok(progress)
+ }
+
fn delete(
&self,
_tx: mpsc::Sender<FileOperationProgress>,
diff --git a/src/key_command/command.rs b/src/key_command/command.rs
index 8d1110c..9ffbe5c 100644
--- a/src/key_command/command.rs
+++ b/src/key_command/command.rs
@@ -21,6 +21,7 @@ pub enum Command {
CopyFileNameWithoutExtension,
CopyFilePath,
CopyDirPath,
+ SymlinkFiles,
PasteFiles(FileOperationOptions),
DeleteFiles { background: bool },
diff --git a/src/key_command/constants.rs b/src/key_command/constants.rs
index ba5db2e..8dd60ed 100644
--- a/src/key_command/constants.rs
+++ b/src/key_command/constants.rs
@@ -24,7 +24,6 @@ cmd_constants![
(CMD_CLOSE_TAB, "close_tab"),
(CMD_CUT_FILES, "cut_files"),
(CMD_COPY_FILES, "copy_files"),
- (CMD_PASTE_FILES, "paste_files"),
(CMD_COPY_FILENAME, "copy_filename"),
(
CMD_COPY_FILENAME_WITHOUT_EXTENSION,
@@ -32,6 +31,9 @@ cmd_constants![
),
(CMD_COPY_FILEPATH, "copy_filepath"),
(CMD_COPY_DIRECTORY_PATH, "copy_dirpath"),
+ (CMD_SYMLINK_FILES, "symlink_files"),
+ (CMD_PASTE_FILES, "paste_files"),
+ (CMD_DELETE_FILES, "delete_files"),
(CMD_CURSOR_MOVE_UP, "cursor_move_up"),
(CMD_CURSOR_MOVE_DOWN, "cursor_move_down"),
(CMD_CURSOR_MOVE_HOME, "cursor_move_home"),
@@ -45,7 +47,6 @@ cmd_constants![
(CMD_PARENT_CURSOR_MOVE_DOWN, "parent_cursor_move_down"),
(CMD_PREVIEW_CURSOR_MOVE_UP, "preview_cursor_move_up"),
(CMD_PREVIEW_CURSOR_MOVE_DOWN, "preview_cursor_move_down"),
- (CMD_DELETE_FILES, "delete_files"),
(CMD_NEW_DIRECTORY, "mkdir"),
(CMD_OPEN_FILE, "open"),
(CMD_OPEN_FILE_WITH, "open_with"),
diff --git a/src/key_command/impl_appcommand.rs b/src/key_command/impl_appcommand.rs
index 7ea8f93..fe7dbc2 100644
--- a/src/key_command/impl_appcommand.rs
+++ b/src/key_command/impl_appcommand.rs
@@ -24,6 +24,7 @@ impl AppCommand for Command {
Self::CopyFileNameWithoutExtension => CMD_COPY_FILENAME_WITHOUT_EXTENSION,
Self::CopyFilePath => CMD_COPY_FILEPATH,
Self::CopyDirPath => CMD_COPY_DIRECTORY_PATH,
+ Self::SymlinkFiles => CMD_SYMLINK_FILES,
Self::PasteFiles(_) => CMD_PASTE_FILES,
Self::DeleteFiles { .. } => CMD_DELETE_FILES,
diff --git a/src/key_command/impl_appexecute.rs b/src/key_command/impl_appexecute.rs
index 37f0c35..cd7aacc 100644
--- a/src/key_command/impl_appexecute.rs
+++ b/src/key_command/impl_appexecute.rs
@@ -36,7 +36,7 @@ impl AppExecute for Command {
}
Self::CopyFilePath => file_ops::copy_filepath(context),
Self::CopyDirPath => file_ops::copy_dirpath(context),
-
+ Self::SymlinkFiles => file_ops::link(context),
Self::PasteFiles(options) => file_ops::paste(context, *options),
Self::DeleteFiles { background: false } => {
diff --git a/src/key_command/impl_comment.rs b/src/key_command/impl_comment.rs
index a351fed..36697c0 100644
--- a/src/key_command/impl_comment.rs
+++ b/src/key_command/impl_comment.rs
@@ -31,6 +31,7 @@ impl CommandComment for Command {
Self::CopyFileNameWithoutExtension => "Copy filename without extension",
Self::CopyFilePath => "Copy path to file",
Self::CopyDirPath => "Copy directory name",
+ Self::SymlinkFiles => "Symlink selected files",
Self::PasteFiles(FileOperationOptions {
overwrite,
diff --git a/src/key_command/impl_from_str.rs b/src/key_command/impl_from_str.rs
index 224b8d6..81b8949 100644
--- a/src/key_command/impl_from_str.rs
+++ b/src/key_command/impl_from_str.rs
@@ -55,7 +55,6 @@ impl std::str::FromStr for Command {
simple_command_conversion_case!(command, CMD_CURSOR_MOVE_PAGEEND, Self::CursorMovePageEnd);
simple_command_conversion_case!(command, CMD_CUT_FILES, Self::CutFiles);
-
simple_command_conversion_case!(command, CMD_COPY_FILES, Self::CopyFiles);
simple_command_conversion_case!(command, CMD_COPY_FILENAME, Self::CopyFileName);
simple_command_conversion_case!(
@@ -65,6 +64,7 @@ impl std::str::FromStr for Command {
);
simple_command_conversion_case!(command, CMD_COPY_FILEPATH, Self::CopyFilePath);
simple_command_conversion_case!(command, CMD_COPY_DIRECTORY_PATH, Self::CopyDirPath);
+ simple_command_conversion_case!(command, CMD_SYMLINK_FILES, Self::SymlinkFiles);
simple_command_conversion_case!(command, CMD_OPEN_FILE, Self::OpenFile);
diff --git a/src/ui/widgets/tui_worker.rs b/src/ui/widgets/tui_worker.rs
index 06fcd7a..4ac034a 100644
--- a/src/ui/widgets/tui_worker.rs
+++ b/src/ui/widgets/tui_worker.rs
@@ -25,6 +25,7 @@ impl<'a> Widget for TuiWorker<'a> {
let op_str = match progress.kind() {
FileOperation::Cut => "Moving",
FileOperation::Copy => "Copying",
+ FileOperation::Symlink => "Symlinking",
FileOperation::Delete => "Deleting",
};
@@ -61,15 +62,10 @@ impl<'a> Widget for TuiWorker<'a> {
let style = Style::default();
for (i, worker) in self.context.iter().enumerate() {
- let op_str = match worker.kind() {
- FileOperation::Cut => "Move",
- FileOperation::Copy => "Copy",
- FileOperation::Delete => "Delete",
- };
let msg = format!(
"{:02} {} {} items {:?}",
i + 1,
- op_str,
+ worker.kind(),
worker.paths.len(),
worker.dest
);