diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index a5545e79847..7475a8e6e6d 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -1013,6 +1013,17 @@ pub fn did_change_watched_files_dynamic_registration(&self) -> bool { ) } + pub fn did_change_watched_files_relative_pattern_support(&self) -> bool { + try_or_def!( + self.caps + .workspace + .as_ref()? + .did_change_watched_files + .as_ref()? + .relative_pattern_support? + ) + } + pub fn prefill_caches(&self) -> bool { self.data.cachePriming_enable } diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 499e779978b..771a5599f6f 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -428,16 +428,16 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) { } if let FilesWatcher::Client = self.config.files().watcher { - let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions { - watchers: self - .workspaces - .iter() - .flat_map(|ws| ws.to_roots()) - .filter(|it| it.is_local) + let filter = + self.workspaces.iter().flat_map(|ws| ws.to_roots()).filter(|it| it.is_local); + + let watchers = if self.config.did_change_watched_files_relative_pattern_support() { + // When relative patterns are supported by the client, prefer using them + filter .flat_map(|root| { - root.include - .into_iter() - .flat_map(|it| [(it.clone(), "**/*.rs"), (it, "**/Cargo.{lock,toml}")]) + root.include.into_iter().flat_map(|base| { + [(base.clone(), "**/*.rs"), (base, "**/Cargo.{lock,toml}")] + }) }) .map(|(base, pat)| lsp_types::FileSystemWatcher { glob_pattern: lsp_types::GlobPattern::Relative( @@ -450,8 +450,24 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) { ), kind: None, }) - .collect(), + .collect() + } else { + // When they're not, integrate the base to make them into absolute patterns + filter + .flat_map(|root| { + root.include.into_iter().flat_map(|base| { + [format!("{base}/**/*.rs"), format!("{base}/**/Cargo.{{lock,toml}}")] + }) + }) + .map(|glob_pattern| lsp_types::FileSystemWatcher { + glob_pattern: lsp_types::GlobPattern::String(glob_pattern), + kind: None, + }) + .collect() }; + + let registration_options = + lsp_types::DidChangeWatchedFilesRegistrationOptions { watchers }; let registration = lsp_types::Registration { id: "workspace/didChangeWatchedFiles".to_owned(), method: "workspace/didChangeWatchedFiles".to_owned(),