summaryrefslogtreecommitdiffstats
path: root/src/commands/rename_file.rs
diff options
context:
space:
mode:
authorJiayi Zhao <jeff.no.zhao@gmail.com>2019-05-27 08:11:16 -0400
committerJiayi Zhao <jeff.no.zhao@gmail.com>2019-05-27 08:11:16 -0400
commit35579905606926893d4e7c0f3f58096c5b581444 (patch)
tree383c1283617c6deddf0d6263a1f61f5ebcaccd1d /src/commands/rename_file.rs
parentecc16f39e5c146e47e37bb327e86f97b7ade1ef9 (diff)
refactor rename and search to make use of the command line
- update all other commands that make use of textfield to use new interface
Diffstat (limited to 'src/commands/rename_file.rs')
-rw-r--r--src/commands/rename_file.rs237
1 files changed, 159 insertions, 78 deletions
diff --git a/src/commands/rename_file.rs b/src/commands/rename_file.rs
index 558ce74..a5ec420 100644
--- a/src/commands/rename_file.rs
+++ b/src/commands/rename_file.rs
@@ -1,30 +1,31 @@
use std::path;
-use crate::commands::{JoshutoCommand, JoshutoRunnable};
+use crate::commands::{CommandLine, JoshutoCommand, JoshutoRunnable};
use crate::context::JoshutoContext;
use crate::error::JoshutoError;
-use crate::textfield::JoshutoTextField;
-use crate::ui;
use crate::window::JoshutoView;
-#[derive(Clone, Debug)]
-pub enum RenameFileMethod {
- Append,
- Prepend,
- Overwrite,
-}
+use rustyline::completion::{escape, Quote};
+
+#[cfg(unix)]
+static DEFAULT_BREAK_CHARS: [u8; 18] = [
+ b' ', b'\t', b'\n', b'"', b'\\', b'\'', b'`', b'@', b'$', b'>', b'<', b'=', b';', b'|', b'&',
+ b'{', b'(', b'\0',
+];
+#[cfg(unix)]
+static ESCAPE_CHAR: Option<char> = Some('\\');
#[derive(Clone, Debug)]
pub struct RenameFile {
- method: RenameFileMethod,
+ path: path::PathBuf,
}
impl RenameFile {
- pub fn new(method: RenameFileMethod) -> Self {
- RenameFile { method }
+ pub fn new(path: path::PathBuf) -> Self {
+ RenameFile { path }
}
pub const fn command() -> &'static str {
- "rename_file"
+ "rename"
}
pub fn rename_file(
@@ -32,65 +33,20 @@ impl RenameFile {
path: &path::PathBuf,
context: &mut JoshutoContext,
view: &JoshutoView,
- initial: String,
) -> Result<(), std::io::Error> {
- const PROMPT: &str = ":rename_file ";
- let (term_rows, term_cols) = ui::getmaxyx();
- let user_input: Option<String> = {
- let prefix: String;
- let suffix: String;
- match self.method {
- RenameFileMethod::Append => {
- if let Some(ext) = initial.rfind('.') {
- prefix = String::from(&initial[0..ext]);
- suffix = String::from(&initial[ext..]);
- } else {
- prefix = initial;
- suffix = String::new();
- }
- }
- RenameFileMethod::Prepend => {
- prefix = String::new();
- suffix = initial;
- }
- RenameFileMethod::Overwrite => {
- prefix = String::new();
- suffix = String::new();
- }
- }
- let textfield = JoshutoTextField::new(
- 1,
- term_cols,
- (term_rows as usize - 1, 0),
- PROMPT.to_string(),
- prefix,
- suffix,
- );
- textfield.readline()
- };
-
- if let Some(s) = user_input {
- let mut new_path = path.parent().unwrap().to_path_buf();
-
- new_path.push(s);
- if new_path.exists() {
- let err = std::io::Error::new(
- std::io::ErrorKind::AlreadyExists,
- "Filename already exists",
- );
- return Err(err);
- }
- std::fs::rename(&path, &new_path)?;
- let curr_tab = &mut context.tabs[context.curr_tab_index];
- curr_tab
- .curr_list
- .update_contents(&context.config_t.sort_option)?;
- curr_tab.refresh_curr(&view.mid_win, context.config_t.scroll_offset);
- curr_tab.refresh_preview(&view.right_win, &context.config_t);
- } else {
- let curr_tab = &context.tabs[context.curr_tab_index];
- curr_tab.refresh_file_status(&view.bot_win);
+ let new_path = &self.path;
+ if new_path.exists() {
+ let err =
+ std::io::Error::new(std::io::ErrorKind::AlreadyExists, "Filename already exists");
+ return Err(err);
}
+ std::fs::rename(&path, &new_path)?;
+ let curr_tab = &mut context.tabs[context.curr_tab_index];
+ curr_tab
+ .curr_list
+ .update_contents(&context.config_t.sort_option)?;
+ curr_tab.refresh_curr(&view.mid_win, context.config_t.scroll_offset);
+ curr_tab.refresh_preview(&view.right_win, &context.config_t);
Ok(())
}
}
@@ -110,22 +66,147 @@ impl JoshutoRunnable for RenameFile {
view: &JoshutoView,
) -> Result<(), JoshutoError> {
let mut path: Option<path::PathBuf> = None;
- let mut file_name: Option<String> = None;
let curr_list = &context.tabs[context.curr_tab_index].curr_list;
if let Some(s) = curr_list.get_curr_ref() {
path = Some(s.path.clone());
- file_name = Some(s.file_name_as_string.clone());
}
+ if let Some(path) = path {
+ match self.rename_file(&path, context, view) {
+ Ok(_) => {}
+ Err(e) => return Err(JoshutoError::IO(e)),
+ }
+ ncurses::doupdate();
+ }
+ Ok(())
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct RenameFileAppend;
+
+impl RenameFileAppend {
+ pub fn new() -> Self {
+ RenameFileAppend {}
+ }
+ pub const fn command() -> &'static str {
+ "rename_append"
+ }
+
+ pub fn rename_file(
+ &self,
+ context: &mut JoshutoContext,
+ view: &JoshutoView,
+ file_name: String,
+ ) -> Result<(), JoshutoError> {
+ let prefix;
+ let suffix;
+ if let Some(ext) = file_name.rfind('.') {
+ prefix = format!("rename {}", &file_name[0..ext]);
+ suffix = String::from(&file_name[ext..]);
+ } else {
+ prefix = format!("rename {}", file_name);
+ suffix = String::new();
+ }
+
+ let command = CommandLine::new(prefix, suffix);
+ command.readline(context, view)
+ }
+}
+
+impl JoshutoCommand for RenameFileAppend {}
+
+impl std::fmt::Display for RenameFileAppend {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(f, "{}", Self::command())
+ }
+}
+
+impl JoshutoRunnable for RenameFileAppend {
+ fn execute(
+ &self,
+ context: &mut JoshutoContext,
+ view: &JoshutoView,
+ ) -> Result<(), JoshutoError> {
+ let curr_list = &context.tabs[context.curr_tab_index].curr_list;
+ let file_name = match curr_list.get_curr_ref() {
+ Some(s) => {
+ let escaped = escape(
+ s.file_name_as_string.clone(),
+ ESCAPE_CHAR,
+ &DEFAULT_BREAK_CHARS,
+ Quote::None,
+ );
+ Some(escaped)
+ }
+ None => None,
+ };
+
if let Some(file_name) = file_name {
- if let Some(path) = path {
- match self.rename_file(&path, context, view, file_name.clone()) {
- Ok(_) => {}
- Err(e) => return Err(JoshutoError::IO(e)),
- }
- ncurses::doupdate();
+ self.rename_file(context, view, file_name)?;
+ ncurses::doupdate();
+ }
+ Ok(())
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct RenameFilePrepend;
+
+impl RenameFilePrepend {
+ pub fn new() -> Self {
+ RenameFilePrepend {}
+ }
+ pub const fn command() -> &'static str {
+ "rename_prepend"
+ }
+
+ pub fn rename_file(
+ &self,
+ context: &mut JoshutoContext,
+ view: &JoshutoView,
+ file_name: String,
+ ) -> Result<(), JoshutoError> {
+ let prefix = String::from("rename ");
+ let suffix = file_name;
+
+ let command = CommandLine::new(prefix, suffix);
+ command.readline(context, view)
+ }
+}
+
+impl JoshutoCommand for RenameFilePrepend {}
+
+impl std::fmt::Display for RenameFilePrepend {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(f, "{}", Self::command())
+ }
+}
+
+impl JoshutoRunnable for RenameFilePrepend {
+ fn execute(
+ &self,
+ context: &mut JoshutoContext,
+ view: &JoshutoView,
+ ) -> Result<(), JoshutoError> {
+ let curr_list = &context.tabs[context.curr_tab_index].curr_list;
+ let file_name = match curr_list.get_curr_ref() {
+ Some(s) => {
+ let escaped = escape(
+ s.file_name_as_string.clone(),
+ ESCAPE_CHAR,
+ &DEFAULT_BREAK_CHARS,
+ Quote::None,
+ );
+ Some(escaped)
}
+ None => None,
+ };
+
+ if let Some(file_name) = file_name {
+ self.rename_file(context, view, file_name)?;
+ ncurses::doupdate();
}
Ok(())
}