diff options
| author | Aram Drevekenin <aram@poor.dev> | 2024-08-19 19:02:52 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-19 19:02:52 +0200 |
| commit | cfbc0ff49036edeeb25e52eb67948de7dfe5590b (patch) | |
| tree | 284e2900b54f0d816ed7dd7cfdefc8485c61882e /zellij-client/src | |
| parent | docs(changelog): first run setup wizard (diff) | |
| download | sl0ppij-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.rs | 64 |
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 + }, + } +} |
