Emit less update events for odd FS events (#39557)

When running flycheck, I've noticed that scrolling starts to lag:


https://github.com/user-attachments/assets/b0bef0a3-ccbd-479d-a385-273398086d38

When checking the trace, it is notable that project panel updates its
entire tree multiple times during flycheck:

<img width="2032" height="1136" alt="image"
src="https://github.com/user-attachments/assets/d1935e77-3b00-4be5-a12a-8a17a9d64202"
/>


[scrolling.trace.zip](https://github.com/user-attachments/files/22710852/scrolling.trace.zip)

Turns out, `target/debug` directory is loaded by Zed (presumably,
reported by langserver as there are sources generated by bindgen and
proto that need to be loaded), and `target/debug/build` directory
received multiple events of a `None` kind for Zed, which trigger the
rescans.

Rework the logic to omit the `None`-kind events in Zed, and to avoid
excessive repo updates if not needed.


Release Notes:

- Improved worktree FS event emits in gitignored directories

---------

Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
Kirill Bulatov
2025-10-05 17:34:55 +00:00
committed by GitHub
co-authored by Cole Miller
parent 46b6adadf9
commit 469ecfbe13
4 changed files with 338 additions and 23 deletions
+9 -3
View File
@@ -3644,8 +3644,14 @@ impl BackgroundScanner {
while let Poll::Ready(Some(more_paths)) = futures::poll!(fs_events_rx.next()) {
paths.extend(more_paths);
}
self.process_events(paths.into_iter().map(Into::into).collect())
.await;
self.process_events(
paths
.into_iter()
.filter(|e| e.kind.is_some())
.map(Into::into)
.collect(),
)
.await;
}
if let Some(abs_path) = containing_git_repository {
self.process_events(vec![abs_path]).await;
@@ -3690,7 +3696,7 @@ impl BackgroundScanner {
while let Poll::Ready(Some(more_paths)) = futures::poll!(fs_events_rx.next()) {
paths.extend(more_paths);
}
self.process_events(paths.into_iter().map(Into::into).collect()).await;
self.process_events(paths.into_iter().filter(|e| e.kind.is_some()).map(Into::into).collect()).await;
}
paths = global_gitignore_events.next().fuse() => {