diff options
author | qkzk <qu3nt1n@gmail.com> | 2022-12-06 20:42:45 +0100 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2022-12-06 20:42:45 +0100 |
commit | 5e2e51c040f8de48be17579c7e717b36061ff13e (patch) | |
tree | 76c1f05cb9bcf270ffb470257793bccba53e7e43 | |
parent | fc211f60836223c72b91b1bbd557b049e66a3f4d (diff) |
move event & exec to separate source fileevent-action
-rw-r--r-- | src/action_map.rs | 68 | ||||
-rw-r--r-- | src/actioner.rs | 912 | ||||
-rw-r--r-- | src/event_exec.rs | 794 | ||||
-rw-r--r-- | src/lib.rs | 1 |
4 files changed, 896 insertions, 879 deletions
diff --git a/src/action_map.rs b/src/action_map.rs index be8d47b..b22cffc 100644 --- a/src/action_map.rs +++ b/src/action_map.rs @@ -1,6 +1,6 @@ use strum_macros::{Display, EnumString}; -use crate::actioner::Actioner; +use crate::event_exec::EventExec; use crate::fm_error::FmResult; use crate::status::Status; @@ -45,96 +45,96 @@ impl ActionMap { pub fn match_char(&self, status: &mut Status) -> FmResult<()> { let current_tab = status.selected(); match *self { - ActionMap::ToggleHidden => Actioner::event_toggle_hidden(current_tab), + ActionMap::ToggleHidden => EventExec::event_toggle_hidden(current_tab), ActionMap::CopyPaste => { - Actioner::event_copy_paste(current_tab); + EventExec::event_copy_paste(current_tab); Ok(()) } ActionMap::CutPaste => { - Actioner::event_cur_paste(current_tab); + EventExec::event_cur_paste(current_tab); Ok(()) } ActionMap::NewDir => { - Actioner::event_new_dir(current_tab); + EventExec::event_new_dir(current_tab); Ok(()) } ActionMap::NewFile => { - Actioner::event_new_file(current_tab); + EventExec::event_new_file(current_tab); Ok(()) } - ActionMap::Chmod => Actioner::event_chmod(status), + ActionMap::Chmod => EventExec::event_chmod(status), ActionMap::Exec => { - Actioner::event_exec(current_tab); + EventExec::event_exec(current_tab); Ok(()) } ActionMap::Goto => { - Actioner::event_goto(current_tab); + EventExec::event_goto(current_tab); Ok(()) } ActionMap::Rename => { - Actioner::event_rename(current_tab); + EventExec::event_rename(current_tab); Ok(()) } - ActionMap::ClearFlags => Actioner::event_clear_flags(status), - ActionMap::ToggleFlag => Actioner::event_toggle_flag(status), - ActionMap::Shell => Actioner::event_shell(current_tab), + ActionMap::ClearFlags => EventExec::event_clear_flags(status), + ActionMap::ToggleFlag => EventExec::event_toggle_flag(status), + ActionMap::Shell => EventExec::event_shell(current_tab), ActionMap::DeleteFile => { - Actioner::event_delete_file(current_tab); + EventExec::event_delete_file(current_tab); Ok(()) } - ActionMap::OpenFile => Actioner::event_open_file(current_tab), + ActionMap::OpenFile => EventExec::event_open_file(current_tab), ActionMap::Help => { - Actioner::event_help(current_tab); + EventExec::event_help(current_tab); Ok(()) } ActionMap::Search => { - Actioner::event_search(current_tab); + EventExec::event_search(current_tab); Ok(()) } ActionMap::RegexMatch => { - Actioner::event_regex_match(current_tab); + EventExec::event_regex_match(current_tab); Ok(()) } ActionMap::Quit => { - Actioner::event_quit(current_tab); + EventExec::event_quit(current_tab); Ok(()) } - ActionMap::FlagAll => Actioner::event_flag_all(status), - ActionMap::ReverseFlags => Actioner::event_reverse_flags(status), + ActionMap::FlagAll => EventExec::event_flag_all(status), + ActionMap::ReverseFlags => EventExec::event_reverse_flags(status), ActionMap::Jump => { - Actioner::event_jump(status); + EventExec::event_jump(status); Ok(()) } ActionMap::History => { - Actioner::event_history(current_tab); + EventExec::event_history(current_tab); Ok(()) } ActionMap::NvimFilepicker => { - Actioner::event_nvim_filepicker(current_tab); + EventExec::event_nvim_filepicker(current_tab); Ok(()) } ActionMap::Sort => { - Actioner::event_sort(current_tab); + EventExec::event_sort(current_tab); Ok(()) } - ActionMap::Symlink => Actioner::event_symlink(status), - ActionMap::Preview => Actioner::event_preview(current_tab), + ActionMap::Symlink => EventExec::event_symlink(status), + ActionMap::Preview => EventExec::event_preview(current_tab), ActionMap::Shortcut => { - Actioner::event_shortcut(current_tab); + EventExec::event_shortcut(current_tab); Ok(()) } - ActionMap::Bulkrename => Actioner::event_bulkrename(status), + ActionMap::Bulkrename => EventExec::event_bulkrename(status), ActionMap::MarksNew => { - Actioner::event_marks_new(status); + EventExec::event_marks_new(status); Ok(()) } ActionMap::MarksJump => { - Actioner::event_marks_jump(status); + EventExec::event_marks_jump(status); Ok(()) } - ActionMap::Filter => Actioner::event_filter(status.selected()), - ActionMap::Back => Actioner::event_back(status.selected()), - ActionMap::Home => Actioner::event_home(status.selected()), + ActionMap::Filter => EventExec::event_filter(status.selected()), + ActionMap::Back => EventExec::event_back(status.selected()), + ActionMap::Home => EventExec::event_home(status.selected()), } } } diff --git a/src/actioner.rs b/src/actioner.rs index 9bc6eef..760a89e 100644 --- a/src/actioner.rs +++ b/src/actioner.rs @@ -1,31 +1,10 @@ -use std::path::PathBuf; - use tuikit::prelude::{Event, Key, MouseButton}; -use crate::bulkrename::Bulkrename; -use crate::compress::decompress; -use crate::copy_move::CopyMove; -use crate::fileinfo::{FileKind, PathContent, SortBy}; -use crate::fm_error::{FmError, FmResult}; +use crate::event_exec::EventExec; +use crate::fm_error::FmResult; use crate::keybindings::Keybindings; -use crate::last_edition::LastEdition; use crate::mode::{MarkAction, Mode}; -use crate::preview::Preview; use crate::status::Status; -use crate::tab::Tab; -use crate::term_manager::MIN_WIDTH_FOR_DUAL_PANE; - -use std::borrow::Borrow; -use std::cmp::min; -use std::fs; -use std::path; - -use copypasta::{ClipboardContext, ClipboardProvider}; -use log::info; - -use crate::content_window::ContentWindow; -use crate::filter::FilterKind; -use crate::opener::execute_in_child; /// Struct which mutates `tabs.selected().. /// Holds a mapping which can't be static since it's read from a config file. @@ -52,7 +31,7 @@ impl Actioner { Event::Key(Key::Backspace) => Self::backspace(status), Event::Key(Key::Ctrl('d')) => Self::delete(status), Event::Key(Key::Ctrl('q')) => Self::escape(status), - Event::Key(Key::Char(c)) => self.char(status, c), + Event::Key(Key::Char(c)) => Self::char(status, c, &self.binds), Event::Key(Key::Home) => Self::home(status), Event::Key(Key::End) => Self::end(status), Event::Key(Key::PageDown) => Self::page_down(status), @@ -73,26 +52,28 @@ impl Actioner { Event::Key(Key::Ctrl('f')) => Self::ctrl_f(status), Event::Key(Key::Ctrl('c')) => Self::ctrl_c(status), Event::Key(Key::Ctrl('p')) => Self::ctrl_p(status), - Event::Key(Key::Ctrl('r')) => Self::refresh_selected_view(status), + Event::Key(Key::Ctrl('r')) => EventExec::refresh_selected_view(status), Event::Key(Key::Ctrl('x')) => Self::ctrl_x(status), - Event::User(_) => Self::refresh_selected_view(status), - Event::Resize { width, height } => Self::resize(status, width, height), + Event::User(_) => EventExec::refresh_selected_view(status), + Event::Resize { width, height } => EventExec::resize(status, width, height), _ => Ok(()), } } /// Leaving a mode reset the window fn escape(status: &mut Status) -> FmResult<()> { - Self::event_normal(status.selected()) + EventExec::event_normal(status.selected()) } /// Move one line up fn up(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal | Mode::Preview | Mode::Help => Self::event_up_one_row(status.selected()), - Mode::Jump => Self::event_jumplist_prev(status), - Mode::History => Self::event_history_prev(status.selected()), - Mode::Shortcut => Self::event_shortcut_prev(status.selected()), + Mode::Normal | Mode::Preview | Mode::Help => { + EventExec::event_up_one_row(status.selected()) + } + Mode::Jump => EventExec::event_jumplist_prev(status), + Mode::History => EventExec::event_history_prev(status.selected()), + Mode::Shortcut => EventExec::event_shortcut_prev(status.selected()), Mode::Goto | Mode::Exec | Mode::Search => { status.selected().completion.prev(); } @@ -105,11 +86,11 @@ impl Actioner { fn down(status: &mut Status) -> FmResult<()> { match status.selected().mode { Mode::Normal | Mode::Preview | Mode::Help => { - Self::event_down_one_row(status.selected()) + EventExec::event_down_one_row(status.selected()) } - Mode::Jump => Self::event_jumplist_next(status), - Mode::History => Self::event_history_next(status.selected()), - Mode::Shortcut => Self::event_shortcut_next(status.selected()), + Mode::Jump => EventExec::event_jumplist_next(status), + Mode::History => EventExec::event_history_next(status.selected()), + Mode::Shortcut => EventExec::event_shortcut_next(status.selected()), Mode::Goto | Mode::Exec | Mode::Search => { status.selected().completion.next(); } @@ -121,7 +102,7 @@ impl Actioner { /// Move left in a string, move to parent in normal mode fn left(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal => Self::event_move_to_parent(status.selected()), + Mode::Normal => EventExec::event_move_to_parent(status.selected()), Mode::Rename | Mode::Chmod | Mode::Newdir @@ -131,7 +112,7 @@ impl Actioner { | Mode::Goto | Mode::RegexMatch | Mode::Filter => { - Self::event_move_cursor_left(status.selected()); + EventExec::event_move_cursor_left(status.selected()); Ok(()) } @@ -142,7 +123,7 @@ impl Actioner { /// Move right in a string, move to children in normal mode. fn right(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal => Self::exec_file(status.selected()), + Mode::Normal => EventExec::exec_file(status.selected()), Mode::Rename | Mode::Chmod | Mode::Newdir @@ -152,7 +133,7 @@ impl Actioner { | Mode::Goto | Mode::RegexMatch | Mode::Filter => { - Self::event_move_cursor_right(status.selected()); + EventExec::event_move_cursor_right(status.selected()); Ok(()) } _ => Ok(()), @@ -171,7 +152,7 @@ impl Actioner { | Mode::Goto | Mode::RegexMatch | Mode::Filter => { - Self::event_delete_char_left(status.selected()); + EventExec::event_delete_char_left(status.selected()); Ok(()) } Mode::Normal => Ok(()), @@ -192,7 +173,7 @@ impl Actioner { | Mode::Goto | Mode::RegexMatch | Mode::Filter => { - Self::event_delete_chars_right(status.selected()); + EventExec::event_delete_chars_right(status.selected()); Ok(()) } _ => Ok(()), @@ -202,8 +183,8 @@ impl Actioner { /// Move to top or beggining of line. fn home(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal | Mode::Preview | Mode::Help => Self::event_go_top(status.selected()), - _ => Self::event_cursor_home(status.selected()), + Mode::Normal | Mode::Preview | Mode::Help => EventExec::event_go_top(status.selected()), + _ => EventExec::event_cursor_home(status.selected()), }; Ok(()) } @@ -211,8 +192,10 @@ impl Actioner { /// Move to end or end of line. fn end(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal | Mode::Preview | Mode::Help => Self::event_go_bottom(status.selected()), - _ => Self::event_cursor_end(status.selected()), + Mode::Normal | Mode::Preview | Mode::Help => { + EventExec::event_go_bottom(status.selected()) + } + _ => EventExec::event_cursor_end(status.selected()), }; Ok(()) } @@ -220,7 +203,9 @@ impl Actioner { /// Move down 10 rows fn page_down(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal | Mode::Preview | Mode::Help => Self::event_page_down(status.selected()), + Mode::Normal | Mode::Preview | Mode::Help => { + EventExec::event_page_down(status.selected()) + } _ => (), }; Ok(()) @@ -229,7 +214,9 @@ impl Actioner { /// Move up 10 rows fn page_up(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Normal | Mode::Preview | Mode::Help => Self::event_page_up(status.selected()), + Mode::Normal | Mode::Preview | Mode::Help => { + EventExec::event_page_up(status.selected()) + } _ => (), }; Ok(()) @@ -238,19 +225,19 @@ impl Actioner { /// Execute a command fn enter(status: &mut Status) -> FmResult<()> { match status.selected().mode { - Mode::Rename => Self::exec_rename(status.selected())?, - Mode::Newfile => Self::exec_newfile(status.selected())?, - Mode::Newdir => Self::exec_newdir(status.selected())?, - Mode::Chmod => Self::exec_chmod(status)?, - Mode::Exec => Self::exec_exec(status.selected())?, - Mode::Search => Self::exec_search(status.selected()), - Mode::Goto => Self::exec_goto(status.selected())?, - Mode::RegexMatch => Self::exec_regex(status)?, - Mode::Jump => Self::exec_jump(status)?, - Mode::History => Self::exec_history(status.selected())?, - Mode::Shortcut => Self::exec_shortcut(status.selected())?, - Mode::Filter => Self::exec_filter(status.selected())?, - Mode::Normal => Self::exec_file(status.selected())?, + Mode::Rename => EventExec::exec_rename(status.selected())?, + Mode::Newfile => EventExec::exec_newfile(status.selected())?, + Mode::Newdir => EventExec::exec_newdir(status.selected())?, + Mode::Chmod => EventExec::exec_chmod(status)?, + Mode::Exec => EventExec::exec_exec(status.selected())?, + Mode::Search => EventExec::exec_search(status.selected()), + Mode::Goto => EventExec::exec_goto(status.selected())?, + Mode::RegexMatch => EventExec::exec_regex(status)?, + Mode::Jump => EventExec::exec_jump(status)?, + Mode::History => EventExec::exec_history(status.selected())?, + Mode::Shortcut => EventExec::exec_shortcut(status.selected())?, + Mode::Filter => EventExec::exec_filter(status.selected())?, + Mode::Normal => EventExec::exec_file(status.selected())?, Mode::NeedConfirmation | Mode::Help | Mode::Sort | Mode::Preview | Mode::Marks(_) => (), }; @@ -262,14 +249,14 @@ impl Actioner { /// Select this file fn left_click(status: &mut Status, row: u16) { if let Mode::Normal = status.selected().mode { - Self::event_select_row(status.selected(), row) + EventExec::event_select_row(status.selected(), row) } } /// Open a directory or a file fn right_click(status: &mut Status, row: u16) { if let Mode::Normal = status.selected().mode { - let _ = Self::event_right_click(status.selected(), row); + let _ = EventExec::event_right_click(status.selected(), row); } } @@ -278,7 +265,7 @@ impl Actioner { fn tab(status: &mut Status) -> FmResult<()> { match status.selected().mode { Mode::Goto | Mode::Exec | Mode::Search => { - Self::event_replace_input_with_completion(status.selected()) + EventExec::event_replace_input_with_completion(status.selected()) } Mode::Normal => status.next(), _ => (), @@ -301,825 +288,60 @@ impl Actioner { fn ctrl_c(status: &mut Status) -> FmResult<()> { if let Mode::Normal = status.selected_non_mut().mode { - return Self::event_filename_to_clipboard(status.selected()); + return EventExec::event_filename_to_clipboard(status.selected()); } Ok(()) } fn ctrl_p(status: &mut Status) -> FmResult<()> { if let Mode::Normal = status.selected_non_mut().mode { - return Self::event_filepath_to_clipboard(status.selected()); + return EventExec::event_filepath_to_clipboard(status.selected()); } Ok(()) } - fn refresh_selected_view(status: &mut Status) -> FmResult<()> { - status.selected().refresh_view() - } - fn ctrl_x(status: &mut Status) -> FmResult<()> { - Self::event_decompress(status.selected()) + EventExec::event_decompress(status.selected()) } /// Match read key to a relevent event, depending on keybindings. /// Keybindings are read from `Config`. - fn char(&self, status: &mut Status, c: char) -> FmResult<()> { + fn char(status: &mut Status, c: char, binds: &Keybindings) -> FmResult<()> { match status.selected().mode { Mode::Newfile | Mode::Newdir | Mode::Chmod | Mode::Rename | Mode::Filter => { - Self::event_text_insertion(status.selected(), c); + EventExec::event_text_insertion(status.selected(), c); Ok(()) } Mode::RegexMatch => { - Self::event_text_insertion(status.selected(), c); + EventExec::event_text_insertion(status.selected(), c); status.select_from_regex()?; Ok(()) } Mode::Goto | Mode::Exec | Mode::Search => { - Self::event_text_insert_and_complete(status.selected(), c) + EventExec::event_text_insert_and_complete(status.selected(), c) } - Mode::Normal => match self.binds.get(&c) { + Mode::Normal => match binds.get(&c) { Some(event_char) => event_char.match_char(status), None => Ok(()), }, - Mode::Help | Mode::Preview | Mode::Shortcut => Self::event_normal(status.selected()), + Mode::Help | Mode::Preview | Mode::Shortcut => { + EventExec::event_normal(status.selected()) + } Mode::Jump => Ok(()), Mode::History => Ok(()), Mode::NeedConfirmation => { if c == 'y' { - let _ = Self::exec_last_edition(status); + let _ = EventExec::exec_last_edition(status); } - Self::event_leave_need_confirmation(status.selected()); + EventExec::event_leave_need_confirmation(status.selected()); Ok(()) } - Mode::Marks(MarkAction::Jump) => Self::exec_marks_jump(status, c), - Mode::Marks(MarkAction::New) => Self::exec_marks_new(status, c), + Mode::Marks(MarkAction::Jump) => EventExec::exec_marks_jump(status, c), + Mode::Marks(MarkAction::New) => EventExec::exec_marks_new(status, c), Mode::Sort => { - Self::event_leave_sort(status.selected(), c); + EventExec::event_leave_sort(status.selected(), c); Ok(()) } } } - - fn resize(status: &mut Status, width: usize, height: usize) -> FmResult<()> { - if width < MIN_WIDTH_FOR_DUAL_PANE { - status.select_tab(0)?; - status.set_dual_pane(false); - } else { - status.set_dual_pane(true); - } - status.selected().set_height(height); - Self::refresh_selected_view(status)?; - Ok(()) - } - - pub fn event_clear_flags(status: &mut Status) -> FmResult<()> { - status.flagged.clear(); - Ok(()) - } - - pub fn event_flag_all(status: &mut Status) -> FmResult<()> { - status.tabs[status.index] - .path_content - .files - .iter() - .for_each(|file| { - status.flagged.insert(file.path.clone()); - }); - status.reset_statuses() - } - - pub fn event_reverse_flags(status: &mut Status) -> FmResult<()> { - // for file in self.selected().path_content.files.iter() { - // self.toggle_flag_on_path(file.path.clone()) - // } - - status.tabs[status.index] - .path_content - .files - .iter() - .for_each(|file| { - if status.flagged.contains(&file.path.clone()) { - status.flagged.remove(&file.path.clone()); - } else { - status.flagged.insert(file.path.clone()); - } - }); - status.reset_statuses() - } - pub fn event_toggle_flag(status: &mut Status) -> FmResult<()> { - let file = status.tabs[status.index] - .path_content - .selected_file() - .ok_or_else(|| FmError::new("No selected file"))?; - status.toggle_flag_on_path(file.path.clone()); - Self::event_down_one_row(status.selected()); - Ok(()) - } - - pub fn event_jumplist_next(status: &mut Status) { - if status.jump_index < status.flagged.len() { - status.jump_index += 1; - } - } - - pub fn event_jumplist_prev(status: &mut Status) { - if status.jump_index > 0 { - status.jump_index -= 1; - } - } - - pub fn event_chmod(status: &mut Status) -> FmResult<()> { - if status.selected().path_content.files.is_empty() { - return Ok(()); - } - status.selected().mode = Mode::Chmod; - if status.flagged.is_empty() { - status.flagged.insert( - status.tabs[status.index] - .path_content - .selected_file() - .unwrap() - .path - .clone(), - ); - }; - status.reset_statuses() - } - - pub fn event_jump(status: &mut Status) { - if !status.flagged.is_empty() { - status.jump_index = 0; - status.selected().mode = Mode::Jump - } - } - - pub fn event_marks_new(status: &mut Status) { - status.selected().mode = Mode::Marks(MarkAction::New) - } - - pub fn event_marks_jump(status: &mut Status) { - status.selected().mode = Mode::Marks(MarkAction::Jump) - } - - 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()) - } - - pub fn exec_marks_jump(status: &mut Status, c: char) -> FmResult<()> { - if let Some(path) = status.marks.get(c) { - let path = path.to_owned(); - status.selected().history.push(&path); - status.selected().path_content = PathContent::new(path, status.selected().show_hidden)?; - }; - Self::event_normal(status.selected()) - } - - /// Creates a symlink of every flagged file to the current directory. - pub fn event_symlink(status: &mut Status) -> FmResult<()> { - for oldpath in status.flagged.iter() { - let newpath = status.tabs[status.index].path_content.path.clone().join( - oldpath - .as_path() - .file_name() - .ok_or_else(|| FmError::new("File not found"))?, - ); - std::os::unix::fs::symlink(oldpath, newpath)?; - } - status.clear_flags_and_reset_view() - } - - pub fn event_bulkrename(status: &mut Status) -> FmResult<()> { - Bulkrename::new(status.filtered_flagged_files())? - .rename(&status.selected_non_mut().opener)?; - status.selected().refresh_view() - } - - fn exec_copy_paste(status: &mut Status) -> FmResult<()> { - status.cut_or_copy_flagged_files(CopyMove::Copy) - } - - fn exec_cut_paste(status: &mut Status) -> FmResult<()> { - status.cut_or_copy_flagged_files(CopyMove::Move) - } - - fn exec_delete_files(status: &mut Status) -> FmResult<()> { - for pathbuf in status.flagged.iter() { - if pathbuf.is_dir() { - std::fs::remove_dir_all(pathbuf)?; - } else { - std::fs::remove_file(pathbuf)?; - } - } - status.clear_flags_and_reset_view() - } - - pub fn exec_chmod(status: &mut Status) -> FmResult<()> { - if status.selected().input.string.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.iter() { - Status::set_permissions(path.clone(), permissions)? - } - status.flagged.clear() - } - status.selected().refresh_view()?; - status.reset_statuses() - } - pub fn _exec_last_edition(status: &mut Status) -> FmResult<()> { - match status.selected().last_edition { - LastEdition::Delete => Self::exec_delete_files(status), - LastEdition::CutPaste => Self::exec_cut_paste(status), - LastEdition::CopyPaste => Self::exec_copy_paste(status), - LastEdition::Nothing => Ok(()), - } - } - - pub fn exec_jump(status: &mut Status) -> FmResult<()> { - status.selected().input.string.clear(); - let jump_list: Vec<&PathBuf> = status.flagged.iter().collect(); - let jump_target = jump_list[status.jump_index].clone(); - let target_dir = match jump_target.parent() { - Some(parent) => parent.to_path_buf(), - None => jump_target.clone(), - }; - status.selected().history.push(&target_dir); - status.selected().path_content = - PathContent::new(target_dir, status.selected().show_hidden)?; - if let Some(index) = status.find_jump_target(&jump_target) { - status.selected().line_index = index; - } else { - status.selected().line_index = 0; - } - - let s_index = status.tabs[status.index].line_index; - status.tabs[status.index].path_content.select_index(s_index); - let len = status.tabs[status.index].path_content.files.len(); - status.selected().window.reset(len); - status.selected().window.scroll_to(s_index); - Ok(()) - } - - pub fn exec_last_edition(status: &mut Status) -> FmResult<()> { - Self::_exec_last_edition(status)?; - status.selected().mode = Mode::Normal; - status.selected().last_edition = LastEdition::Nothing; - Ok(()) - } - - pub fn exec_regex(status: &mut Status) -> Result<(), regex::Error> { - status.select_from_regex()?; - status.selected().input.reset(); - Ok(()) - } - - pub fn event_normal(tab: &mut Tab) -> FmResult<()> { - tab.input.reset(); - tab.completion.reset(); - tab.path_content.reset_files()?; - tab.window.reset(tab.path_content.files.len()); - tab.mode = Mode::Normal; - tab.preview = Preview::empty(); - Ok(()) - } - - pub fn event_up_one_row(tab: &mut Tab) { - match tab.mode { - Mode::Normal => { - tab.path_content.select_prev(); - if tab.line_index > 0 { - tab.line_index -= 1; - } - } - Mode::Preview | Mode::Help => tab.line_index = tab.window.top, - _ => (), - } - tab.window.scroll_up_one(tab.line_index); - } - - pub fn event_down_one_row(tab: &mut Tab) { - match tab.mode { - Mode::Normal => { - tab.path_content.select_next(); - let max_line = tab.path_content.files.len(); - if max_line >= ContentWindow::WINDOW_MARGIN_TOP - && tab.line_index < max_line - ContentWindow::WINDOW_MARGIN_TOP - { - tab.line_index += 1; - } - } - Mode::Preview | Mode::Help => tab.line_index = tab.window.bottom, - _ => (), - } - tab.window.scroll_down_one(tab.line_index); - } - - pub fn event_go_top(tab: &mut Tab) { - if let Mode::Normal = tab.mode { - tab.path_content.select_index(0); - } - tab.line_index = 0; - tab.window.scroll_to(0); - } - - pub fn event_page_up(tab: &mut Tab) { - let scroll_up: usize = if let Mode::Normal = tab.mode { - 10 - } else { - tab.height - }; - let up_index = if tab.line_index > scroll_up { - tab.line_index - scroll_up - } else { - 0 - }; - if let Mode::Normal = tab.mode { - tab.path_content.select_index(up_index); - } - tab.line_index = up_index; - tab.window.scroll_to(up_index); - } - - pub fn event_go_bottom(tab: &mut Tab) { - let last_index: usize; - if let Mode::Normal = tab.mode { - last_index = tab.path_content.files.len() - 1; - tab.path_content.select_index(last_index); - } else { - last_index = tab.preview.len() - 1; - } - tab.line_index = last_index; - tab.window.scroll_to(last_index); - } - - pub fn event_cursor_home(tab: &mut Tab) { - tab.input.cursor_start() - } - - pub fn event_cursor_end(tab: &mut Tab) { - tab.input.cursor_end() - } - - pub fn event_page_down(tab: &mut Tab) { - let down_index: usize; - if let Mode::Normal = tab.mode { - down_index = min(tab.path_content.files.len() - 1, tab.line_index + 10); - tab.path_content.select_index(down_index); - } else { - down_index = min(tab.preview.len() - 1, tab.line_index + 30) - } - tab.line_index = down_index; - tab.window.scroll_to(down_index); - } - - pub fn event_select_row(tab: &mut Tab, row: u16) { - tab.line_index = (row - 2).into(); - tab.path_content.select_index(tab.line_index); - tab.window.scroll_to(tab.line_index) - } - - pub fn event_shortcut_next(tab: &mut Tab) { - tab.shortcut.next() - } - - pub fn event_shortcut_prev(tab: &mut Tab) { - tab.shortcut.prev() - } - - pub fn event_history_next(tab: &mut Tab) { - tab.history.next() - } - - pub fn event_history_prev(tab: &mut Tab) { - tab.history.prev() - } - - pub fn event_move_to_parent(tab: &mut Tab) -> FmResult<()> { - let parent = tab.path_content.path.parent(); - let path = path::PathBuf::from( - parent.ok_or_else(|| FmError::new("Root directory has no parent"))?, - ); - tab.history.push(&path); - tab.path_content = PathContent::new(path, tab.show_hidden)?; - tab.window.reset(tab.path_content.files.len()); - tab.line_index = 0; - tab.input.cursor_start(); - Ok(()) - } - - pub fn event_move_cursor_left(tab: &mut Tab) { - tab.input.cursor_left() - } - - pub fn exec_file(tab: &mut Tab) -> FmResult<()> { - if tab.path_content.is_empty() { - return Ok(()); - } - if tab.path_content.is_selected_dir()? { - tab.go_to_child() - } else { - Self::event_open_file(tab) - } - } - - pub fn event_move_cursor_right(tab: &mut Tab) { - tab.input.cursor_right() - } - < |