summaryrefslogtreecommitdiffstats
path: root/src/event_exec.rs
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2023-04-15 00:52:55 +0200
committerqkzk <qu3nt1n@gmail.com>2023-04-15 00:52:55 +0200
commit3017482632fcf862d14cacdd2f2d08a727f86af7 (patch)
tree9c59355654481c9d61059c5631ae415570b9e6fa /src/event_exec.rs
parent91f4dbf41cb30bd6b348d3d42fe585464142f32e (diff)
start event exec refactoring
Diffstat (limited to 'src/event_exec.rs')
-rw-r--r--src/event_exec.rs2076
1 files changed, 1035 insertions, 1041 deletions
diff --git a/src/event_exec.rs b/src/event_exec.rs
index 81c710f..83fb104 100644
--- a/src/event_exec.rs
+++ b/src/event_exec.rs
@@ -45,28 +45,6 @@ use crate::utils::{current_username, disk_used_by_path, filename_from_path};
pub struct EventExec {}
impl EventExec {
- /// Reset the selected tab view to the default.
- pub fn refresh_status(status: &mut Status, colors: &Colors) -> Result<()> {
- status.force_clear();
- status.refresh_users()?;
- status.selected().refresh_view()?;
- if let Mode::Tree = status.selected_non_mut().mode {
- status.selected().make_tree(colors)?
- }
- Ok(())
- }
-
- /// When a rezise event occurs, we may hide the second panel if the width
- /// isn't sufficiant to display enough information.
- /// We also need to know the new height of the terminal to start scrolling
- /// up or down.
- pub fn resize(status: &mut Status, width: usize, height: usize, colors: &Colors) -> Result<()> {
- status.set_dual_pane_if_wide_enough(width)?;
- status.selected().set_height(height);
- Self::refresh_status(status, colors)?;
- Ok(())
- }
-
/// Remove every flag on files in this directory and others.
pub fn event_clear_flags(status: &mut Status) -> Result<()> {
status.flagged.clear();
@@ -105,7 +83,7 @@ impl EventExec {
let Some(file) = tab.path_content.selected() else { return Ok(()) };
let path = file.path.clone();
status.toggle_flag_on_path(&path);
- Self::event_down_one_row(status.selected());
+ bla_down_one_row(status.selected());
}
Mode::Tree => {
let path = tab.directory.tree.current_node.filepath();
@@ -158,57 +136,6 @@ impl EventExec {
.set_mode(Mode::Navigate(Navigate::Marks(MarkAction::Jump)));
Ok(())
}
-
- /// Jump to the current mark.
- pub fn exec_marks_jump(status: &mut Status) -> Result<()> {
- let marks = status.marks.clone();
- let tab = status.selected();
- if let Some((_, path)) = marks.selected() {
- tab.history.push(path);
- tab.set_pathcontent(path)?;
- tab.window.reset(tab.path_content.content.len());
- tab.input.reset();
- }
- Ok(())
- }
-
- /// Update the selected mark with the current path.
- /// Doesn't change its char.
- /// If it doesn't fail, a new pair will be set with (oldchar, new path).
- pub fn exec_marks_update(status: &mut Status) -> Result<()> {
- let marks = status.marks.clone();
- let len = status.selected_non_mut().path_content.content.len();
- if let Some((ch, _)) = marks.selected() {
- if let Some(path_str) = status.selected_non_mut().path_content_str() {
- status.marks.new_mark(*ch, path::PathBuf::from(path_str))?;
- }
- status.selected().window.reset(len);
- status.selected().input.reset();
- }
- Ok(())
- }
-
- /// Execute a new mark, saving it to a config file for futher use.
- pub fn exec_marks_new(status: &mut Status, c: char, colors: &Colors) -> Result<()> {
- let path = status.selected().path_content.path.clone();
- status.marks.new_mark(c, path)?;
- Self::event_normal(status.selected())?;
- status.selected().reset_mode();
- Self::refresh_status(status, colors)
- }
-
- /// Execute a jump to a mark, moving to a valid path.
- /// If the saved path is invalid, it does nothing but reset the view.
- pub fn exec_marks_jump_char(status: &mut Status, c: char, colors: &Colors) -> Result<()> {
- if let Some(path) = status.marks.get(c) {
- status.selected().set_pathcontent(&path)?;
- status.selected().history.push(&path);
- }
- Self::event_normal(status.selected())?;
- status.selected().reset_mode();
- Self::refresh_status(status, colors)
- }
-
/// Creates a symlink of every flagged file to the current directory.
pub fn event_symlink(status: &mut Status) -> Result<()> {
for original_file in status.flagged.content.iter() {
@@ -233,367 +160,12 @@ impl EventExec {
status.selected().set_mode(Mode::Navigate(Navigate::Bulk));
Ok(())
}
-
- pub fn exec_bulk(status: &mut Status) -> Result<()> {
- status.bulk.execute_bulk(status)
- }
-
- pub fn exec_shellmenu(status: &mut Status) -> Result<()> {
- status.shell_menu.execute(status)
- }
-
- pub fn exec_cli_info(status: &mut Status) -> Result<()> {
- let output = status.cli_info.execute()?;
- info!("output\n{output}");
- status.selected().set_mode(Mode::Preview);
- let preview = Preview::cli_info(&output);
- status.selected().window.reset(preview.len());
- status.selected().preview = preview;
- Ok(())
- }
-
- /// Copy the flagged file to current directory.
- /// A progress bar is displayed and a notification is sent once it's done.
- pub fn exec_copy_paste(status: &mut Status) -> Result<()> {
- status.cut_or_copy_flagged_files(CopyMove::Copy)
- }
-
- /// Move the flagged file to current directory.
- /// A progress bar is displayed and a notification is sent once it's done.
- pub fn exec_cut_paste(status: &mut Status) -> Result<()> {
- status.cut_or_copy_flagged_files(CopyMove::Move)
- }
-
- /// Recursively delete all flagged files.
- pub fn exec_delete_files(status: &mut Status, colors: &Colors) -> Result<()> {
- for pathbuf in status.flagged.content.iter() {
- if pathbuf.is_dir() {
- std::fs::remove_dir_all(pathbuf)?;
- } else {
- std::fs::remove_file(pathbuf)?;
- }
- }
- status.selected().reset_mode();
- status.clear_flags_and_reset_view()?;
- Self::refresh_status(status, colors)
- }
-
- /// Change permission of the flagged files.
- /// Once the user has typed an octal permission like 754, it's applied to
- /// the file.
- /// Nothing is done if the user typed nothing or an invalid permission like
- /// 955.
- pub fn exec_chmod(status: &mut Status) -> Result<()> {
- if status.selected().input.is_empty() {
- return Ok(());
- }
- let permissions: u32 =
- u32::from_str_radix(&status.selected().input.string(), 8).unwrap_or(0_u32);
- if permissions <= Status::MAX_PERMISSIONS {
- for path in status.flagged.content.iter() {
- Status::set_permissions(path, permissions)?
- }
- status.flagged.clear()
- }
- status.selected().refresh_view()?;
- status.reset_tabs_view()
- }
-
- pub fn exec_set_nvim_addr(status: &mut Status) -> Result<()> {
- status.nvim_server = status.selected_non_mut().input.string();
- status.selected().reset_mode();
- Ok(())
- }
-
- /// Execute a jump to the selected flagged file.
- /// If the user selected a directory, we jump inside it.
- /// Otherwise, we jump to the parent and select the file.
- pub fn exec_jump(status: &mut Status) -> Result<()> {
- let Some(jump_target) = status.flagged.selected() else { return Ok(()) };
- let jump_target = jump_target.to_owned();
- let target_dir = match jump_target.parent() {
- Some(parent) => parent,
- None => &jump_target,
- };
- status.selected().set_pathcontent(target_dir)?;
- let index = status.selected().path_content.select_file(&jump_target);
- status.selected().scroll_to(index);
-
- Ok(())
- }
-
- /// Execute a command requiring a confirmation (Delete, Move or Copy).
- pub fn exec_confirmed_action(
- status: &mut Status,
- confirmed_action: NeedConfirmation,
- colors: &Colors,
- ) -> Result<()> {
- Self::_exec_confirmed_action(status, confirmed_action, colors)?;
- status.selected().reset_mode();
- Ok(())
- }
-
- fn _exec_confirmed_action(
- status: &mut Status,
- confirmed_action: NeedConfirmation,
- colors: &Colors,
- ) -> Result<()> {
- match confirmed_action {
- NeedConfirmation::Delete => Self::exec_delete_files(status, colors),
- NeedConfirmation::Move => Self::exec_cut_paste(status),
- NeedConfirmation::Copy => Self::exec_copy_paste(status),
- NeedConfirmation::EmptyTrash => Self::exec_trash_empty(status),
- }
- }
-
- /// Select the first file matching the typed regex in current dir.
- pub fn exec_regex(status: &mut Status) -> Result<(), regex::Error> {
- status.select_from_regex()?;
- status.selected().input.reset();
- Ok(())
- }
-
- /// Execute a shell command typed by the user.
- /// pipes and redirections aren't NotSupported
- /// expansions are supported
- pub fn exec_shell(status: &mut Status) -> Result<bool> {
- let shell_command = status.selected_non_mut().input.string();
- let mut args = ShellCommandParser::new(&shell_command).compute(status)?;
- info!("command {shell_command} args: {args:?}");
- if Self::args_is_empty(&args) {
- status.selected().set_mode(Mode::Normal);
- return Ok(true);
- }
- let executable = args.remove(0);
- if Self::is_sudo_command(&executable) {
- status.sudo_command = Some(shell_command);
- Self::event_ask_password(status, PasswordKind::SUDO, None, PasswordUsage::SUDOCOMMAND)?;
- Ok(false)
- } else {
- let Ok(executable) = which(executable) else { return Ok(true); };
- let current_directory = status
- .selected_non_mut()
- .directory_of_selected()?
- .to_owned();
- let params: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
- execute_in_child_without_output_with_path(
- executable,
- current_directory,
- Some(&params),
- )?;
- status.selected().set_mode(Mode::Normal);
- Ok(true)
- }
- }
-
- fn args_is_empty(args: &[String]) -> bool {
- args.is_empty() || args[0] == *""
- }
- fn is_sudo_command(executable: &str) -> bool {
- matches!(executable, "sudo")
- }
/// Leave current mode to normal mode.
/// Reset the inputs and completion, reset the window, exit the preview.
pub fn event_reset_mode(tab: &mut Tab) -> Result<()> {
tab.reset_mode();
tab.refresh_view()
}
-
- /// Reset the inputs and completion, reset the window, exit the preview.
- pub fn event_normal(tab: &mut Tab) -> Result<()> {
- tab.refresh_view()
- }
-
- /// Move up one row if possible.
- pub fn event_up_one_row(tab: &mut Tab) {
- match tab.mode {
- Mode::Normal => {
- tab.path_content.unselect_current();
- tab.path_content.prev();
- tab.path_content.select_current();
- tab.window.scroll_up_one(tab.path_content.index)
- }
- Mode::Preview => tab.window.scroll_up_one(tab.window.top),
- _ => (),
- }
- }
-
- /// Move down one row if possible.
- pub fn event_down_one_row(tab: &mut Tab) {
- match tab.mode {
- Mode::Normal => {
- tab.path_content.unselect_current();
- tab.path_content.next();
- tab.path_content.select_current();
- tab.window.scroll_down_one(tab.path_content.index)
- }
- Mode::Preview => tab.window.scroll_down_one(tab.window.bottom),
- _ => (),
- }
- }
-
- /// Move to the top of the current directory.
- pub fn event_go_top(tab: &mut Tab) {
- match tab.mode {
- Mode::Normal => tab.path_content.select_index(0),
- Mode::Preview => (),
- _ => {
- return;
- }
- }
- tab.window.scroll_to(0);
- }
-
- /// Move up 10 rows in normal mode.
- /// In other modes where vertical scrolling is possible (atm Preview),
- /// if moves up one page.
- pub fn page_up(tab: &mut Tab) {
- match tab.mode {
- Mode::Normal => {
- let up_index = if tab.path_content.index > 10 {
- tab.path_content.index - 10
- } else {
- 0
- };
- tab.path_content.select_index(up_index);
- tab.window.scroll_to(up_index)
- }
- Mode::Preview => {
- if tab.window.top > 0 {
- let skip = min(tab.window.top, 30);
- tab.window.bottom -= skip;
- tab.window.top -= skip;
- }
- }
- _ => (),
- }
- }
-
- /// Move down 10 rows in normal mode.
- /// In other modes where vertical scrolling is possible (atm Preview),
- /// if moves down one page.
- pub fn page_down(tab: &mut Tab) {
- match tab.mode {
- Mode::Normal => {
- let down_index = min(
- tab.path_content.content.len() - 1,
- tab.path_content.index + 10,
- );
- tab.path_content.select_index(down_index);
- tab.window.scroll_to(down_index);
- }
- Mode::Preview => {
- if tab.window.bottom < tab.preview.len() {
- let skip = min(tab.preview.len() - tab.window.bottom, 30);
- tab.window.bottom += skip;
- tab.window.top += skip;
- }
- }
- _ => (),
- }
- }
- /// Move to the bottom of current view.
- pub fn event_go_bottom(tab: &mut Tab) {
- match tab.mode {
- Mode::Normal => {
- let last_index = tab.path_content.content.len() - 1;
- tab.path_content.select_index(last_index);
- tab.window.scroll_to(last_index)
- }
- Mode::Preview => tab.window.scroll_to(tab.preview.len() - 1),
- _ => (),
- }
- }
-
- /// Move the cursor to the start of line.
- pub fn event_cursor_home(tab: &mut Tab) {
- tab.input.cursor_start()
- }
-
- /// Move the cursor to the end of line.
- pub fn event_cursor_end(tab: &mut Tab) {
- tab.input.cursor_end()
- }
-
- /// Select the left or right tab depending on where the user clicked.
- pub fn event_select_pane(status: &mut Status, col: u16) -> Result<()> {
- let (width, _) = status.term_size()?;
- if (col as usize) < width / 2 {
- status.select_tab(0)?;
- } else {
- status.select_tab(1)?;
- };
- Ok(())
- }
-
- /// Select a given row, if there's something in it.
- pub fn event_select_row(status: &mut Status, row: u16, colors: &Colors) -> Result<()> {
- let tab = status.selected();
- match tab.mode {
- Mode::Normal => {
- let index = Self::row_to_index(row);
- tab.path_content.select_index(index);
- tab.window.scroll_to(index);
- }
- Mode::Tree => {
- let index = Self::row_to_index(row) + 1;
- tab.directory.tree.unselect_children();
- tab.directory.tree.position = tab.directory.tree.position_from_index(index);
- let (_, _, node) = tab.directory.tree.select_from_position()?;
- tab.directory.make_preview(colors);
- tab.directory.tree.current_node = node;
- }
- _ => (),
- }
- Ok(())
- }
-
- /// Move to parent directory if there's one.
- /// Does
- /// Add the starting directory to history.
- pub fn event_move_to_parent(tab: &mut Tab) -> Result<()> {
- tab.move_to_parent()
- }
-
- /// Move the cursor left one block.
- pub fn event_move_cursor_left(tab: &mut Tab) {
- tab.input.cursor_left()
- }
-
- /// Open the file with configured opener or enter the directory.
- pub fn exec_file(status: &mut Status) -> Result<()> {
- let tab = status.selected();
- if tab.path_content.is_empty() {
- return Ok(());
- }
- if tab.path_content.is_selected_dir()? {
- tab.go_to_child()
- } else {
- Self::event_open_file(status)
- }
- }
-
- /// Move the cursor to the right in input string.
- pub fn event_move_cursor_right(tab: &mut Tab) {
- tab.input.cursor_right()
- }
-
- /// Delete the char to the left in input string.
- pub fn event_delete_char_left(tab: &mut Tab) {
- tab.input.delete_char_left()
- }
-
- /// Delete all chars right of the cursor in input string.
- pub fn event_delete_chars_right(tab: &mut Tab) {
- tab.input.delete_chars_right()
- }
-
- /// Add a char to input string, look for a possible completion.
- pub fn event_text_insert_and_complete(tab: &mut Tab, c: char) -> Result<()> {
- Self::event_text_insertion(tab, c);
- tab.fill_completion()
- }
-
/// Enter a copy paste mode.
/// A confirmation is asked before copying all flagged files to
/// the current directory.
@@ -701,7 +273,7 @@ impl EventExec {
tab.set_mode(Mode::Preview);
tab.preview = Preview::log(log);
tab.window.reset(tab.preview.len());
- Self::event_go_bottom(tab);
+ bla_go_bottom(tab);
Ok(())
}
@@ -733,59 +305,13 @@ impl EventExec {
/// It's usefull to reset the cursor before leaving the application.
pub fn event_quit(tab: &mut Tab) -> Result<()> {
if let Mode::Tree = tab.mode {
- Self::event_normal(tab)?;
+ tab_refresh_view(tab)?;
tab.set_mode(Mode::Normal)
} else {
tab.must_quit = true;
}
Ok(())
}
-
- /// Leave a mode requiring a confirmation without doing anything.
- /// Reset the mode to the previous mode.
- pub fn event_leave_need_confirmation(tab: &mut Tab) {
- tab.reset_mode();
- }
-
- /// Sort the file with given criteria
- /// Valid kind of sorts are :
- /// by kind : directory first, files next, in alphanumeric order
- /// by filename,
- /// by date of modification,
- /// by size,
- /// by extension.
- /// The first letter is used to identify the method.
- /// If the user types an uppercase char, the sort is reverse.
- pub fn event_leave_sort(status: &mut Status, c: char, colors: &Colors) -> Result<()> {
- if status.selected_non_mut().path_content.content.is_empty() {
- return Ok(());
- }
- let tab = status.selected();
- tab.reset_mode();
- match tab.mode {
- Mode::Normal => {
- tab.path_content.unselect_current();
- tab.path_content.update_sort_from_char(c);
- tab.path_content.sort();
- Self::event_go_top(tab);
- tab.path_content.select_index(0);
- }
- Mode::Tree => {
- tab.directory.tree.update_sort_from_char(c);
- tab.directory.tree.sort();
- tab.tree_select_root(colors)?;
- tab.directory.tree.into_navigable_content(colors);
- }
- _ => (),
- }
- Ok(())
- }
-
- /// Insert a char in the input string.
- pub fn event_text_insertion(tab: &mut Tab, c: char) {
- tab.input.insert(c);
- }
-
/// Toggle the display of hidden files.
pub fn event_toggle_hidden(status: &mut Status, colors: &Colors) -> Result<()> {
let tab = status.selected();
@@ -808,7 +334,7 @@ impl EventExec {
.clone();
let opener = status.opener.open_info(filepath);
if let Some(InternalVariant::NotSupported) = opener.internal_variant.as_ref() {
- Self::event_mount_iso_drive(status)?;
+ bla_mount_iso_drive(status)?;
} else {
match status.opener.open(filepath) {
Ok(_) => (),
@@ -897,27 +423,12 @@ impl EventExec {
tab.set_mode(Mode::Navigate(Navigate::Shortcut));
Ok(())
}
-
- /// A right click opens a file or a directory.
- pub fn event_right_click(status: &mut Status, colors: &Colors) -> Result<()> {
- match status.selected().mode {
- Mode::Normal => Self::exec_file(status),
- Mode::Tree => Self::exec_tree(status, colors),
- _ => Ok(()),
- }
- }
-
- /// Replace the input string by the selected completion.
- pub fn event_replace_input_with_completion(tab: &mut Tab) {
- tab.input.replace(tab.completion.current_proposition())
- }
-
/// Send a signal to parent NVIM process, picking the selected file.
/// If no RPC server were provided at launch time - which may happen for
/// reasons unknow to me - it does nothing.
/// It requires the "nvim-send" application to be in $PATH.
pub fn event_nvim_filepicker(status: &mut Status) -> Result<()> {
- Self::read_nvim_listen_address_if_needed(status);
+ read_nvim_listen_address_if_needed(status);
if status.nvim_server.is_empty() {
return Ok(());
};
@@ -925,7 +436,7 @@ impl EventExec {
let tab = status.selected();
let Some(fileinfo) = tab.selected() else { return Ok(()) };
let Some(path_str) = fileinfo.path.to_str() else { return Ok(()) };
- Self::open_in_current_neovim(path_str, &nvim_server);
+ open_in_current_neovim(path_str, &nvim_server);
Ok(())
}
@@ -937,42 +448,6 @@ impl EventExec {
Ok(())
}
- fn open_in_current_neovim(path_str: &str, nvim_server: &str) {
- let command = &format!("<esc>:e {path_str}<cr><esc>:set number<cr><esc>:close<cr>");
- let _ = nvim(nvim_server, command);
- }
-
- /// Copy the selected filename to the clipboard. Only the filename.
- pub fn event_filename_to_clipboard(tab: &Tab) -> Result<()> {
- Self::set_clipboard(
- tab.selected()
- .context("event_filename_to_clipboard: no selected file")?
- .filename
- .clone(),
- )
- }
-
- /// Copy the selected filepath to the clipboard. The absolute path.
- pub fn event_filepath_to_clipboard(tab: &Tab) -> Result<()> {
- Self::set_clipboard(
- tab.selected()
- .context("event_filepath_to_clipboard: no selected file")?
- .path
- .to_str()
- .context("event_filepath_to_clipboard: no selected file")?
- .to_owned(),
- )
- }
-
- fn set_clipboard(content: String) -> Result<()> {
- info!("copied to clipboard: {}", content);
- let Ok(mut ctx) = ClipboardContext::new() else { return Ok(()); };
- let Ok(_) = ctx.set_contents(content) else { return Ok(()); };
- // For some reason, it's not writen if you don't read it back...
- let _ = ctx.get_contents();
- Ok(())
- }
-
/// Enter the filter mode, where you can filter.
/// See `crate::filter::Filter` for more details.
pub fn event_filter(tab: &mut Tab) -> Result<()> {
@@ -1015,111 +490,6 @@ impl EventExec {
status.selected().set_pathcontent(&start_folder)
}
- fn read_nvim_listen_address_if_needed(status: &mut Status) {
- if !status.nvim_server.is_empty() {
- return;
- }
- let Ok(nvim_listen_address) = std::env::var("NVIM_LISTEN_ADDRESS") else { return; };
- status.nvim_server = nvim_listen_address;
- }
-
- /// Execute a rename of the selected file.
- /// It uses the `fs::rename` function and has the same limitations.
- /// We only try to rename in the same directory, so it shouldn't be a problem.
- /// Filename is sanitized before processing.
- pub fn exec_rename(tab: &mut Tab) -> Result<()> {
- let fileinfo = match tab.previous_mode {
- Mode::Tree => &tab.directory.tree.current_node.fileinfo,
- _ => tab
- .path_content
- .selected()
- .context("rename: couldnt parse selected")?,
- };
-
- let original_path = &fileinfo.path;
- if let Some(parent) = original_path.parent() {
- let new_path = parent.join(sanitize_filename::sanitize(tab.input.string()));
- info!(
- "renaming: original: {} - new: {}",
- original_path.display(),
- new_path.display()
- );
- info!(target: "special",
- "renaming: original: {} - new: {}",
- original_path.display(),
- new_path.display()
- );
- fs::rename(original_path, new_path)?;
- }
-
- tab.refresh_view()
- }
-
- /// Creates a new file with input string as name.
- /// Nothing is done if the file already exists.
- /// Filename is sanitized before processing.
- pub fn exec_newfile(tab: &mut Tab) -> Result<()> {
- let path = tab
- .path_content
- .path
- .join(sanitize_filename::sanitize(tab.input.string()));
- if !path.exists() {
- fs::File::create(&path)?;
- info!(target: "special", "New file: {path}", path=path.display());
- }
- tab.refresh_view()
- }
-
- /// Creates a new directory with input string as name.
- /// Nothing is done if the directory already exists.
- /// We use `fs::create_dir` internally so it will fail if the input string
- /// ie. the user can create `newdir` or `newdir/newfolder`.
- /// Directory name is sanitized before processing.
- pub fn exec_newdir(tab: &mut Tab) -> Result<()> {
- let path = tab
- .path_content
- .path
- .join(sanitize_filename::sanitize(tab.input.string()));
- if !path.exists() {
- fs::create_dir_all(&path)?;
- info!(target: "special", "New directory: {path}", path=path.display());
- }
- tab.refresh_view()
- }
-
- /// Tries to execute the selected file with an executable which is read
- /// from the input string. It will fail silently if the executable can't
- /// be found.
- /// Optional parameters can be passed normally. ie. `"ls -lah"`
- pub fn exec_exec(tab: &mut Tab) -> Result<()> {
- if tab.path_content.content.is_empty() {
- return Err(anyhow!("exec exec: empty directory"));
- }
- let exec_command = tab.input.string();
- if let Ok(success) = EventExec::execute_custom(tab, exec_command) {
- if success {
- tab.completion.reset();
- tab.input.reset();
- }
- }
- Ok(())
- }
-
- fn execute_custom(tab: &mut Tab, exec_command: String) -> Result<bool> {
- let mut args: Vec<&str> = exec_command.split(' ').collect();
- let command = args.remove(0);
- if !std::path::Path::new(command).exists() {
- return Ok(false);
- }
- let path = &tab
- .path_content
- .selected_path_string()
- .context("execute custom: can't find command")?;
- args.push(path);
- execute_in_child(command, &args)?;
- Ok(true)
- }
-
/// Executes a `dragon-drop` command on the selected file.
/// It obviously requires the `dragon-drop` command to be installed.
pub fn event_drag_n_drop(status: &mut Status) -> Result<()> {
@@ -1134,41 +504,6 @@ impl EventExec {
Ok(())
}
- /// Executes a search in current folder, selecting the first file matching
- /// the current completion proposition.
- /// ie. If you typed `"jpg"` before, it will move to the first file
- /// whose filename contains `"jpg"`.
- /// The current order of files is used.
- pub fn exec_search(status: &mut Status, colors: &Colors) -> Result<()> {
- let tab = status.selected();
- let searched = tab.input.string();
- tab.input.reset();
- if searched.is_empty() {
- tab.searched = None;
- return Ok(());
- }
- tab.searched = Some(searched.clone());
- match tab.previous_mode {
- Mode::Tree => {
- tab.directory.tree.unselect_children();
- if let Some(position) = tab.directory.tree.select_first_match(&searched) {
- tab.directory.tree.position = position;
- (_, _, tab.directory.tree.current_node) =
- tab.directory.tree.select_from_position()?;
- } else {
- tab.directory.tree.select_root()
- };
- tab.directory.make_preview(colors);
- Ok(())
- }
- _ => {
- let next_index = tab.path_content.index;
- tab.search_from(&searched, next_index);
- Ok(())
- }
- }
- }
-
pub fn event_search_next(tab: &mut Tab) -> Result<()> {
match tab.mode {
Mode::Tree => (),
@@ -1181,71 +516,11 @@ impl EventExec {
Ok(())
}
- /// Move to the folder typed by the user.
- /// The first completion proposition is used, `~` expansion is done.
- /// If no result were found, no cd is done and we go back to normal mode
- /// silently.
- pub fn exec_goto(tab: &mut Tab) -> Result<()> {
- if tab.completion.is_empty() {
- return Ok(());
- }
- let completed = tab.completion.current_proposition();
- let path = string_to_path(completed)?;
- tab.input.reset();
- tab.history.push(&path);
- tab.set_pathcontent(&path)?;
- tab.window.reset(tab.path_content.content.len());
- Ok(())
- }
-
- /// Move to the selected shortcut.
- /// It may fail if the user has no permission to visit the path.
- pub fn exec_shortcut(tab: &mut Tab) -> Result<()> {
- tab.input.reset();
- let path = tab
- .shortcut
- .selected()
- .context("exec shortcut: empty shortcuts")?
- .clone();
- tab.history.push(&path);
- tab.set_pathcontent(&path)?;
- Self::event_normal(tab)
- }
-
- /// Move back to a previously visited path.
- /// It may fail if the user has no permission to visit the path
- pub fn exec_history(tab: &mut Tab) -> Result<()> {
- tab.input.reset();
- let path = tab
- .history
- .selected()
- .context("exec history: path unreachable")?
- .clone();
- tab.set_pathcontent(&path)?;
- tab.history.drop_queue();
- Self::event_normal(tab)
- }
-
- /// Apply a filter to the displayed files.
- /// See `crate::filter` for more details.
- pub fn exec_filter(status: &mut Status, colors: &Colors) -> Result<()> {
- let tab = status.selected();
- let filter = FilterKind::from_input(&tab.input.string());
- tab.set_filter(filter);
- tab.input.reset();
- tab.path_content.reset_files(&tab.filter, tab.show_hidden)?;
- if let Mode::Tree = tab.previous_mode {
- tab.make_tree(colors)?;
- }
- tab.window.reset(tab.path_content.content.len());
- Ok(())
- }
-
/// Move up one row in modes allowing movement.
/// Does nothing if the selected item is already the first in list.
pub fn event_move_up(status: &mut Status, colors: &Colors) -> Result<()> {
match status.selected().mode {
- Mode::Normal | Mode::Preview => EventExec::event_up_one_row(status.selected()),
+ Mode::Normal | Mode::Preview => bla_up_one_row(status.selected()),
Mode::Navigate(Navigate::Jump) => status.flagged.prev(),
Mode::Navigate(Navigate::History) => status.selected().history.prev(),
Mode::Navigate(Navigate::Trash) => status.trash.prev(),
@@ -1257,7 +532,7 @@ impl EventExec {
Mode::Navigate(Navigate::CliInfo) => status.cli_info.prev(),
Mode::Navigate(Navigate::EncryptedDrive) => status.encrypted_devices.prev(),
Mode::InputCompleted(_) => status.selected().completion.prev(),
- Mode::Tree => EventExec::event_select_prev(status.selected(), colors)?,
+ Mode::Tree => bla_select_prev(status.selected(), colors)?,
_ => (),
};
Ok(())
@@ -1267,7 +542,7 @@ impl EventExec {
/// Does nothing if the user is already at the bottom.
pub fn event_move_down(status: &mut Status, colors: &Colors) -> Result<()> {
match status.selected().mode {
- Mode::Normal | Mode::Preview => EventExec::event_down_one_row(status.selected()),
+ Mode::Normal | Mode::Preview => bla_down_one_row(status.selected()),
Mode::Navigate