summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaïm Favier <n@monade.li>2021-08-27 23:30:39 +0200
committerGitHub <noreply@github.com>2021-08-27 21:30:39 +0000
commit70d3b4ef6cc53df74e03467258766fa8319e13a1 (patch)
tree5505f0f38efa8d48458357c6d973dccb8ea76f8d
parente6565f1b76973eeb5ad7c5f858834ca0bdfa9959 (diff)
downloadalacritty-70d3b4ef6cc53df74e03467258766fa8319e13a1.tar.gz
alacritty-70d3b4ef6cc53df74e03467258766fa8319e13a1.zip
Watch non-canonical path for config symlinks
To make it possible to detect the replacement of the configuration file when it is a symlink, the symlinks path has to be observed in addition to the canonicalized path. That way changes to either file will trigger a live config reload. Multiple layers of symlinks would still not get detected when any symlink other than the configuration file itself is replaced, but this patch should cover most realistic usage scenarios.
-rw-r--r--CHANGELOG.md1
-rw-r--r--alacritty/src/config/monitor.rs37
2 files changed, 17 insertions, 21 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a752821e..1694f367 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- `ExpandSelection` is now a configurable mouse binding action
- Config option `background_opacity`, you should use `window.opacity` instead
+- Reload configuration files when their symbolic link is replaced
## 0.9.0
diff --git a/alacritty/src/config/monitor.rs b/alacritty/src/config/monitor.rs
index 4a694fac..e3dd0556 100644
--- a/alacritty/src/config/monitor.rs
+++ b/alacritty/src/config/monitor.rs
@@ -1,4 +1,3 @@
-use std::fs;
use std::path::PathBuf;
use std::sync::mpsc;
use std::time::Duration;
@@ -16,23 +15,21 @@ const DEBOUNCE_DELAY: Duration = Duration::from_millis(10);
const DEBOUNCE_DELAY: Duration = Duration::from_millis(1000);
pub fn watch(mut paths: Vec<PathBuf>, event_proxy: EventProxy) {
- // Canonicalize all paths, filtering out the ones that do not exist.
- paths = paths
- .drain(..)
- .filter_map(|path| match fs::canonicalize(&path) {
- Ok(path) => Some(path),
- Err(err) => {
- error!("Unable to canonicalize config path {:?}: {}", path, err);
- None
- },
- })
- .collect();
-
// Don't monitor config if there is no path to watch.
if paths.is_empty() {
return;
}
+ // Canonicalize paths, keeping the base paths for symlinks.
+ for i in 0..paths.len() {
+ if let Ok(canonical_path) = paths[i].canonicalize() {
+ match paths[i].symlink_metadata() {
+ Ok(metadata) if metadata.file_type().is_symlink() => paths.push(canonical_path),
+ _ => paths[i] = canonical_path,
+ }
+ }
+ }
+
// The Duration argument is a debouncing period.
let (tx, rx) = mpsc::channel();
let mut watcher = match watcher(tx, DEBOUNCE_DELAY) {
@@ -73,17 +70,15 @@ pub fn watch(mut paths: Vec<PathBuf>, event_proxy: EventProxy) {
};
match event {
- DebouncedEvent::Rename(..) => continue,
- DebouncedEvent::Write(path)
+ DebouncedEvent::Rename(_, path)
+ | DebouncedEvent::Write(path)
| DebouncedEvent::Create(path)
- | DebouncedEvent::Chmod(path) => {
- if !paths.contains(&path) {
- continue;
- }
-
+ | DebouncedEvent::Chmod(path)
+ if paths.contains(&path) =>
+ {
// Always reload the primary configuration file.
event_proxy.send_event(Event::ConfigReload(paths[0].clone()));
- },
+ }
_ => {},
}
}