diff options
author | qkzk <qu3nt1n@gmail.com> | 2023-04-15 00:52:55 +0200 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2023-04-15 00:52:55 +0200 |
commit | 3017482632fcf862d14cacdd2f2d08a727f86af7 (patch) | |
tree | 9c59355654481c9d61059c5631ae415570b9e6fa /src/event_exec.rs | |
parent | 91f4dbf41cb30bd6b348d3d42fe585464142f32e (diff) |
start event exec refactoring
Diffstat (limited to 'src/event_exec.rs')
-rw-r--r-- | src/event_exec.rs | 2076 |
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(¶ms), - )?; - 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 |