diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2022-07-18 20:30:07 +0200 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2022-07-18 20:30:58 +0200 |
| commit | a63b5d3c846b74b917b8029aa00cb448faba409f (patch) | |
| tree | b958289e2e759d3d01f4de2e5dfe9f31cb99dc2d | |
| parent | ea416175d5401b85a3774a6b2c1e03281dac40c3 (diff) | |
| download | rust-a63b5d3c846b74b917b8029aa00cb448faba409f.tar.gz rust-a63b5d3c846b74b917b8029aa00cb448faba409f.zip | |
feat: Only flycheck workspace that belongs to saved file
| -rw-r--r-- | crates/flycheck/src/lib.rs | 7 | ||||
| -rw-r--r-- | crates/paths/src/lib.rs | 8 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 62 |
3 files changed, 70 insertions, 7 deletions
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs index f683fe61fe3..973f2a53c1a 100644 --- a/crates/flycheck/src/lib.rs +++ b/crates/flycheck/src/lib.rs @@ -55,6 +55,7 @@ pub struct FlycheckHandle { // XXX: drop order is significant sender: Sender<Restart>, _thread: jod_thread::JoinHandle, + id: usize, } impl FlycheckHandle { @@ -70,13 +71,17 @@ impl FlycheckHandle { .name("Flycheck".to_owned()) .spawn(move || actor.run(receiver)) .expect("failed to spawn thread"); - FlycheckHandle { sender, _thread: thread } + FlycheckHandle { id, sender, _thread: thread } } /// Schedule a re-start of the cargo check worker. pub fn update(&self) { self.sender.send(Restart).unwrap(); } + + pub fn id(&self) -> usize { + self.id + } } pub enum Message { diff --git a/crates/paths/src/lib.rs b/crates/paths/src/lib.rs index b4beb40e746..cf06bf0c27b 100644 --- a/crates/paths/src/lib.rs +++ b/crates/paths/src/lib.rs @@ -103,6 +103,14 @@ impl AsRef<Path> for AbsPath { } } +impl ToOwned for AbsPath { + type Owned = AbsPathBuf; + + fn to_owned(&self) -> Self::Owned { + AbsPathBuf(self.0.to_owned()) + } +} + impl<'a> TryFrom<&'a Path> for &'a AbsPath { type Error = &'a Path; fn try_from(path: &'a Path) -> Result<&'a AbsPath, &'a Path> { diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 49b83941119..262c30f132c 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -2,6 +2,7 @@ //! requests/replies and notifications back to the client. use std::{ fmt, + ops::Deref, sync::Arc, time::{Duration, Instant}, }; @@ -720,13 +721,62 @@ impl GlobalState { Ok(()) })? .on::<lsp_types::notification::DidSaveTextDocument>(|this, params| { - for flycheck in &this.flycheck { - flycheck.update(); + let mut updated = false; + if let Ok(vfs_path) = from_proto::vfs_path(¶ms.text_document.uri) { + let (vfs, _) = &*this.vfs.read(); + if let Some(file_id) = vfs.file_id(&vfs_path) { + let analysis = this.analysis_host.analysis(); + let crate_ids = analysis.crate_for(file_id)?; + + let paths: Vec<_> = crate_ids + .iter() + .filter_map(|&crate_id| { + analysis + .crate_root(crate_id) + .map(|file_id| { + vfs.file_path(file_id).as_path().map(ToOwned::to_owned) + }) + .transpose() + }) + .collect::<ide::Cancellable<_>>()?; + let paths: Vec<_> = paths.iter().map(Deref::deref).collect(); + + let workspace_ids = + this.workspaces.iter().enumerate().filter(|(_, ws)| match ws { + project_model::ProjectWorkspace::Cargo { cargo, .. } => { + cargo.packages().filter(|&pkg| cargo[pkg].is_member).any( + |pkg| { + cargo[pkg].targets.iter().any(|&it| { + paths.contains(&cargo[it].root.as_path()) + }) + }, + ) + } + project_model::ProjectWorkspace::Json { project, .. } => project + .crates() + .any(|(c, _)| crate_ids.iter().any(|&crate_id| crate_id == c)), + project_model::ProjectWorkspace::DetachedFiles { .. } => false, + }); + 'workspace: for (id, _) in workspace_ids { + for flycheck in &this.flycheck { + if id == flycheck.id() { + updated = true; + flycheck.update(); + continue 'workspace; + } + } + } + } + if let Some(abs_path) = vfs_path.as_path() { + if reload::should_refresh_for_change(&abs_path, ChangeKind::Modify) { + this.fetch_workspaces_queue + .request_op(format!("DidSaveTextDocument {}", abs_path.display())); + } + } } - if let Ok(abs_path) = from_proto::abs_path(¶ms.text_document.uri) { - if reload::should_refresh_for_change(&abs_path, ChangeKind::Modify) { - this.fetch_workspaces_queue - .request_op(format!("DidSaveTextDocument {}", abs_path.display())); + if !updated { + for flycheck in &this.flycheck { + flycheck.update(); } } Ok(()) |
