From 8f9a58c73d4181f137f92a83377cd4ca0a9b0259 Mon Sep 17 00:00:00 2001 From: "Alexis (Poliorcetics) Bourget" Date: Wed, 27 Mar 2024 02:29:03 +0100 Subject: [PATCH] fix: check for client support of relative glob patterns before using them --- crates/rust-analyzer/src/config.rs | 11 +++++++++ crates/rust-analyzer/src/reload.rs | 36 +++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 10 deletions(-) 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(),