aboutsummaryrefslogtreecommitdiffstats
path: root/crates/turtle/src/atuin_client/settings
diff options
context:
space:
mode:
Diffstat (limited to 'crates/turtle/src/atuin_client/settings')
-rw-r--r--crates/turtle/src/atuin_client/settings/watcher.rs70
1 files changed, 37 insertions, 33 deletions
diff --git a/crates/turtle/src/atuin_client/settings/watcher.rs b/crates/turtle/src/atuin_client/settings/watcher.rs
index 20082639..e280480c 100644
--- a/crates/turtle/src/atuin_client/settings/watcher.rs
+++ b/crates/turtle/src/atuin_client/settings/watcher.rs
@@ -22,7 +22,7 @@
//! ```
use std::{
- path::PathBuf,
+ path::{Path, PathBuf},
sync::{Arc, OnceLock},
time::Duration,
};
@@ -74,9 +74,9 @@ impl SettingsWatcher {
let (tx, rx) = watch::channel(initial_settings);
let config_path = Self::config_path();
- info!("starting config file watcher: {:?}", config_path);
+ info!("starting config file watcher: {}", config_path.display());
- let watcher = Self::create_watcher(tx, config_path)?;
+ let watcher = Self::create_watcher(tx, &config_path)?;
Ok(Self {
rx,
@@ -93,37 +93,29 @@ impl SettingsWatcher {
self.rx.clone()
}
- /// Get the current settings without subscribing to updates.
- pub(crate) fn current(&self) -> Arc<Settings> {
- self.rx.borrow().clone()
- }
-
/// Get the config file path.
fn config_path() -> PathBuf {
- let config_dir = if let Ok(p) = std::env::var("ATUIN_CONFIG_DIR") {
- PathBuf::from(p)
- } else {
- crate::atuin_common::utils::config_dir()
- };
+ let config_dir = std::env::var("ATUIN_CONFIG_DIR")
+ .map_or_else(|_| crate::atuin_common::utils::config_dir(), PathBuf::from);
config_dir.join("config.toml")
}
/// Create the file watcher with debouncing.
fn create_watcher(
tx: watch::Sender<Arc<Settings>>,
- config_path: PathBuf,
+ config_path: &Path,
) -> Result<RecommendedWatcher> {
// Channel for debouncing file events
let (debounce_tx, debounce_rx) = std::sync::mpsc::channel::<()>();
// Spawn debounce thread
- let config_path_clone = config_path.clone();
+ let config_path_clone = config_path.to_owned();
std::thread::spawn(move || {
- Self::debounce_loop(debounce_rx, tx, config_path_clone);
+ Self::debounce_loop(&debounce_rx, &tx, &config_path_clone);
});
// Clone config_path for use in the watcher callback
- let config_path_for_watcher = config_path.clone();
+ let config_path_for_watcher = config_path.to_owned();
// Canonicalize config path for reliable comparison on macOS
// (handles symlinks like /var -> /private/var)
@@ -169,13 +161,13 @@ impl SettingsWatcher {
EventKind::Modify(ModifyKind::Data(_) | ModifyKind::Any)
| EventKind::Create(_)
) {
- debug!("config file event detected: {:?}", event);
+ debug!("config file event detected: {event:?}");
// Send to debounce channel (ignore send errors - receiver might be gone)
let _ = debounce_tx.send(());
}
}
Err(e) => {
- error!("file watcher error: {}", e);
+ error!("file watcher error: {e}");
}
}
},
@@ -184,31 +176,40 @@ impl SettingsWatcher {
.wrap_err("failed to create file watcher")?;
// Watch the config file's parent directory (some editors create new files)
- let watch_path = config_path.parent().unwrap_or(&config_path);
+ let watch_path = config_path.parent().unwrap_or(config_path);
// Defensive: ensure watch path exists before trying to watch
if !watch_path.exists() {
warn!(
- "config directory does not exist, creating it: {:?}",
- watch_path
+ "config directory does not exist, creating it: {}",
+ watch_path.display()
);
- std::fs::create_dir_all(watch_path)
- .wrap_err_with(|| format!("failed to create config directory: {:?}", watch_path))?;
+ std::fs::create_dir_all(watch_path).wrap_err_with(|| {
+ format!(
+ "failed to create config directory: {}",
+ watch_path.display()
+ )
+ })?;
}
watcher
.watch(watch_path, RecursiveMode::NonRecursive)
- .wrap_err_with(|| format!("failed to watch config directory: {:?}", watch_path))?;
+ .wrap_err_with(|| {
+ format!("failed to watch config directory: {}", watch_path.display())
+ })?;
- info!("config file watcher initialized for: {:?}", watch_path);
+ info!(
+ "config file watcher initialized for: {}",
+ watch_path.display()
+ );
Ok(watcher)
}
/// Debounce loop that batches file events and reloads settings.
fn debounce_loop(
- rx: std::sync::mpsc::Receiver<()>,
- tx: watch::Sender<Arc<Settings>>,
- config_path: PathBuf,
+ rx: &std::sync::mpsc::Receiver<()>,
+ tx: &watch::Sender<Arc<Settings>>,
+ config_path: &Path,
) {
const DEBOUNCE_DURATION: Duration = Duration::from_millis(500);
@@ -229,14 +230,17 @@ impl SettingsWatcher {
// (handles case where file was deleted - we'll get notified when it's recreated)
if !config_path.exists() {
debug!(
- "config file does not exist, skipping reload: {:?}",
- config_path
+ "config file does not exist, skipping reload: {}",
+ config_path.display()
);
continue;
}
// Now reload settings
- info!("config file changed, reloading settings: {:?}", config_path);
+ info!(
+ "config file changed, reloading settings: {}",
+ config_path.display()
+ );
match Settings::new() {
Ok(settings) => {
if tx.send(Arc::new(settings)).is_err() {
@@ -247,7 +251,7 @@ impl SettingsWatcher {
info!("settings reloaded successfully");
}
Err(e) => {
- warn!("failed to reload settings: {}", e);
+ warn!("failed to reload settings: {e}");
// Keep the old settings, don't broadcast the error
}
}