Copy feature in ui; new keybinding <C>

This commit is contained in:
ChristianVisintin
2020-12-21 11:11:29 +01:00
parent 08728bf55e
commit 3901ed54c6
6 changed files with 137 additions and 16 deletions

View File

@@ -11,7 +11,7 @@
## 0.2.0
Released on ??
Released on 21/12/2020
> The Bookmarks Update
@@ -24,6 +24,9 @@ Released on ??
- **Text Editor**
- Added text editor feature to explorer view
- Added `o` to keybindings to open a text file
- Keybindings:
- `C`: Copy file/directory
- `O`: Open text file in editor
- Enhancements:
- User interface
- Collpased borders to make everything more *aesthetic*

View File

@@ -244,6 +244,7 @@ Text editor is automatically found using this [awesome crate](https://github.com
| `<PGDOWN>` | Move down in selected list by 8 rows |
| `<ENTER>` | Enter directory |
| `<SPACE>` | Upload / download selected file |
| `<C>` | Copy file/directory |
| `<D>` | Make directory |
| `<E>` | Delete file (Same as `CANC`) |
| `<G>` | Go to supplied path |

View File

@@ -830,7 +830,7 @@ mod tests {
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
#[test]
fn test_host_copy_file() {
fn test_host_copy_file_absolute() {
let tmpdir: tempfile::TempDir = tempfile::TempDir::new().unwrap();
// Create file in tmpdir
let mut file1_path: PathBuf = PathBuf::from(tmpdir.path());
@@ -851,6 +851,28 @@ mod tests {
assert_eq!(host.files.len(), 2);
}
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
#[test]
fn test_host_copy_file_relative() {
let tmpdir: tempfile::TempDir = tempfile::TempDir::new().unwrap();
// Create file in tmpdir
let mut file1_path: PathBuf = PathBuf::from(tmpdir.path());
file1_path.push("foo.txt");
// Write file 1
let mut file1: File = File::create(file1_path.as_path()).ok().unwrap();
assert!(file1.write_all(b"Hello world!\n").is_ok());
// Get file 2 path
let file2_path: PathBuf = PathBuf::from("bar.txt");
// Create host
let mut host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap();
let file1_entry: FsEntry = host.files.get(0).unwrap().clone();
assert_eq!(file1_entry.get_name(), String::from("foo.txt"));
// Copy
assert!(host.copy(&file1_entry, file2_path.as_path()).is_ok());
// Verify host has two files
assert_eq!(host.files.len(), 2);
}
#[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))]
#[test]
fn test_hop_copy_directory_absolute() {

View File

@@ -62,6 +62,77 @@ impl FileTransferActivity {
}
}
/// ### callback_copy
///
/// Callback for COPY command (both from local and remote)
pub(super) fn callback_copy(&mut self, input: String) {
let dest_path: PathBuf = PathBuf::from(input);
match self.tab {
FileExplorerTab::Local => {
// Get selected entry
if self.local.files.get(self.local.index).is_some() {
let entry: FsEntry = self.local.files.get(self.local.index).unwrap().clone();
if let Some(ctx) = self.context.as_mut() {
match ctx.local.copy(&entry, dest_path.as_path()) {
Ok(_) => {
self.log(
LogLevel::Info,
format!(
"Copied \"{}\" to \"{}\"",
entry.get_abs_path().display(),
dest_path.display()
)
.as_str(),
);
// Reload entries
let wrkdir: PathBuf = self.local.wrkdir.clone();
self.local_scan(wrkdir.as_path());
}
Err(err) => self.log_and_alert(
LogLevel::Error,
format!(
"Could not copy \"{}\" to \"{}\": {}",
entry.get_abs_path().display(),
dest_path.display(),
err
),
),
}
}
}
}
FileExplorerTab::Remote => {
// Get selected entry
if self.remote.files.get(self.remote.index).is_some() {
let entry: FsEntry = self.remote.files.get(self.remote.index).unwrap().clone();
match self.client.as_mut().copy(&entry, dest_path.as_path()) {
Ok(_) => {
self.log(
LogLevel::Info,
format!(
"Copied \"{}\" to \"{}\"",
entry.get_abs_path().display(),
dest_path.display()
)
.as_str(),
);
self.reload_remote_dir();
}
Err(err) => self.log_and_alert(
LogLevel::Error,
format!(
"Could not copy \"{}\" to \"{}\": {}",
entry.get_abs_path().display(),
dest_path.display(),
err
),
),
}
}
}
}
}
/// ### callback_mkdir
///
/// Callback for MKDIR command (supports both local and remote)

View File

@@ -177,6 +177,20 @@ impl FileTransferActivity {
}
}
KeyCode::Char(ch) => match ch {
'c' | 'C' => {
// Copy
self.input_mode = InputMode::Popup(PopupType::Input(
String::from("Insert destination name"),
FileTransferActivity::callback_copy,
));
}
'd' | 'D' => {
// Make directory
self.input_mode = InputMode::Popup(PopupType::Input(
String::from("Insert directory name"),
FileTransferActivity::callback_mkdir,
));
}
'e' | 'E' => {
// Get file at index
if let Some(entry) = self.local.files.get(self.local.index) {
@@ -201,13 +215,6 @@ impl FileTransferActivity {
FileTransferActivity::callback_change_directory,
));
}
'd' | 'D' => {
// Make directory
self.input_mode = InputMode::Popup(PopupType::Input(
String::from("Insert directory name"),
FileTransferActivity::callback_mkdir,
));
}
'h' | 'H' => {
// Show help
self.input_mode = InputMode::Popup(PopupType::Help);
@@ -389,6 +396,20 @@ impl FileTransferActivity {
}
}
KeyCode::Char(ch) => match ch {
'c' | 'C' => {
// Copy
self.input_mode = InputMode::Popup(PopupType::Input(
String::from("Insert destination name"),
FileTransferActivity::callback_copy,
));
}
'd' | 'D' => {
// Make directory
self.input_mode = InputMode::Popup(PopupType::Input(
String::from("Insert directory name"),
FileTransferActivity::callback_mkdir,
));
}
'e' | 'E' => {
// Get file at index
if let Some(entry) = self.remote.files.get(self.remote.index) {
@@ -405,13 +426,6 @@ impl FileTransferActivity {
))
}
}
'd' | 'D' => {
// Make directory
self.input_mode = InputMode::Popup(PopupType::Input(
String::from("Insert directory name"),
FileTransferActivity::callback_mkdir,
));
}
'g' | 'G' => {
// Goto
// Show input popup

View File

@@ -716,6 +716,16 @@ impl FileTransferActivity {
Span::raw(" "),
Span::raw("Delete file"),
])),
ListItem::new(Spans::from(vec![
Span::styled(
"<C>",
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
),
Span::raw(" "),
Span::raw("Copy"),
])),
ListItem::new(Spans::from(vec![
Span::styled(
"<D>",