diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index c76f7ba0..557f29b2 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -14,14 +14,18 @@ jobs: permissions: issues: write pull-requests: write + discussions: write steps: - uses: dessant/lock-threads@v4 with: issue-inactive-days: "30" issue-comment: > I'm going to lock this issue because it has been closed for _30 days_. ⏳ + This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. - process-only: "issues" + pr-inactive-days: "30" + discussion-inactive-days: "30" + process-only: "issues,prs,discussions" diff --git a/yazi-core/src/manager/watcher.rs b/yazi-core/src/manager/watcher.rs index 4079f940..eea2e80a 100644 --- a/yazi-core/src/manager/watcher.rs +++ b/yazi-core/src/manager/watcher.rs @@ -17,7 +17,7 @@ pub(crate) static WATCHED: RoCell>> = RoCell::new(); pub static LINKED: RoCell> = RoCell::new(); pub struct Watcher { - tx: watch::Sender<(HashSet, HashSet)>, + tx: watch::Sender>, } impl Watcher { @@ -60,16 +60,7 @@ impl Watcher { pub(super) fn watch(&mut self, mut new: HashSet<&Url>) { new.retain(|&u| u.is_regular()); - - let old = WATCHED.read(); - let old: HashSet<_> = old.iter().collect(); - - let (to_unwatch, to_watch): (HashSet<_>, HashSet<_>) = ( - old.difference(&new).map(|&x| x.clone()).collect(), - new.difference(&old).map(|&x| x.clone()).collect(), - ); - - self.tx.send((to_unwatch, to_watch)).ok(); + self.tx.send(new.into_iter().cloned().collect()).ok(); } pub(super) fn trigger_dirs(&self, folders: &[&Folder]) { @@ -103,23 +94,20 @@ impl Watcher { }); } - async fn on_in( - mut rx: watch::Receiver<(HashSet, HashSet)>, - mut watcher: RecommendedWatcher, - ) { + async fn on_in(mut rx: watch::Receiver>, mut watcher: RecommendedWatcher) { loop { + let (mut to_unwatch, mut to_watch): (HashSet<_>, HashSet<_>) = { + let (new, old) = (&*rx.borrow_and_update(), &*WATCHED.read()); + (old.difference(new).cloned().collect(), new.difference(old).cloned().collect()) + }; + + to_unwatch.retain(|u| watcher.unwatch(u).is_ok()); + to_watch.retain(|u| watcher.watch(u, RecursiveMode::NonRecursive).is_ok()); + { - let (ref to_unwatch, ref to_watch) = *rx.borrow_and_update(); - for u in to_unwatch { - if watcher.unwatch(u).is_ok() { - WATCHED.write().remove(u); - } - } - for u in to_watch { - if watcher.watch(u, RecursiveMode::NonRecursive).is_ok() { - WATCHED.write().insert(u.clone()); - } - } + let mut watched = WATCHED.write(); + watched.retain(|u| !to_unwatch.contains(u)); + watched.extend(to_watch); } if !rx.has_changed().unwrap_or(false) { @@ -166,23 +154,24 @@ impl Watcher { async fn sync_linked() { let mut new = WATCHED.read().clone(); - LINKED.write().retain(|k, _| new.remove(k)); - macro_rules! go { - ($todo:expr) => { - for from in $todo { - match fs::canonicalize(&from).await { - Ok(to) if to != *from && WATCHED.read().contains(&from) => { - LINKED.write().insert(from, Url::from(to)); - } - _ => {} - } + let old = { + let mut linked = LINKED.write(); + linked.retain(|k, _| new.remove(k)); + linked.keys().cloned().collect() + }; + + async fn go(todo: HashSet) { + for from in todo { + let Ok(to) = fs::canonicalize(&from).await else { continue }; + + if to != *from && WATCHED.read().contains(&from) { + LINKED.write().insert(from, Url::from(to)); } - }; + } } - let old: Vec<_> = LINKED.read().keys().cloned().collect(); - go!(new); - go!(old); + go(new).await; + go(old).await; } }