diff options
author | Canop <cano.petrole@gmail.com> | 2021-06-13 16:45:44 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2021-06-13 16:45:44 +0200 |
commit | dec7324fd505e41decf152492ae4942ffed36db0 (patch) | |
tree | 0caf0e1e5ce0f0a0191914527a3b5307850a976a /src/app | |
parent | 442e304c3f3ca867d09103301efee42da7ea969f (diff) |
`{root}` verb argument
Fix #395
Diffstat (limited to 'src/app')
-rw-r--r-- | src/app/app.rs | 31 | ||||
-rw-r--r-- | src/app/app_state.rs | 11 | ||||
-rw-r--r-- | src/app/cmd_context.rs | 2 | ||||
-rw-r--r-- | src/app/panel.rs | 2 | ||||
-rw-r--r-- | src/app/panel_state.rs | 22 |
5 files changed, 39 insertions, 29 deletions
diff --git a/src/app/app.rs b/src/app/app.rs index f9ea5b7..44217e2 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -10,6 +10,7 @@ use { launchable::Launchable, path::closest_dir, skin::*, + stage::Stage, task_sync::{Dam, Either}, verb::Internal, }, @@ -54,10 +55,6 @@ pub struct App { stage_panel: Option<PanelId>, - /// the current root, updated when a panel with this concept - /// becomes active - root: PathBuf, - /// an optional copy of the root for the --server shared_root: Option<Arc<Mutex<PathBuf>>>, @@ -99,7 +96,6 @@ impl App { created_panels_count: 1, preview_panel: None, stage_panel: None, - root: con.launch_args.root.clone(), shared_root: None, tx_seqs, rx_seqs, @@ -271,7 +267,6 @@ impl App { let mut error: Option<String> = None; let is_input_invocation = cmd.is_verb_invocated_from_input(); let app_cmd_context = AppCmdContext { - other_path: self.get_other_panel_path(), panel_skin, preview_panel: self.preview_panel, stage_panel: self.stage_panel, @@ -325,7 +320,6 @@ impl App { let new_input = self.panel().get_input_content(); let cmd = Command::from_raw(new_input, false); let app_cmd_context = AppCmdContext { - other_path: self.get_other_panel_path(), panel_skin, preview_panel: self.preview_panel, stage_panel: self.stage_panel, @@ -373,7 +367,6 @@ impl App { } 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, @@ -476,7 +469,6 @@ impl App { } if self.remove_state() { let app_cmd_context = AppCmdContext { - other_path: self.get_other_panel_path(), panel_skin, preview_panel: self.preview_panel, stage_panel: self.stage_panel, @@ -507,19 +499,21 @@ impl App { if let Some(text) = error { self.mut_panel().set_error(text); } - self.update_preview(con); - - if let Some(path) = self.state().selected_path() { - self.root = path.to_path_buf(); + app_state.other_panel_path = self.get_other_panel_path(); + if let Some(path) = self.state().tree_root() { + app_state.root = path.to_path_buf(); } + if let Some(shared_root) = &mut self.shared_root { if let Ok(mut root) = shared_root.lock() { - *root = self.root.clone(); + *root = app_state.root.clone(); } } + self.update_preview(con); + Ok(()) } @@ -616,7 +610,6 @@ impl App { if self.do_pending_task(app_state, con, dam) { self.update_preview(con); // the selection may have changed let app_cmd_context = AppCmdContext { - other_path: self.get_other_panel_path(), panel_skin: &skin.focused, preview_panel: self.preview_panel, stage_panel: self.stage_panel, @@ -676,7 +669,11 @@ impl App { let rx_events = event_source.receiver(); let mut dam = Dam::from(rx_events); let skin = AppSkin::new(conf, con.launch_args.no_style); - let mut app_state = AppState::default(); + let mut app_state = AppState { + stage: Stage::default(), + root: con.launch_args.root.clone(), + other_panel_path: None, + }; self.screen.clear_bottom_right_char(w, &skin.focused)?; @@ -689,7 +686,7 @@ impl App { #[cfg(unix)] let _server = con.launch_args.listen.as_ref() .map(|server_name| { - let shared_root = Arc::new(Mutex::new(self.root.clone())); + let shared_root = Arc::new(Mutex::new(app_state.root.clone())); let server = crate::net::Server::new( &server_name, self.tx_seqs.clone(), diff --git a/src/app/app_state.rs b/src/app/app_state.rs index 474aa00..4b20376 100644 --- a/src/app/app_state.rs +++ b/src/app/app_state.rs @@ -2,13 +2,22 @@ use { crate::{ stage::Stage, }, + std::path::PathBuf, }; /// global mutable state -#[derive(Debug, Default)] +#[derive(Debug)] pub struct AppState { pub stage: Stage, + + /// the current root, updated when a panel with this concept + /// becomes active or changes its root + pub root: PathBuf, + + /// the selected path in another panel than the currently + /// active one, if any + pub other_panel_path: Option<PathBuf>, } impl AppState { diff --git a/src/app/cmd_context.rs b/src/app/cmd_context.rs index f6a03d8..f5a955a 100644 --- a/src/app/cmd_context.rs +++ b/src/app/cmd_context.rs @@ -5,7 +5,6 @@ use { display::{Areas, Screen}, skin::PanelSkin, }, - std::path::PathBuf, }; /// short lived wrapping of a few things which are needed for the handling @@ -18,7 +17,6 @@ pub struct CmdContext<'c> { /// the part of the immutable command execution context which comes from the app pub struct AppCmdContext<'c> { - pub other_path: Option<PathBuf>, pub panel_skin: &'c PanelSkin, pub preview_panel: Option<PanelId>, // id of the app's preview panel pub stage_panel: Option<PanelId>, // id of the app's preview panel diff --git a/src/app/panel.rs b/src/app/panel.rs index 61cea36..6a2f97c 100644 --- a/src/app/panel.rs +++ b/src/app/panel.rs @@ -129,7 +129,7 @@ impl Panel { con: &AppContext, ) -> Result<Command, ProgramError> { let sel_info = self.states[self.states.len() - 1].sel_info(&app_state); - self.input.on_event(w, event, con, sel_info, self.state().get_mode()) + self.input.on_event(w, event, con, sel_info, app_state, self.state().get_mode()) } pub fn push_state(&mut self, new_state: Box<dyn PanelState>) { diff --git a/src/app/panel_state.rs b/src/app/panel_state.rs index fba66c4..94d45af 100644 --- a/src/app/panel_state.rs +++ b/src/app/panel_state.rs @@ -433,7 +433,7 @@ pub trait PanelState { if verb.needs_selection && !self.has_at_least_one_selection(app_state) { return Ok(CmdResult::error("This verb needs a selection")); } - if verb.needs_another_panel && cc.app.other_path.is_none() { + if verb.needs_another_panel && app_state.other_panel_path.is_none() { return Ok(CmdResult::error("This verb needs another panel")); } match &verb.execution { @@ -461,7 +461,7 @@ pub trait PanelState { let exec_builder = ExecutionStringBuilder::with_invocation( &verb.invocation_parser, self.sel_info(app_state), - &cc.app.other_path, + app_state, if let Some(inv) = invocation { &inv.args } else { @@ -478,7 +478,7 @@ pub trait PanelState { seq_ex: &SequenceExecution, invocation: Option<&VerbInvocation>, app_state: &mut AppState, - cc: &CmdContext, + _cc: &CmdContext, ) -> Result<CmdResult, ProgramError> { let sel_info = self.sel_info(app_state); if matches!(sel_info, SelInfo::More(_)) { @@ -490,7 +490,7 @@ pub trait PanelState { let exec_builder = ExecutionStringBuilder::with_invocation( &verb.invocation_parser, sel_info, - &cc.app.other_path, + app_state, if let Some(inv) = invocation { &inv.args } else { @@ -618,6 +618,11 @@ pub trait PanelState { } } + /// must return None if the state doesn't display a file tree + fn tree_root(&self) -> Option<&Path> { + None + } + fn selected_path(&self) -> Option<&Path>; fn selection(&self) -> Option<Selection<'_>>; @@ -719,7 +724,7 @@ pub trait PanelState { Status::new("No matching verb (*?* for the list of verbs)", true) } PrefixSearchResult::Match(_, verb) => { - self.get_verb_status(verb, invocation, sel_info, cc) + self.get_verb_status(verb, invocation, sel_info, cc, app_state) } PrefixSearchResult::Matches(completions) => Status::new( format!( @@ -744,7 +749,8 @@ pub trait PanelState { verb: &Verb, invocation: &VerbInvocation, sel_info: SelInfo<'_>, - cc: &CmdContext, + _cc: &CmdContext, + app_state: &AppState, ) -> Status { if sel_info.count_paths() > 1 { if let VerbExecution::External(external) = &verb.execution { @@ -757,13 +763,13 @@ pub trait PanelState { } // right now there's no check for sequences but they're inherently dangereous } - if let Some(err) = verb.check_args(&sel_info, invocation, &cc.app.other_path) { + if let Some(err) = verb.check_args(&sel_info, invocation, &app_state.other_panel_path) { Status::new(err, true) } else { Status::new( verb.get_status_markdown( sel_info, - &cc.app.other_path, + app_state, invocation, ), false, |