summaryrefslogtreecommitdiffstats
path: root/src/context
diff options
context:
space:
mode:
authorDLFW <daniel@llin.info>2022-01-14 02:18:51 +0100
committerGitHub <noreply@github.com>2022-01-13 20:18:51 -0500
commitc6e477cae753fe2ec3453a59e12fc2c5c95462a6 (patch)
tree531ee419a9d2f8971dd3d73869cd92858f22c027 /src/context
parentfd06ae874291679b7ca0a1e8ac3611106b410840 (diff)
Calling preview removed hook when help page shown (#125)
* Calling preview removed hook when help page shown * Better function names and documentation * syntax fix
Diffstat (limited to 'src/context')
-rw-r--r--src/context/app_context.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/context/app_context.rs b/src/context/app_context.rs
index 0bdcf28..57178ee 100644
--- a/src/context/app_context.rs
+++ b/src/context/app_context.rs
@@ -1,5 +1,7 @@
use std::collections::HashSet;
+use std::process;
use std::sync::mpsc;
+use std::thread;
use tui::layout::Rect;
use crate::config;
@@ -7,6 +9,8 @@ use crate::context::{
CommandLineContext, LocalStateContext, MessageQueue, PreviewContext, TabContext, WorkerContext,
};
use crate::event::{AppEvent, Events};
+use crate::ui::views;
+use crate::ui::PreviewArea;
use crate::util::search::SearchPattern;
use crate::Args;
use notify::{RecursiveMode, Watcher};
@@ -59,6 +63,9 @@ pub struct AppContext {
watcher: notify::NullWatcher,
// list of watched paths; seems not to be possible to get them from a notify::Watcher
watched_paths: HashSet<path::PathBuf>,
+ // the last preview area (or None if now preview shown) to check if a preview hook script needs
+ // to be called
+ preview_area: Option<PreviewArea>,
}
impl AppContext {
@@ -94,9 +101,91 @@ impl AppContext {
config,
watcher,
watched_paths,
+ preview_area: None,
}
}
+ /// Calls the "preview shown hook script" if it's configured.
+ ///
+ /// This method takes the current preview area as argument to check for both, the path of the
+ /// currently previewed file and the geometry of the preview area.
+ fn call_preview_shown_hook(&self, preview_area: PreviewArea) {
+ let preview_options = self.config_ref().preview_options_ref();
+ let preview_shown_hook_script = preview_options.preview_shown_hook_script.as_ref();
+ if let Some(hook_script) = preview_shown_hook_script {
+ let hook_script = hook_script.to_path_buf();
+ let _ = thread::spawn(move || {
+ let _ = process::Command::new(hook_script.as_path())
+ .arg(preview_area.file_preview_path.as_path())
+ .arg(preview_area.preview_area.x.to_string())
+ .arg(preview_area.preview_area.y.to_string())
+ .arg(preview_area.preview_area.width.to_string())
+ .arg(preview_area.preview_area.height.to_string())
+ .status();
+ });
+ }
+ }
+
+ /// Calls the "preview removed hook script" if it's configured.
+ fn call_preview_removed_hook(&self) {
+ let preview_options = self.config_ref().preview_options_ref();
+ let preview_removed_hook_script = preview_options.preview_removed_hook_script.as_ref();
+ if let Some(hook_script) = preview_removed_hook_script {
+ let hook_script = hook_script.to_path_buf();
+ let _ = thread::spawn(|| {
+ let _ = process::Command::new(hook_script).status();
+ });
+ }
+ }
+
+ /// Updates the external preview to the current preview in Joshuto.
+ ///
+ /// The function checks if the current preview content is the same as the preview content which
+ /// has been last communicated to an external preview logic with the preview hook scripts.
+ /// If the preview content has changed, one of the hook scripts is called. Either the "preview
+ /// shown hook", if a preview is shown in Joshuto, or the "preview removed hook", if Joshuto has
+ /// changed from an entry with preview to an entry without a preview.
+ ///
+ /// This function shall be called each time a change of Joshuto's preview can be expected.
+ /// (As of now, it's called in each cycle of the main loop.)
+ pub fn update_external_preview(&mut self) {
+ let layout = &self.ui_context_ref().layout;
+ let new_preview_area = views::calculate_preview(self, layout[2]);
+ match new_preview_area.as_ref() {
+ Some(new) => {
+ let should_preview = if let Some(old) = &self.preview_area {
+ new.file_preview_path != old.file_preview_path
+ } else {
+ true
+ };
+ if should_preview {
+ self.call_preview_shown_hook(new.clone())
+ }
+ }
+ None => self.call_preview_removed_hook(),
+ }
+ self.preview_area = new_preview_area
+ }
+
+ /// Remove the external preview, if any is present.
+ ///
+ /// If the last preview hook script called was the "preview shown hook", this function will
+ /// call the "preview removed hook" to remove any external preview.
+ /// Otherwise it won't do anything.
+ ///
+ /// To restore the external preview, `update_external_preview` is called which will detect the
+ /// difference and call the "preview shown hook" again for the current preview (if any).
+ ///
+ /// This function can be called if an external preview shall be temporarily removed, for example
+ /// when entering the help screen.
+ pub fn remove_external_preview(&mut self) {
+ if let Some(_) = &self.preview_area {
+ self.call_preview_removed_hook();
+ self.preview_area = None;
+ }
+ }
+
+ /// Updates the file system supervision with the currently shown directories.
pub fn update_watcher(&mut self) {
// collect the paths that shall be watched...
let mut new_paths_to_watch: HashSet<path::PathBuf> = HashSet::with_capacity(3);