diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index a4a13b296ed5c1..37922b7c2ee03b 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -2892,11 +2892,27 @@ impl LspStore { let file = File::from_dyn(buffer.read(cx).file())?; let worktree_id = file.worktree_id(cx); let abs_path = file.as_local()?.abs_path(cx); + let worktree_path = file.as_local()?.path(); let text_document = lsp::TextDocumentIdentifier { uri: lsp::Url::from_file_path(abs_path).log_err()?, }; + let watched_paths_for_server = &self.as_local()?.language_server_watched_paths; for server in self.language_servers_for_worktree(worktree_id) { + let should_notify = maybe!({ + Some( + watched_paths_for_server + .get(&server.server_id())? + .read(cx) + .worktree_paths + .get(&worktree_id)? + .is_match(worktree_path), + ) + }) + .unwrap_or_default(); + if !should_notify { + continue; + } if let Some(include_text) = include_text(server.as_ref()) { let text = if include_text { Some(buffer.read(cx).text()) diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 9e58caa2442439..dd14ccd60f4e98 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -386,6 +386,34 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) { // A server is started up, and it is notified about Rust files. let mut fake_rust_server = fake_rust_servers.next().await.unwrap(); + fake_rust_server + .request::(lsp::RegistrationParams { + registrations: vec![lsp::Registration { + id: Default::default(), + method: "workspace/didChangeWatchedFiles".to_string(), + register_options: serde_json::to_value( + lsp::DidChangeWatchedFilesRegistrationOptions { + watchers: vec![ + lsp::FileSystemWatcher { + glob_pattern: lsp::GlobPattern::String( + "/the-root/Cargo.toml".to_string(), + ), + kind: None, + }, + lsp::FileSystemWatcher { + glob_pattern: lsp::GlobPattern::String( + "/the-root/*.rs".to_string(), + ), + kind: None, + }, + ], + }, + ) + .ok(), + }], + }) + .await + .unwrap(); assert_eq!( fake_rust_server .receive_notification::() @@ -433,6 +461,24 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) { // A json language server is started up and is only notified about the json buffer. let mut fake_json_server = fake_json_servers.next().await.unwrap(); + fake_json_server + .request::(lsp::RegistrationParams { + registrations: vec![lsp::Registration { + id: Default::default(), + method: "workspace/didChangeWatchedFiles".to_string(), + register_options: serde_json::to_value( + lsp::DidChangeWatchedFilesRegistrationOptions { + watchers: vec![lsp::FileSystemWatcher { + glob_pattern: lsp::GlobPattern::String("/the-root/*.json".to_string()), + kind: None, + }], + }, + ) + .ok(), + }], + }) + .await + .unwrap(); assert_eq!( fake_json_server .receive_notification::() @@ -483,7 +529,7 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) { ) ); - // Save notifications are reported to all servers. + // Save notifications are reported only to servers that signed up for a given extension. project .update(cx, |project, cx| project.save_buffer(toml_buffer, cx)) .await @@ -495,13 +541,6 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) { .text_document, lsp::TextDocumentIdentifier::new(lsp::Url::from_file_path("/the-root/Cargo.toml").unwrap()) ); - assert_eq!( - fake_json_server - .receive_notification::() - .await - .text_document, - lsp::TextDocumentIdentifier::new(lsp::Url::from_file_path("/the-root/Cargo.toml").unwrap()) - ); // Renames are reported only to servers matching the buffer's language. fs.rename(