diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index b649831fd2..7064448e16 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -587,38 +587,54 @@ impl Fs for RealFs { let pending_paths: Arc>> = Default::default(); let root_path = path.to_path_buf(); - watcher::global(|g| { - let tx = tx.clone(); - let pending_paths = pending_paths.clone(); - g.add(move |event: ¬ify::Event| { - let kind = match event.kind { - EventKind::Create(_) => Some(PathEventKind::Created), - EventKind::Modify(_) => Some(PathEventKind::Changed), - EventKind::Remove(_) => Some(PathEventKind::Removed), - _ => None, - }; - let mut paths = event - .paths - .iter() - .filter_map(|path| { - path.starts_with(&root_path).then(|| PathEvent { - path: path.clone(), - kind, - }) - }) - .collect::>(); + // Check if root path is a symlink + let target_path = self.read_link(&path).await.ok(); - if !paths.is_empty() { - paths.sort(); - let mut pending_paths = pending_paths.lock(); - if pending_paths.is_empty() { - tx.try_send(()).ok(); + watcher::global({ + let target_path = target_path.clone(); + |g| { + let tx = tx.clone(); + let pending_paths = pending_paths.clone(); + g.add(move |event: ¬ify::Event| { + let kind = match event.kind { + EventKind::Create(_) => Some(PathEventKind::Created), + EventKind::Modify(_) => Some(PathEventKind::Changed), + EventKind::Remove(_) => Some(PathEventKind::Removed), + _ => None, + }; + let mut paths = event + .paths + .iter() + .filter_map(|path| { + if let Some(target) = target_path.clone() { + if path.starts_with(target) { + return Some(PathEvent { + path: path.clone(), + kind, + }); + } + } else if path.starts_with(&root_path) { + return Some(PathEvent { + path: path.clone(), + kind, + }); + } + None + }) + .collect::>(); + + if !paths.is_empty() { + paths.sort(); + let mut pending_paths = pending_paths.lock(); + if pending_paths.is_empty() { + tx.try_send(()).ok(); + } + util::extend_sorted(&mut *pending_paths, paths, usize::MAX, |a, b| { + a.path.cmp(&b.path) + }); } - util::extend_sorted(&mut *pending_paths, paths, usize::MAX, |a, b| { - a.path.cmp(&b.path) - }); - } - }) + }) + } }) .log_err(); @@ -626,6 +642,14 @@ impl Fs for RealFs { watcher.add(path).ok(); // Ignore "file doesn't exist error" and rely on parent watcher. + // Check if path is a symlink and follow the target parent + if let Some(target) = target_path { + watcher.add(&target).ok(); + if let Some(parent) = target.parent() { + watcher.add(parent).log_err(); + } + } + // watch the parent dir so we can tell when settings.json is created if let Some(parent) = path.parent() { watcher.add(parent).log_err();