diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/app/app.rs | 116 | ||||
-rw-r--r-- | src/app/panel_state.rs | 3 | ||||
-rw-r--r-- | src/app/state_type.rs | 2 | ||||
-rw-r--r-- | src/verb/internal.rs | 1 | ||||
-rw-r--r-- | website/docs/conf_verbs.md | 1 |
6 files changed, 88 insertions, 36 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 175ea91..a6f5080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - `:rename` built-in verb, best used with its keyboard shortcut F2 - new verb argument: `auto_exec` - new standard verb arguments: `{file-stem}`, `{file-extension}`, and `{file-dot-extension}`, +- new `:toggle_second_tree` internal - Fix #388 - fix a few minor bugs <a name="v1.4.0"></a> diff --git a/src/app/app.rs b/src/app/app.rs index 9dbab9c..fd21e35 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -8,6 +8,7 @@ use { errors::ProgramError, file_sum, git, launchable::Launchable, + path::closest_dir, skin::*, task_sync::{Dam, Either}, verb::Internal, @@ -344,47 +345,92 @@ impl App { self.tx_seqs.send(sequence).unwrap(); } HandleInApp(internal) => { - let new_active_panel_idx = match internal { - Internal::panel_left => { - // we're not here to create a panel, this is handled in the state - // we're here because the state wants us to either move to the panel - // to the left, or close the rightest one - if self.active_panel_idx == 0 { - self.close_panel(self.panels.len().get()-1); - None - } else { - Some(self.active_panel_idx - 1) + match internal { + Internal::panel_left | Internal::panel_right => { + let new_active_panel_idx = if internal == Internal::panel_left { + // we're not here to create a panel, this is handled in the state + // we're here because the state wants us to either move to the panel + // to the left, or close the rightest one + if self.active_panel_idx == 0 { + self.close_panel(self.panels.len().get()-1); + None + } else { + Some(self.active_panel_idx - 1) + } + } else { // panel_right + // we're not here to create panels (it's done in the state). + // So we either move to the right or close the leftes panel + if self.active_panel_idx + 1 == self.panels.len().get() { + self.close_panel(0); + None + } else { + Some(self.active_panel_idx + 1) + } + }; + if let Some(idx) = new_active_panel_idx { + if is_input_invocation { + self.mut_panel().clear_input(); + } + self.active_panel_idx = idx; + let app_cmd_context = AppCmdContext { + other_path: self.get_other_panel_path(), + panel_skin, + preview_panel: self.preview_panel, + stage_panel: self.stage_panel, + screen: self.screen, + con, + }; + self.mut_panel().refresh_input_status(app_state, &app_cmd_context); } } - Internal::panel_right => { - // we're not here to create panels (it's done in the state). - // So we either move to the right or close the leftes panel - if self.active_panel_idx + 1 == self.panels.len().get() { - self.close_panel(0); - None + Internal::toggle_second_tree => { + let panels_count = self.panels.len().get(); + let trees_count = self.panels.iter() + .filter(|p| p.state().get_type() == PanelStateType::Tree) + .count(); + if trees_count < 2 { + // we open a tree, closing a panel if necessary + if panels_count >= con.max_panels_count { + for i in (0..panels_count).rev() { + if self.panels[i].state().get_type() != PanelStateType::Tree { + self.close_panel(i); + break; + } + } + } + if let Some(selected_path) = self.state().selected_path() { + let dir = closest_dir(selected_path); + if let Ok(Some(new_state)) = BrowserState::new( + dir, + self.state().tree_options().without_pattern(), + self.screen, + con, + &Dam::unlimited(), + ) { + if let Err(s) = self.new_panel( + Box::new(new_state), + PanelPurpose::None, + HDir::Right, + is_input_invocation, + con, + ) { + error = Some(s); + } + } + } } else { - Some(self.active_panel_idx + 1) + // we close the rightest tree + for i in (0..panels_count).rev() { + if self.panels[i].state().get_type() == PanelStateType::Tree { + self.close_panel(i); + break; + } + } } } _ => { - debug!("unhandled propagated internal. cmd={:?}", &cmd); - None - } - }; - if let Some(idx) = new_active_panel_idx { - if is_input_invocation { - self.mut_panel().clear_input(); + info!("unhandled propagated internal. cmd={:?}", &cmd); } - self.active_panel_idx = idx; - let app_cmd_context = AppCmdContext { - other_path: self.get_other_panel_path(), - panel_skin, - preview_panel: self.preview_panel, - stage_panel: self.stage_panel, - screen: self.screen, - con, - }; - self.mut_panel().refresh_input_status(app_state, &app_cmd_context); } } Keep => { @@ -494,7 +540,7 @@ impl App { state: Box<dyn PanelState>, purpose: PanelPurpose, direction: HDir, - is_input_invocation: bool, + is_input_invocation: bool, // if true we clean the input con: &AppContext, ) -> Result<(), String> { match state.get_type() { diff --git a/src/app/panel_state.rs b/src/app/panel_state.rs index bc439aa..14acbe1 100644 --- a/src/app/panel_state.rs +++ b/src/app/panel_state.rs @@ -302,6 +302,9 @@ pub trait PanelState { Internal::panel_right => { CmdResult::HandleInApp(Internal::panel_right) } + Internal::toggle_second_tree => { + CmdResult::HandleInApp(Internal::toggle_second_tree) + } Internal::clear_stage => { app_state.stage.clear(); if let Some(panel_id) = cc.app.stage_panel { diff --git a/src/app/state_type.rs b/src/app/state_type.rs index 7ceecfb..04f3fa4 100644 --- a/src/app/state_type.rs +++ b/src/app/state_type.rs @@ -1,7 +1,7 @@ /// one of the types of state that you could /// find in a panel today -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum PanelStateType { /// The standard browsing tree diff --git a/src/verb/internal.rs b/src/verb/internal.rs index 71fd6e6..4c32681 100644 --- a/src/verb/internal.rs +++ b/src/verb/internal.rs @@ -127,6 +127,7 @@ Internals! { toggle_perm: "toggle showing file permissions" false, toggle_sizes: "toggle showing sizes" false, toggle_trim_root: "toggle removing nodes at first level too" false, + toggle_second_tree: "toggle display of a second tree panel" true, total_search: "search again but on all children" false, up_tree: "focus the parent of the current root" true, } diff --git a/website/docs/conf_verbs.md b/website/docs/conf_verbs.md index 7560692..bea725d 100644 --- a/website/docs/conf_verbs.md +++ b/website/docs/conf_verbs.md @@ -356,6 +356,7 @@ invocation | default key | default shortcut | behavior / details :toggle_preview | - | - | toggle display of the preview panel :toggle_sizes | - | - | toggle the size mode :toggle_trim_root | - | - | toggle trimming of top level files in tree display +:toggle_second_tree | - | - | toggle displaying a second tree :up_tree | - | - | focus the parent of the current root :stage | <kbd>+</kbd> | - | add selection to staging area :unstage | <kbd>-</kbd> | - | remove selection from staging area |