From 400e3cda322086ef8a33ed231807e65947a31268 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 21 Jun 2023 10:07:29 -0700 Subject: [PATCH] Scan directories when they stop being ignored --- crates/project/src/worktree.rs | 44 ++++++++++++++++++++++++---- crates/project/src/worktree_tests.rs | 3 +- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index d3ff0e93d23f83fd496c5ddd416d608379085891..39350f1c8f3cf32fb89441a132b69016a6fe8225 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -3066,11 +3066,16 @@ impl BackgroundScanner { let (scan_job_tx, scan_job_rx) = channel::unbounded(); let paths = self - .reload_entries_for_paths(root_path, root_canonical_path, abs_paths, Some(scan_job_tx)) + .reload_entries_for_paths( + root_path, + root_canonical_path, + abs_paths, + Some(scan_job_tx.clone()), + ) .await; - self.scan_dirs(false, scan_job_rx).await; - self.update_ignore_statuses().await; + self.update_ignore_statuses(scan_job_tx).await; + self.scan_dirs(false, scan_job_rx).await; { let mut state = self.state.lock(); @@ -3571,7 +3576,7 @@ impl BackgroundScanner { Some(()) } - async fn update_ignore_statuses(&self) { + async fn update_ignore_statuses(&self, scan_job_tx: Sender) { use futures::FutureExt as _; let mut snapshot = self.state.lock().snapshot.clone(); @@ -3619,6 +3624,7 @@ impl BackgroundScanner { abs_path: parent_abs_path, ignore_stack, ignore_queue: ignore_queue_tx.clone(), + scan_queue: scan_job_tx.clone(), })) .unwrap(); } @@ -3663,7 +3669,7 @@ impl BackgroundScanner { let path = job.abs_path.strip_prefix(&snapshot.abs_path).unwrap(); for mut entry in snapshot.child_entries(path).cloned() { let was_ignored = entry.is_ignored; - let abs_path = snapshot.abs_path().join(&entry.path); + let abs_path: Arc = snapshot.abs_path().join(&entry.path).into(); entry.is_ignored = ignore_stack.is_abs_path_ignored(&abs_path, entry.is_dir()); if entry.is_dir() { let child_ignore_stack = if entry.is_ignored { @@ -3671,11 +3677,36 @@ impl BackgroundScanner { } else { ignore_stack.clone() }; + + // Scan any directories that were previously ignored and weren't + // previously scanned. + if was_ignored + && !entry.is_ignored + && !entry.is_external + && entry.kind == EntryKind::PendingDir + { + job.scan_queue + .try_send(ScanJob { + abs_path: abs_path.clone(), + path: entry.path.clone(), + ignore_stack: child_ignore_stack.clone(), + scan_queue: job.scan_queue.clone(), + ancestor_inodes: self + .state + .lock() + .snapshot + .ancestor_inodes_for_path(&entry.path), + is_external: false, + }) + .unwrap(); + } + job.ignore_queue .send(UpdateIgnoreStatusJob { - abs_path: abs_path.into(), + abs_path: abs_path.clone(), ignore_stack: child_ignore_stack, ignore_queue: job.ignore_queue.clone(), + scan_queue: job.scan_queue.clone(), }) .await .unwrap(); @@ -3847,6 +3878,7 @@ struct UpdateIgnoreStatusJob { abs_path: Arc, ignore_stack: Arc, ignore_queue: Sender, + scan_queue: Sender, } pub trait WorktreeHandle { diff --git a/crates/project/src/worktree_tests.rs b/crates/project/src/worktree_tests.rs index b544181292be15505a5f282235f813bf4c1cd747..5cab52a21a1c31df65bff349b171d37fdb8eaa89 100644 --- a/crates/project/src/worktree_tests.rs +++ b/crates/project/src/worktree_tests.rs @@ -644,6 +644,7 @@ async fn test_dirs_no_longer_ignored(cx: &mut TestAppContext) { (Path::new("a/a.js"), false), (Path::new("b"), false), (Path::new("b/b.js"), false), + // This directory is no longer ignored (Path::new("node_modules"), false), (Path::new("node_modules/c"), false), (Path::new("node_modules/c/c.js"), false), @@ -660,7 +661,7 @@ async fn test_dirs_no_longer_ignored(cx: &mut TestAppContext) { // Each of the newly-loaded directories is scanned only once. let read_dir_count_3 = fs.read_dir_call_count(); - assert_eq!(read_dir_count_3 - read_dir_count_2, 4); + assert_eq!(read_dir_count_3 - read_dir_count_2, 2); } #[gpui::test]