diff --git a/benches/navigation.rs b/benches/navigation.rs index a0987f5..4c3a054 100644 --- a/benches/navigation.rs +++ b/benches/navigation.rs @@ -8,21 +8,26 @@ fn criterion_benchmark(c: &mut Criterion) { fs::File::create(format!("/tmp/xplr_bench/{}", i)).unwrap(); }); - let app = app::App::create("/tmp/xplr_bench".into()) - .expect("failed to create app") - .handle_task(app::Task::new( - app::MsgIn::External(app::ExternalMsg::ChangeDirectory("/tmp/xplr_bench".into())), - None, - )) + let mut app = app::App::create("/tmp/xplr_bench".into()).expect("failed to create app"); + + app = app + .clone() + .handle_task( + app::Task::new( + app::MsgIn::External(app::ExternalMsg::ChangeDirectory("/tmp/xplr_bench".into())), + None, + ), + &app.clone(), + ) .unwrap(); c.bench_function("focus next item", |b| { b.iter(|| { app.clone() - .handle_task(app::Task::new( - app::MsgIn::External(app::ExternalMsg::FocusNext), - None, - )) + .handle_task( + app::Task::new(app::MsgIn::External(app::ExternalMsg::FocusNext), None), + &app.clone(), + ) .unwrap() }) }); @@ -30,10 +35,10 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("focus previous item", |b| { b.iter(|| { app.clone() - .handle_task(app::Task::new( - app::MsgIn::External(app::ExternalMsg::FocusPrevious), - None, - )) + .handle_task( + app::Task::new(app::MsgIn::External(app::ExternalMsg::FocusPrevious), None), + &app.clone(), + ) .unwrap() }) }); @@ -41,10 +46,10 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("focus first item", |b| { b.iter(|| { app.clone() - .handle_task(app::Task::new( - app::MsgIn::External(app::ExternalMsg::FocusFirst), - None, - )) + .handle_task( + app::Task::new(app::MsgIn::External(app::ExternalMsg::FocusFirst), None), + &app.clone(), + ) .unwrap() }) }); @@ -52,10 +57,10 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("focus last item", |b| { b.iter(|| { app.clone() - .handle_task(app::Task::new( - app::MsgIn::External(app::ExternalMsg::FocusLast), - None, - )) + .handle_task( + app::Task::new(app::MsgIn::External(app::ExternalMsg::FocusLast), None), + &app.clone(), + ) .unwrap() }) }); @@ -63,15 +68,15 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("leave and enter directory", |b| { b.iter(|| { app.clone() - .handle_task(app::Task::new( - app::MsgIn::External(app::ExternalMsg::Back), - None, - )) + .handle_task( + app::Task::new(app::MsgIn::External(app::ExternalMsg::Back), None), + &app.clone(), + ) .unwrap() - .handle_task(app::Task::new( - app::MsgIn::External(app::ExternalMsg::Enter), - None, - )) + .handle_task( + app::Task::new(app::MsgIn::External(app::ExternalMsg::Enter), None), + &app.clone(), + ) .unwrap() }) }); diff --git a/src/app.rs b/src/app.rs index 8898202..0b2dfae 100644 --- a/src/app.rs +++ b/src/app.rs @@ -11,6 +11,7 @@ use std::collections::VecDeque; use std::env; use std::fs; use std::io; +use std::io::prelude::*; use std::path::PathBuf; pub const TEMPLATE_TABLE_ROW: &str = "TEMPLATE_TABLE_ROW"; @@ -1269,6 +1270,8 @@ impl App { )); } + fs::write(&app.pipe().global_help_menu_out, app.global_help_menu_str())?; + Ok(app) } @@ -1287,10 +1290,10 @@ impl App { self } - pub fn handle_task(self, task: Task) -> Result { + pub fn handle_task(self, task: Task, last_app: &Self) -> Result { match task.msg { MsgIn::Internal(msg) => self.handle_internal(msg), - MsgIn::External(msg) => self.handle_external(msg, task.key), + MsgIn::External(msg) => self.handle_external(msg, task.key, last_app), } } @@ -1301,7 +1304,7 @@ impl App { } } - fn handle_external(self, msg: ExternalMsg, key: Option) -> Result { + fn handle_external(self, msg: ExternalMsg, key: Option, last_app: &Self) -> Result { if self.config().general.read_only.unwrap_or_default() && !msg.is_read_only() { self.log_error("Cannot call shell command in read-only mode.".into()) } else { @@ -1383,7 +1386,9 @@ impl App { ExternalMsg::Debug(path) => self.debug(path), ExternalMsg::Terminate => bail!(""), } - } + }? + .refresh_selection() + .write_pipes(&last_app) } fn handle_key(mut self, key: Key) -> Result { @@ -2018,13 +2023,10 @@ impl App { &self.session_path } - pub fn refresh_selection(mut self) -> Result { - self.selection = self - .selection - .into_iter() - .filter(|n| PathBuf::from(&n.absolute_path).exists()) - .collect(); - Ok(self) + fn refresh_selection(mut self) -> Self { + self.selection + .retain(|n| PathBuf::from(&n.absolute_path).exists()); + self } pub fn result(&self) -> Vec<&Node> { @@ -2148,4 +2150,47 @@ impl App { .collect::>() .join("") } + + pub fn write_pipes(self, last_app: &Self) -> Result { + if self.focused_node() != last_app.focused_node() { + fs::write(&self.pipe().focus_out, self.focused_node_str())?; + }; + + if self.selection() != last_app.selection() { + fs::write(&self.pipe().selection_out, self.selection_str())?; + }; + + if self.history_str() != last_app.history_str() { + fs::write(&self.pipe().history_out, self.history_str())?; + }; + + if self.mode_str() != last_app.mode_str() { + fs::write(&self.pipe().mode_out, self.mode_str())?; + }; + + if self.directory_buffer() != last_app.directory_buffer() { + fs::write(&self.pipe().directory_nodes_out, self.directory_nodes_str())?; + }; + + if self.logs().len() != last_app.logs().len() { + let new_logs = self + .logs() + .iter() + .skip(last_app.logs().len()) + .map(|l| format!("{}\n", l)) + .collect::>() + .join(""); + + let mut file = fs::OpenOptions::new() + .append(true) + .open(&self.pipe().logs_out)?; + + file.write_all(new_logs.as_bytes())?; + }; + + if self.result() != last_app.result() { + fs::write(&self.pipe().result_out, self.result_str())?; + }; + Ok(self) + } } diff --git a/src/runner.rs b/src/runner.rs index 0d50cf8..363b1d9 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -78,8 +78,6 @@ pub fn run(mut app: app::App, focused_path: Option) -> Result) -> Result (a, Ok(None)), Err(err) => (last_app.clone(), Err(err)), }; @@ -176,7 +174,6 @@ pub fn run(mut app: app::App, focused_path: Option) -> Result { - app = app.refresh_selection()?; if app.pwd() != last_app.pwd() { tx_pwd_watcher.send(app.pwd().clone())?; explorer::explore( @@ -242,46 +239,6 @@ pub fn run(mut app: app::App, focused_path: Option) -> Result>() - .join(""); - - let mut file = fs::OpenOptions::new() - .append(true) - .open(&app.pipe().logs_out)?; - - file.write_all(new_logs.as_bytes())?; - }; - - if app.result() != last_app.result() { - fs::write(&app.pipe().result_out, app.result_str())?; - }; } terminal.clear()?;