diff options
author | qkzk <qkzk@users.noreply.github.com> | 2023-01-11 21:11:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-11 21:11:10 +0100 |
commit | 67eac8610edb8959c1e588d26a21730e1009ce07 (patch) | |
tree | 7acd212149ddc7bf0780e54ddc6136bb3b4d702e | |
parent | 2c05d3f1e0f87eb06000135bf8feb3edeb1a6f6d (diff) | |
parent | eb110b7abe5bfa4ec0239d1ec432ec75e76051ba (diff) |
Merge pull request #66 from qkzk/previous-modev0.1.10
Previous mode
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | development.md | 30 | ||||
-rw-r--r-- | readme.md | 9 | ||||
-rw-r--r-- | src/action_map.rs | 12 | ||||
-rw-r--r-- | src/completion.rs | 6 | ||||
-rw-r--r-- | src/constant_strings_paths.rs | 2 | ||||
-rw-r--r-- | src/event_dispatch.rs | 5 | ||||
-rw-r--r-- | src/event_exec.rs | 258 | ||||
-rw-r--r-- | src/mode.rs | 21 | ||||
-rw-r--r-- | src/sort.rs | 42 | ||||
-rw-r--r-- | src/tab.rs | 16 | ||||
-rw-r--r-- | src/term_manager.rs | 72 | ||||
-rw-r--r-- | src/trash.rs | 9 | ||||
-rw-r--r-- | src/tree.rs | 48 |
15 files changed, 343 insertions, 191 deletions
@@ -935,7 +935,7 @@ dependencies = [ [[package]] name = "fm-tui" -version = "0.1.9" +version = "0.1.10" dependencies = [ "chrono", "clap 4.0.32", @@ -1,6 +1,6 @@ [package] name = "fm-tui" -version = "0.1.9" +version = "0.1.10" authors = ["Quentin Konieczko <qu3nt1n@gmail.com>"] edition = "2021" license-file = "LICENSE.txt" diff --git a/development.md b/development.md index 069b398..0953279 100644 --- a/development.md +++ b/development.md @@ -296,9 +296,15 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally. - [x] display a triangle to display folded status - [x] unfold all, fold all +### Version 0.1.10 : keep track previous mode + +- [x] return to previous mode when executing (ie. pressing Enter) or leaving a mode which mutates the content (like sort). +- [x] tree: sort. + ## TODO - [ ] remote control + - [x] filepicker requires the nvim-remote rust crate installed - [ ] listen to stdin (rcv etc.) @@ -309,18 +315,18 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally. - https://neovim.io/doc/user/api.html - [ ] $NVIM_LISTEN_ADDRESS isn't always set on nbim startup ; can be set from nvim before running... then sent to fm with some args - [ ] args read correctly, use NVIM_LISTEN_ADDRESS if args is sent + - [ ] display / event separation. use async and message passing between coroutines + - [ ] @ranger [ueberzug-rs](https://github.com/Adit-Chauhan/Ueberzug-rs) @[termimage](https://rawcdn.githack.com/nabijaczleweli/termimage/doc/termimage/index.html) - [ ] vim keys, harmonize keybinds with ranger -- [ ] scrollable shortcuts, marks & history -- [ ] improve thumbnail with [chafa](https://hpjansson.org/chafa/) - [felix](https://github.com/kyoheiu/felix#usage) - - [x] use chafa - - [x] print in term - - [x] print in raw mode - - [ ] print with term: term... - [ ] zoxide support +- [ ] Version 0.1.11 : window for mode displaying info (completion, marks, shortcut, jump) + +- [ ] Version 0.1.12 : scrollable shortcuts, marks & history + - [ ] Version 0.2.0 : tests - [ ] tests @@ -359,6 +365,18 @@ All of this stuff can be done easily through a shell command or automatically. I or just use sshfs... +### Thumbnails with chafa + +- [ ] improve thumbnail with [chafa](https://hpjansson.org/chafa/) - [felix](https://github.com/kyoheiu/felix#usage) + + - [x] use chafa + - [x] print in term + - [x] print in raw mode + - [ ] print with term: term... + + Can't make it work in tuikit. We need the whole chafa output into tuikit attr + It's too much work and it will be too slow for such a gadget. + ## Sources ### CLI @@ -77,6 +77,7 @@ If you added the [recommanded function](#cd-on-quit) to your bashrc/zshrc, simpl - Detect removable disks automatically and jump to them in a few keystrokes (G, up, enter) - Drag and drop files (requires dragon-drop installed) with Alt+D - Trash a file with X, open the trash with Alt+o. x to remove permanently, enter to restore. Wipe the trash with Alt+x. +- Toggle the tree view with t. Fold folders with z. Unfold every folder with Z, fold every folder with Alt+z. Most of those features are inspired by ranger and alternatives (Midnight commander), the look and feel by dired. @@ -166,7 +167,15 @@ fm: a dired like file manager. Keybindings. Alt('o'): Open the trash (enter to restore, del clear) Alt('x'): Empty the trash + - Tree - + Navigate as usual. Most actions works as in 'normal' view. + Char('T'): Toggle tree mode + Char('z'): Fold a node + Alt('z'): Fold every node + Char('Z'): Unfold every node + - MODES - + Char('T'): TREE Char('m'): CHMOD Char('e'): EXEC Char('d'): NEWDIR diff --git a/src/action_map.rs b/src/action_map.rs index aad13e6..91220c1 100644 --- a/src/action_map.rs +++ b/src/action_map.rs @@ -83,7 +83,7 @@ impl ActionMap { pub fn matcher(&self, status: &mut Status) -> FmResult<()> { let current_tab = status.selected(); match *self { - ActionMap::Back => EventExec::event_back(current_tab), + ActionMap::Back => EventExec::event_back(status), ActionMap::BackTab => EventExec::backtab(status), ActionMap::Backspace => EventExec::event_backspace(status), ActionMap::Bulkrename => EventExec::event_bulkrename(status), @@ -98,7 +98,7 @@ impl ActionMap { ActionMap::DisplayFull => EventExec::event_toggle_display_full(status), ActionMap::DragNDrop => EventExec::event_drag_n_drop(status), ActionMap::End => EventExec::event_end(status), - ActionMap::Enter => EventExec::enter(status), + ActionMap::Enter => EventExec::event_enter(status), ActionMap::Exec => EventExec::event_exec(current_tab), ActionMap::Filter => EventExec::event_filter(current_tab), ActionMap::FlagAll => EventExec::event_flag_all(status), @@ -111,7 +111,7 @@ impl ActionMap { ActionMap::KeyHome => EventExec::event_key_home(status), ActionMap::MarksJump => EventExec::event_marks_jump(status), ActionMap::MarksNew => EventExec::event_marks_new(current_tab), - ActionMap::ModeNormal => EventExec::event_normal(current_tab), + ActionMap::ModeNormal => EventExec::event_reset_mode(current_tab), ActionMap::MoveDown => EventExec::event_move_down(status), ActionMap::MoveLeft => EventExec::event_move_left(status), ActionMap::MoveRight => EventExec::event_move_right(status), @@ -120,8 +120,8 @@ impl ActionMap { ActionMap::NewFile => EventExec::event_new_file(current_tab), ActionMap::NvimFilepicker => EventExec::event_nvim_filepicker(current_tab), ActionMap::OpenFile => EventExec::event_open_file(status), - ActionMap::PageDown => EventExec::page_down(status), - ActionMap::PageUp => EventExec::page_up(status), + ActionMap::PageDown => EventExec::event_page_down(status), + ActionMap::PageUp => EventExec::event_page_up(status), ActionMap::Preview => EventExec::event_preview(status), ActionMap::Quit => EventExec::event_quit(current_tab), ActionMap::RefreshView => EventExec::event_refreshview(status), @@ -134,7 +134,7 @@ impl ActionMap { ActionMap::Shortcut => EventExec::event_shortcut(current_tab), ActionMap::Sort => EventExec::event_sort(current_tab), ActionMap::Symlink => EventExec::event_symlink(status), - ActionMap::Tab => EventExec::tab(status), + ActionMap::Tab => EventExec::event_tab(status), ActionMap::Thumbnail => EventExec::event_thumbnail(current_tab), ActionMap::ToggleDualPane => EventExec::event_toggle_dualpane(status), ActionMap::ToggleFlag => EventExec::event_toggle_flag(status), diff --git a/src/completion.rs b/src/completion.rs index 7f88bba..f6cc3d0 100644 --- a/src/completion.rs +++ b/src/completion.rs @@ -2,7 +2,7 @@ use std::fs::{self, ReadDir}; use crate::fileinfo::PathContent; use crate::fm_error::FmResult; -use crate::mode::{LastMode, Mode}; +use crate::mode::Mode; /// Different kind of completions #[derive(Clone, Default, Copy)] @@ -13,7 +13,7 @@ pub enum InputCompleted { /// Complete a directory path in filesystem Goto, /// Complete a filename from current directory - Search(LastMode), + Search, /// Complete an executable name from $PATH Exec, } @@ -106,7 +106,7 @@ impl Completion { match self.kind { InputCompleted::Exec => self.exec(input_string), InputCompleted::Goto => self.goto(input_string, current_path), - InputCompleted::Search(_) => self.search(input_string, path_content), + InputCompleted::Search => self.search(input_string, path_content), InputCompleted::Nothing => Ok(()), } } diff --git a/src/constant_strings_paths.rs b/src/constant_strings_paths.rs index 81f1c22..e7f8876 100644 --- a/src/constant_strings_paths.rs +++ b/src/constant_strings_paths.rs @@ -44,12 +44,12 @@ pub static HARDCODED_SHORTCUTS: [&str; 9] = [ "/", "/dev", "/etc", - "/media", "/mnt", "/opt", "/run/media", "/tmp", "/usr", + "/var", ]; /// Path to the trash folder files pub static TRASH_FOLDER_FILES: &str = "~/.local/share/Trash/files"; diff --git a/src/event_dispatch.rs b/src/event_dispatch.rs index 4f2bb33..a7ad1a0 100644 --- a/src/event_dispatch.rs +++ b/src/event_dispatch.rs @@ -59,10 +59,7 @@ impl EventDispatcher { Mode::InputSimple(InputSimple::Marks(MarkAction::New)) => { EventExec::exec_marks_new(status, c) } - Mode::InputSimple(InputSimple::Sort) => { - EventExec::event_leave_sort(status.selected(), c); - Ok(()) - } + Mode::InputSimple(InputSimple::Sort) => EventExec::event_leave_sort(status, c), Mode::InputSimple(InputSimple::RegexMatch) => { EventExec::event_text_insertion(status.selected(), c); status.select_from_regex()?; diff --git a/src/event_exec.rs b/src/event_exec.rs index 170d20b..6df3da9 100644 --- a/src/event_exec.rs +++ b/src/event_exec.rs @@ -9,7 +9,6 @@ use sysinfo::SystemExt; use crate::bulkrename::Bulkrename; use crate::completion::InputCompleted; -use crate::config::Colors; use crate::constant_strings_paths::DEFAULT_DRAGNDROP; use crate::constant_strings_paths::NVIM_RPC_SENDER; use crate::content_window::RESERVED_ROWS; @@ -17,7 +16,6 @@ use crate::copy_move::CopyMove; use crate::fileinfo::FileKind; use crate::filter::FilterKind; use crate::fm_error::{FmError, FmResult}; -use crate::mode::LastMode; use crate::mode::Navigate; use crate::mode::{InputSimple, MarkAction, Mode, NeedConfirmation}; use crate::opener::execute_in_child; @@ -125,7 +123,9 @@ impl EventExec { if status.selected().path_content.is_empty() { return Ok(()); } - status.selected().mode = Mode::InputSimple(InputSimple::Chmod); + status + .selected() + .set_mode(Mode::InputSimple(InputSimple::Chmod)); if status.flagged.is_empty() { status .flagged @@ -139,14 +139,14 @@ impl EventExec { pub fn event_jump(status: &mut Status) -> FmResult<()> { if !status.flagged.is_empty() { status.flagged.index = 0; - status.selected().mode = Mode::Navigate(Navigate::Jump) + status.selected().set_mode(Mode::Navigate(Navigate::Jump)) } Ok(()) } /// Enter Marks new mode, allowing to bind a char to a path. pub fn event_marks_new(tab: &mut Tab) -> FmResult<()> { - tab.mode = Mode::InputSimple(InputSimple::Marks(MarkAction::New)); + tab.set_mode(Mode::InputSimple(InputSimple::Marks(MarkAction::New))); Ok(()) } @@ -155,7 +155,9 @@ impl EventExec { if status.marks.is_empty() { return Ok(()); } - status.selected().mode = Mode::InputSimple(InputSimple::Marks(MarkAction::Jump)); + status + .selected() + .set_mode(Mode::InputSimple(InputSimple::Marks(MarkAction::Jump))); Ok(()) } @@ -163,7 +165,9 @@ impl EventExec { pub fn exec_marks_new(status: &mut Status, c: char) -> FmResult<()> { let path = status.selected().path_content.path.clone(); status.marks.new_mark(c, path)?; - Self::event_normal(status.selected()) + Self::event_normal(status.selected())?; + status.selected().reset_mode(); + Self::refresh_status(status) } /// Execute a jump to a mark, moving to a valid path. @@ -173,7 +177,9 @@ impl EventExec { let path = path.clone(); status.selected().set_pathcontent(&path)? } - Self::event_normal(status.selected()) + Self::event_normal(status.selected())?; + status.selected().reset_mode(); + Self::refresh_status(status) } /// Creates a symlink of every flagged file to the current directory. @@ -221,7 +227,9 @@ impl EventExec { std::fs::remove_file(pathbuf)?; } } - status.clear_flags_and_reset_view() + status.selected().reset_mode(); + status.clear_flags_and_reset_view()?; + Self::refresh_status(status) } /// Change permission of the flagged files. @@ -274,7 +282,7 @@ impl EventExec { confirmed_action: NeedConfirmation, ) -> FmResult<()> { Self::_exec_confirmed_action(status, confirmed_action)?; - status.selected().mode = Mode::Normal; + status.selected().set_mode(Mode::Normal); Ok(()) } @@ -299,14 +307,14 @@ impl EventExec { /// 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) -> FmResult<()> { + tab.reset_mode(); + tab.refresh_view() + } + + /// Reset the inputs and completion, reset the window, exit the preview. pub fn event_normal(tab: &mut Tab) -> FmResult<()> { - tab.input.reset(); - tab.completion.reset(); - tab.path_content.reset_files(&tab.filter, tab.show_hidden)?; - tab.window.reset(tab.path_content.content.len()); - tab.mode = Mode::Normal; - tab.preview = Preview::new_empty(); - Ok(()) + tab.refresh_view() } /// Move up one row if possible. @@ -352,7 +360,7 @@ impl EventExec { /// Move up 10 rows in normal mode. /// In other modes where vertical scrolling is possible (atm Preview), /// if moves up one page. - pub fn event_page_up(tab: &mut Tab) { + pub fn page_up(tab: &mut Tab) { match tab.mode { Mode::Normal => { let up_index = if tab.path_content.index > 10 { @@ -377,7 +385,7 @@ impl EventExec { /// Move down 10 rows in normal mode. /// In other modes where vertical scrolling is possible (atm Preview), /// if moves down one page. - pub fn event_page_down(tab: &mut Tab) { + pub fn page_down(tab: &mut Tab) { match tab.mode { Mode::Normal => { let down_index = min( @@ -509,7 +517,9 @@ impl EventExec { if status.flagged.is_empty() { return Ok(()); } - status.selected().mode = Mode::NeedConfirmation(NeedConfirmation::Copy); + status + .selected() + .set_mode(Mode::NeedConfirmation(NeedConfirmation::Copy)); Ok(()) } @@ -521,26 +531,28 @@ impl EventExec { if status.flagged.is_empty() { return Ok(()); } - status.selected().mode = Mode::NeedConfirmation(NeedConfirmation::Move); + status + .selected() + .set_mode(Mode::NeedConfirmation(NeedConfirmation::Move)); Ok(()) } /// Enter the new dir mode. pub fn event_new_dir(tab: &mut Tab) -> FmResult<()> { - tab.mode = Mode::InputSimple(InputSimple::Newdir); + tab.set_mode(Mode::InputSimple(InputSimple::Newdir)); Ok(()) } /// Enter the new file mode. pub fn event_new_file(tab: &mut Tab) -> FmResult<()> { - tab.mode = Mode::InputSimple(InputSimple::Newfile); + tab.set_mode(Mode::InputSimple(InputSimple::Newfile)); Ok(()) } /// Enter the execute mode. Most commands must be executed to allow for /// a confirmation. pub fn event_exec(tab: &mut Tab) -> FmResult<()> { - tab.mode = Mode::InputCompleted(InputCompleted::Exec); + tab.set_mode(Mode::InputCompleted(InputCompleted::Exec)); Ok(()) } @@ -558,7 +570,7 @@ impl EventExec { FileKind::NormalFile => { let preview = Preview::new(file_info, &unmutable_tab.path_content.users_cache, status)?; - status.selected().mode = Mode::Preview; + status.selected().set_mode(Mode::Preview); status.selected().window.reset(preview.len()); status.selected().preview = preview; } @@ -576,7 +588,9 @@ impl EventExec { if status.flagged.is_empty() { return Ok(()); } - status.selected().mode = Mode::NeedConfirmation(NeedConfirmation::Delete); + status + .selected() + .set_mode(Mode::NeedConfirmation(NeedConfirmation::Delete)); Ok(()) } @@ -585,7 +599,7 @@ impl EventExec { pub fn event_help(status: &mut Status) -> FmResult<()> { let help = status.help.clone(); let tab = status.selected(); - tab.mode = Mode::Preview; + tab.set_mode(Mode::Preview); tab.preview = Preview::help(&help); tab.window.reset(tab.preview.len()); Ok(()) @@ -595,7 +609,7 @@ impl EventExec { /// Matching items are displayed as you type them. pub fn event_search(tab: &mut Tab) -> FmResult<()> { tab.searched = None; - tab.mode = Mode::InputCompleted(InputCompleted::Search(LastMode::from_mode(tab.mode))); + tab.set_mode(Mode::InputCompleted(InputCompleted::Search)); Ok(()) } @@ -604,17 +618,14 @@ impl EventExec { pub fn event_regex_match(tab: &mut Tab) -> FmResult<()> { match tab.mode { Mode::Tree => (), - _ => tab.mode = Mode::InputSimple(InputSimple::RegexMatch), + _ => tab.set_mode(Mode::InputSimple(InputSimple::RegexMatch)), } Ok(()) } /// Enter the sort mode, allowing the user to select a sort method. pub fn event_sort(tab: &mut Tab) -> FmResult<()> { - match tab.mode { - Mode::Tree => (), - _ => tab.mode = Mode::InputSimple(InputSimple::Sort), - } + tab.set_mode(Mode::InputSimple(InputSimple::Sort)); Ok(()) } @@ -622,16 +633,17 @@ impl EventExec { /// It's usefull to reset the cursor before leaving the application. pub fn event_quit(tab: &mut Tab) -> FmResult<()> { if let Mode::Tree = tab.mode { - Self::event_normal(tab) + Self::event_normal(tab)?; + tab.set_mode(Mode::Normal) } else { tab.must_quit = true; - Ok(()) } + Ok(()) } /// Reset the mode to normal. pub fn event_leave_need_confirmation(tab: &mut Tab) { - tab.mode = Mode::Normal; + tab.reset_mode(); } /// Sort the file with given criteria @@ -643,16 +655,30 @@ impl EventExec { /// 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(tab: &mut Tab, c: char) { - tab.mode = Mode::Normal; - if tab.path_content.content.is_empty() { - return; + pub fn event_leave_sort(status: &mut Status, c: char) -> FmResult<()> { + if status.selected_non_mut().path_content.content.is_empty() { + return Ok(()); } - 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) + let colors = &status.config_colors.clone(); + 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. @@ -698,14 +724,14 @@ impl EventExec { /// not the selected file in the pathcontent. pub fn event_rename(tab: &mut Tab) -> FmResult<()> { if tab.selected().is_some() { - tab.mode = Mode::InputSimple(InputSimple::Rename(LastMode::from_mode(tab.mode))); + tab.set_mode(Mode::InputSimple(InputSimple::Rename)); } Ok(()) } /// Enter the goto mode where an user can type a path to jump to. pub fn event_goto(tab: &mut Tab) -> FmResult<()> { - tab.mode = Mode::InputCompleted(InputCompleted::Goto); + tab.set_mode(Mode::InputCompleted(InputCompleted::Goto)); tab.completion.reset(); Ok(()) } @@ -726,7 +752,7 @@ impl EventExec { /// Enter the history mode, allowing to navigate to previously visited /// directory. pub fn event_history(tab: &mut Tab) -> FmResult<()> { - tab.mode = Mode::Navigate(Navigate::History); + tab.set_mode(Mode::Navigate(Navigate::History)); Ok(()) } @@ -734,7 +760,7 @@ impl EventExec { /// Basic folders (/, /dev... $HOME) and mount points (even impossible to /// visit ones) are proposed. pub fn event_shortcut(tab: &mut Tab) -> FmResult<()> { - tab.mode = Mode::Navigate(Navigate::Shortcut); + tab.set_mode(Mode::Navigate(Navigate::Shortcut)); Ok(()) } @@ -795,31 +821,30 @@ impl EventExec { /// Copy the selected filename to the clipboard. Only the filename. pub fn event_filename_to_clipboard(tab: &Tab) -> FmResult<()> { - let filename = tab - .selected() - .ok_or_else(|| FmError::custom("event_filename_to_clipboard", "no selected file"))? - .filename - .clone(); - let mut ctx = ClipboardContext::new()?; - ctx.set_contents(filename)?; - // For some reason, it's not writen if you don't read it back... - let _ = ctx.get_contents(); - - Ok(()) + Self::set_clipboard( + tab.selected() + .ok_or_else(|| FmError::custom("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) -> FmResult<()> { - let filepath = tab - .selected() - .ok_or_else(|| FmError::custom("event_filepath_to_clipboard", "no selected file"))? - .path - .to_str() - .ok_or_else(|| FmError::custom("event_filepath_to_clipboard", "no selected file"))? - .to_owned(); - info!("filepath: {}", filepath); + Self::set_clipboard( + tab.selected() + .ok_or_else(|| FmError::custom("event_filepath_to_clipboard", "no selected file"))? + .path + .to_str() + .ok_or_else(|| FmError::custom("event_filepath_to_clipboard", "no selected file"))? + .to_owned(), + ) + } + + fn set_clipboard(content: String) -> FmResult<()> { + info!("copied to clipboard: {}", content); let mut ctx = ClipboardContext::new()?; - ctx.set_contents(filepath)?; + ctx.set_contents(content)?; // For some reason, it's not writen if you don't read it back... let _ = ctx.get_contents(); Ok(()) @@ -828,19 +853,24 @@ impl EventExec { /// Enter the filter mode, where you can filter. /// See `crate::filter::Filter` for more details. pub fn event_filter(tab: &mut Tab) -> FmResult<()> { - tab.mode = Mode::InputSimple(InputSimple::Filter); + tab.set_mode(Mode::InputSimple(InputSimple::Filter)); Ok(()) } /// Move back in history to the last visited directory. - pub fn event_back(tab: &mut Tab) -> FmResult<()> { - if tab.history.content.len() <= 1 { + pub fn event_back(status: &mut Status) -> FmResult<()> { + if status.selected_non_mut().history.content.len() <= 1 { return Ok(()); } + let colors = &status.config_colors.clone(); + let tab = status.selected(); tab.history.content.pop(); - let index = tab.history.len() - 1; - let last = tab.history.content[index].clone(); + let last_index = tab.history.len() - 1; + let last = tab.history.content[last_index].clone(); tab.set_pathcontent(&last)?; + if let Mode::Tree = tab.mode { + tab.make_tree(colors)? + } Ok(()) } @@ -865,23 +895,22 @@ impl EventExec { /// Execute a rename of the selected file. /// It uses the `fs::rename` function and has the same limitations. - /// We only tries to rename in the same directory, so it shouldn't be a problem. + /// 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, lastmode: LastMode) -> FmResult<()> { - let fileinfo = match lastmode { - LastMode::Tree => &tab.directory.tree.current_node.fileinfo, - LastMode::Other => tab + pub fn exec_rename(tab: &mut Tab) -> FmResult<()> { + let fileinfo = match tab.previous_mode { + Mode::Tree => &tab.directory.tree.current_node.fileinfo, + _ => tab .path_content .selected() .ok_or_else(|| FmError::custom("rename", "couldnt parse selected"))?, }; - info!("fileinfo {:?}", fileinfo); let original_path = &fileinfo.path; if let Some(parent) = original_path.parent() { let new_path = parent.join(sanitize_filename::sanitize(tab.input.string())); info!( - "original: {} - new: {}", + "renaming: original: {} - new: {}", original_path.display(), new_path.display() ); @@ -978,7 +1007,9 @@ impl EventExec { /// 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(tab: &mut Tab, lastmode: LastMode, colors: &Colors) -> FmResult<()> { + pub fn exec_search(status: &mut Status) -> FmResult<()> { + let colors = &status.config_colors.clone(); + let tab = status.selected(); let searched = tab.input.string(); tab.input.reset(); if searched.is_empty() { @@ -986,8 +1017,8 @@ impl EventExec { return Ok(()); } tab.searched = Some(searched.clone()); - match lastmode { - LastMode::Tree => { + 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; @@ -998,7 +1029,7 @@ impl EventExec { tab.directory.make_preview(colors); Ok(()) } - LastMode::Other => { + _ => { let next_index = tab.path_content.index; tab.search_from(&searched, next_index); Ok(()) @@ -1181,18 +1212,18 @@ impl EventExec { } /// Move up 10 lines in normal mode and preview. - pub fn page_up(status: &mut Status) -> FmResult<()> { + pub fn event_page_up(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal | Mode::Preview => EventExec::event_page_up(status.selected()), + Mode::Normal | Mode::Preview => EventExec::page_up(status.selected()), _ => (), }; Ok(()) } /// Move down 10 lines in normal & preview mode. - pub fn page_down(status: &mut Status) -> FmResult<()> { + pub fn event_page_down(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal | Mode::Preview => EventExec::event_page_down(status.selected()), + Mode::Normal | Mode::Preview => EventExec::page_down(status.selected()), _ => (), }; Ok(()) @@ -1203,13 +1234,10 @@ impl EventExec { /// related action. /// In normal mode, it will open the file. /// Reset to normal mode afterwards. - pub fn enter(status: &mut Status) -> FmResult<()> { - let mut mode_coming_from = None; + pub fn event_enter(status: &mut Status) -> FmResult<()> { + let mut must_refresh = true; match status.selected_non_mut().mode { - Mode::InputSimple(InputSimple::Rename(last_mode)) => { - mode_coming_from = Some(last_mode); - EventExec::exec_rename(status.selected(), last_mode)? - } + Mode::InputSimple(InputSimple::Rename) => EventExec::exec_rename(status.selected())?, Mode::InputSimple(InputSimple::Newfile) => EventExec::exec_newfile(status.selected())?, Mode::InputSimple(InputSimple::Newdir) => EventExec::exec_newdir(status.selected())?, Mode::InputSimple(InputSimple::Chmod) => EventExec::exec_chmod(status)?, @@ -1220,10 +1248,9 @@ impl EventExec { Mode::Navigate(Navigate::Shortcut) => EventExec::exec_shortcut(status.selected())?, Mode::Navigate(Navigate::Trash) => EventExec::event_trash_restore_file(status)?, Mode::InputCompleted(InputCompleted::Exec) => EventExec::exec_exec(status.selected())?, - Mode::InputCompleted(InputCompleted::Search(last_mode)) => {< |