diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index cea03fb6b6c..702f25a1927 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -198,39 +198,49 @@ impl GlobalState { } self.analysis_host.maybe_collect_garbage(); } - Event::Vfs(task) => match task { - vfs::loader::Message::Loaded { files } => { - let vfs = &mut self.vfs.write().0; - for (path, contents) in files { - let path = VfsPath::from(path); - if !self.mem_docs.contains(&path) { - vfs.set_file_contents(path, contents) + Event::Vfs(mut task) => { + let _p = profile("GlobalState::handle_event/vfs"); + loop { + match task { + vfs::loader::Message::Loaded { files } => { + let vfs = &mut self.vfs.write().0; + for (path, contents) in files { + let path = VfsPath::from(path); + if !self.mem_docs.contains(&path) { + vfs.set_file_contents(path, contents) + } + } + } + vfs::loader::Message::Progress { n_total, n_done } => { + if n_total == 0 { + self.transition(Status::Invalid); + } else { + let state = if n_done == 0 { + self.transition(Status::Loading); + Progress::Begin + } else if n_done < n_total { + Progress::Report + } else { + assert_eq!(n_done, n_total); + self.transition(Status::Ready); + Progress::End + }; + self.report_progress( + "roots scanned", + state, + Some(format!("{}/{}", n_done, n_total)), + Some(Progress::percentage(n_done, n_total)), + ) + } } } - } - vfs::loader::Message::Progress { n_total, n_done } => { - if n_total == 0 { - self.transition(Status::Invalid); - } else { - let state = if n_done == 0 { - self.transition(Status::Loading); - Progress::Begin - } else if n_done < n_total { - Progress::Report - } else { - assert_eq!(n_done, n_total); - self.transition(Status::Ready); - Progress::End - }; - self.report_progress( - "roots scanned", - state, - Some(format!("{}/{}", n_done, n_total)), - Some(Progress::percentage(n_done, n_total)), - ) + // Coalesce many VFS event into a single loop turn + task = match self.loader.receiver.try_recv() { + Ok(task) => task, + Err(_) => break, } } - }, + } Event::Flycheck(task) => match task { flycheck::Message::AddDiagnostic { workspace_root, diagnostic } => { let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs index 569da8a1c9d..3bfecd08fbb 100644 --- a/crates/vfs/src/lib.rs +++ b/crates/vfs/src/lib.rs @@ -70,7 +70,7 @@ impl ChangedFile { } } -#[derive(Eq, PartialEq, Copy, Clone)] +#[derive(Eq, PartialEq, Copy, Clone, Debug)] pub enum ChangeKind { Create, Modify,