diff --git a/CHANGELOG.md b/CHANGELOG.md index 088c0c1..42ac483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,9 @@ FIXME: Released on - Enhancements: - Replaced `sha256` sum with last modification time check, to verify if a file has been changed in the text editor - Default protocol changed to default protocol in configuration when providing address as CLI argument -- dependencies: +- Keybindings: + - `N`: New file +- Dependencies: - removed `data-encoding` - updated `rand` to `0.8.0` - removed `ring` diff --git a/README.md b/README.md index f963ec3..42c1a0c 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,7 @@ You can access the SSH key storage, from configuration moving to the `SSH Keys` | `` | Show help | Help | | `` | Show info about selected file or directory | Info | | `` | Reload current directory's content | List | +| `` | Create new file with provided name | New | | `` | Edit file; see [Text editor](#text-editor-) | Open | | `` | Quit TermSCP | Quit | | `` | Rename file | Rename | diff --git a/src/ui/activities/filetransfer_activity/callbacks.rs b/src/ui/activities/filetransfer_activity/callbacks.rs index e6330a2..15a83a7 100644 --- a/src/ui/activities/filetransfer_activity/callbacks.rs +++ b/src/ui/activities/filetransfer_activity/callbacks.rs @@ -19,8 +19,9 @@ * */ +// Locals use super::{FileExplorerTab, FileTransferActivity, FsEntry, LogLevel}; - +// Ext use std::path::PathBuf; impl FileTransferActivity { @@ -371,4 +372,98 @@ impl FileTransferActivity { } } } + + /// ### callback_new_file + /// + /// Create a new file in current directory with `input` as name + pub(super) fn callback_new_file(&mut self, input: String) { + match self.tab { + FileExplorerTab::Local => { + // Check if file exists + for file in self.local.files.iter() { + if input == file.get_name() { + self.log_and_alert( + LogLevel::Warn, + format!("File \"{}\" already exists", input,), + ); + return; + } + } + // Create file + let file_path: PathBuf = PathBuf::from(input.as_str()); + if let Some(ctx) = self.context.as_mut() { + if let Err(err) = ctx.local.open_file_write(file_path.as_path()) { + self.log_and_alert( + LogLevel::Error, + format!("Could not create file \"{}\": {}", file_path.display(), err), + ); + } + // Reload files + let path: PathBuf = self.local.wrkdir.clone(); + self.local_scan(path.as_path()); + } + } + FileExplorerTab::Remote => { + // Check if file exists + for file in self.remote.files.iter() { + if input == file.get_name() { + self.log_and_alert( + LogLevel::Warn, + format!("File \"{}\" already exists", input,), + ); + return; + } + } + // Get path on remote + let file_path: PathBuf = PathBuf::from(input.as_str()); + // Create file (on local) + match tempfile::NamedTempFile::new() { + Err(err) => self.log_and_alert( + LogLevel::Error, + format!("Could not create tempfile: {}", err), + ), + Ok(tfile) => { + // Stat tempfile + if let Some(ctx) = self.context.as_mut() { + let local_file: FsEntry = match ctx.local.stat(tfile.path()) { + Err(err) => { + self.log_and_alert( + LogLevel::Error, + format!("Could not stat tempfile: {}", err), + ); + return; + } + Ok(f) => f, + }; + if let FsEntry::File(local_file) = local_file { + // Create file + match self.client.send_file(&local_file, file_path.as_path()) { + Err(err) => self.log_and_alert( + LogLevel::Error, + format!( + "Could not create file \"{}\": {}", + file_path.display(), + err + ), + ), + Ok(writer) => { + // Finalize write + if let Err(err) = self.client.on_sent(writer) { + self.log_and_alert( + LogLevel::Warn, + format!("Could not finalize file: {}", err), + ); + } + // Reload files + let path: PathBuf = self.remote.wrkdir.clone(); + self.remote_scan(path.as_path()); + } + } + } + } + } + } + } + } + } } diff --git a/src/ui/activities/filetransfer_activity/input.rs b/src/ui/activities/filetransfer_activity/input.rs index 2455b58..af5b4d7 100644 --- a/src/ui/activities/filetransfer_activity/input.rs +++ b/src/ui/activities/filetransfer_activity/input.rs @@ -228,6 +228,13 @@ impl FileTransferActivity { let pwd: PathBuf = self.local.wrkdir.clone(); self.local_scan(pwd.as_path()); } + 'n' | 'N' => { + // New file + self.input_mode = InputMode::Popup(PopupType::Input( + String::from("New file"), + Self::callback_new_file, + )); + } 'o' | 'O' => { // Edit local file if self.local.files.get(self.local.index).is_some() { @@ -446,6 +453,13 @@ impl FileTransferActivity { // Reload file entries self.reload_remote_dir(); } + 'n' | 'N' => { + // New file + self.input_mode = InputMode::Popup(PopupType::Input( + String::from("New file"), + Self::callback_new_file, + )); + } 'o' | 'O' => { // Edit remote file if self.remote.files.get(self.remote.index).is_some() {