aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-client/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2024-08-19 19:02:52 +0200
committerGitHub <noreply@github.com>2024-08-19 19:02:52 +0200
commitcfbc0ff49036edeeb25e52eb67948de7dfe5590b (patch)
tree284e2900b54f0d816ed7dd7cfdefc8485c61882e /zellij-client/src
parentdocs(changelog): first run setup wizard (diff)
downloadsl0ppij-cfbc0ff49036edeeb25e52eb67948de7dfe5590b.tar.gz
sl0ppij-cfbc0ff49036edeeb25e52eb67948de7dfe5590b.tar.xz
sl0ppij-cfbc0ff49036edeeb25e52eb67948de7dfe5590b.zip
feat(ux): reload config at runtime (#3558)
* feat(ux): reload config at runtime * style(fmt): rustfmt
Diffstat (limited to 'zellij-client/src')
-rw-r--r--zellij-client/src/lib.rs64
1 files changed, 63 insertions, 1 deletions
diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs
index 9146e755..660fbf0c 100644
--- a/zellij-client/src/lib.rs
+++ b/zellij-client/src/lib.rs
@@ -12,12 +12,14 @@ use log::info;
use std::env::current_exe;
use std::io::{self, Write};
use std::path::Path;
-use std::path::PathBuf;
use std::process::Command;
use std::sync::{Arc, Mutex};
use std::thread;
use zellij_utils::errors::FatalError;
+use zellij_utils::notify_debouncer_full::notify::{self, Event, RecursiveMode, Watcher};
+use zellij_utils::setup::Setup;
+
use crate::stdin_ansi_parser::{AnsiStdinInstruction, StdinAnsiParser, SyncOutput};
use crate::{
command_is_executing::CommandIsExecuting, input_handler::input_loop,
@@ -357,7 +359,13 @@ pub fn start_client(
.name("signal_listener".to_string())
.spawn({
let os_input = os_input.clone();
+ let opts = opts.clone();
move || {
+ // we keep the config_file_watcher here so that it is only dropped when this thread
+ // exits (which is when the client disconnects/detaches), once it's dropped it
+ // stops watching and we want it to keep watching the config file path for changes
+ // as long as the client is alive
+ let _config_file_watcher = report_changes_in_config_file(&opts, &os_input);
os_input.handle_signals(
Box::new({
let os_api = os_input.clone();
@@ -660,3 +668,57 @@ pub fn start_server_detached(
os_input.connect_to_server(&*ipc_pipe);
os_input.send_to_server(first_msg);
}
+
+fn report_changes_in_config_file(
+ opts: &CliArgs,
+ os_input: &Box<dyn ClientOsApi>,
+) -> Option<Box<dyn Watcher>> {
+ match Config::config_file_path(&opts) {
+ Some(config_file_path) => {
+ let mut watcher = notify::recommended_watcher({
+ let os_input = os_input.clone();
+ let opts = opts.clone();
+ let config_file_path = config_file_path.clone();
+ move |res: Result<Event, _>| match res {
+ Ok(event)
+ if (event.kind.is_create() || event.kind.is_modify())
+ && event.paths.contains(&config_file_path) =>
+ {
+ match Setup::from_cli_args(&opts) {
+ Ok((
+ new_config,
+ _layout,
+ _config_options,
+ _config_without_layout,
+ _config_options_without_layout,
+ )) => {
+ os_input.send_to_server(ClientToServerMsg::ConfigWrittenToDisk(
+ new_config,
+ ));
+ },
+ Err(e) => {
+ log::error!("Failed to reload config: {}", e);
+ },
+ }
+ },
+ Err(e) => log::error!("watch error: {:?}", e),
+ _ => {},
+ }
+ })
+ .unwrap();
+ if let Some(config_file_parent_folder) = config_file_path.parent() {
+ watcher
+ .watch(&config_file_parent_folder, RecursiveMode::Recursive)
+ .unwrap();
+ Some(Box::new(watcher))
+ } else {
+ log::error!("Could not find config parent folder");
+ None
+ }
+ },
+ None => {
+ log::error!("Failed to find config path");
+ None
+ },
+ }
+}