1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
use std::path::PathBuf;
use std::sync::mpsc;
use std::time::Duration;
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
pub struct Monitor {
_thread: ::std::thread::JoinHandle<()>,
rx: mpsc::Receiver<PathBuf>,
}
pub trait OnConfigReload {
fn on_config_reload(&mut self);
}
impl OnConfigReload for crate::display::Notifier {
fn on_config_reload(&mut self) {
self.notify();
}
}
impl Monitor {
/// Get pending config changes
pub fn pending(&self) -> Option<PathBuf> {
let mut config = None;
while let Ok(new) = self.rx.try_recv() {
config = Some(new);
}
config
}
pub fn new<H, P>(path: P, mut handler: H) -> Monitor
where
H: OnConfigReload + Send + 'static,
P: Into<PathBuf>,
{
let path = path.into();
let (config_tx, config_rx) = mpsc::channel();
Monitor {
_thread: crate::util::thread::spawn_named("config watcher", move || {
let (tx, rx) = mpsc::channel();
// The Duration argument is a debouncing period.
let mut watcher =
watcher(tx, Duration::from_millis(10)).expect("Unable to spawn file watcher");
let config_path = ::std::fs::canonicalize(path).expect("canonicalize config path");
// Get directory of config
let mut parent = config_path.clone();
parent.pop();
// Watch directory
watcher
.watch(&parent, RecursiveMode::NonRecursive)
.expect("watch alacritty.yml dir");
loop {
match rx.recv().expect("watcher event") {
DebouncedEvent::Rename(..) => continue,
DebouncedEvent::Write(path)
| DebouncedEvent::Create(path)
| DebouncedEvent::Chmod(path) => {
if path != config_path {
continue;
}
let _ = config_tx.send(path);
handler.on_config_reload();
},
_ => {},
}
}
}),
rx: config_rx,
}
}
}
|