lsp: Watch paths outside of worktrees at language servers request (#17499)

Another stab at https://github.com/zed-industries/zed/pull/17173, this
time fixing the segfault found in
https://github.com/zed-industries/zed/pull/17206

Release Notes:

- Improved language server reliability in multi-worktree projects and
monorepo. We now notify the language server more reliably about which
files have changed.
This commit is contained in:
Piotr Osiewicz 2024-09-06 15:47:17 +02:00 committed by GitHub
parent 938c90fd3b
commit 903f92045a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 446 additions and 102 deletions

View file

@ -7,7 +7,7 @@ use ::ignore::gitignore::{Gitignore, GitignoreBuilder};
use anyhow::{anyhow, Context as _, Result};
use clock::ReplicaId;
use collections::{HashMap, HashSet, VecDeque};
use fs::{copy_recursive, Fs, RemoveOptions, Watcher};
use fs::{copy_recursive, Fs, PathEvent, RemoveOptions, Watcher};
use futures::{
channel::{
mpsc::{self, UnboundedSender},
@ -1048,7 +1048,11 @@ impl LocalWorktree {
watcher,
};
scanner.run(events).await;
scanner
.run(Box::pin(
events.map(|events| events.into_iter().map(Into::into).collect()),
))
.await;
}
});
let scan_state_updater = cx.spawn(|this, mut cx| async move {
@ -3512,7 +3516,7 @@ enum BackgroundScannerPhase {
}
impl BackgroundScanner {
async fn run(&mut self, mut fs_events_rx: Pin<Box<dyn Send + Stream<Item = Vec<PathBuf>>>>) {
async fn run(&mut self, mut fs_events_rx: Pin<Box<dyn Send + Stream<Item = Vec<PathEvent>>>>) {
use futures::FutureExt as _;
// If the worktree root does not contain a git repository, then find
@ -3593,7 +3597,8 @@ impl BackgroundScanner {
while let Poll::Ready(Some(more_paths)) = futures::poll!(fs_events_rx.next()) {
paths.extend(more_paths);
}
self.process_events(paths).await;
self.process_events(paths.into_iter().map(Into::into).collect())
.await;
}
// Continue processing events until the worktree is dropped.
@ -3634,7 +3639,7 @@ impl BackgroundScanner {
while let Poll::Ready(Some(more_paths)) = futures::poll!(fs_events_rx.next()) {
paths.extend(more_paths);
}
self.process_events(paths.clone()).await;
self.process_events(paths.into_iter().map(Into::into).collect()).await;
}
}
}