Skip to content

Commit db92a31

Browse files
authored
lsp: Do not notify all language servers on file save (#17756)
This is not an ideal solution to https://github.com/fasterthanlime/zed-diags-readme, but current status quo is not great either; we were just going through all of the language servers and notifying them, whereas we should ideally do it based on a glob. /cc @fasterthanlime Release Notes: - N/A
1 parent 31902a1 commit db92a31

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

crates/project/src/lsp_store.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2892,11 +2892,27 @@ impl LspStore {
28922892
let file = File::from_dyn(buffer.read(cx).file())?;
28932893
let worktree_id = file.worktree_id(cx);
28942894
let abs_path = file.as_local()?.abs_path(cx);
2895+
let worktree_path = file.as_local()?.path();
28952896
let text_document = lsp::TextDocumentIdentifier {
28962897
uri: lsp::Url::from_file_path(abs_path).log_err()?,
28972898
};
28982899

2900+
let watched_paths_for_server = &self.as_local()?.language_server_watched_paths;
28992901
for server in self.language_servers_for_worktree(worktree_id) {
2902+
let should_notify = maybe!({
2903+
Some(
2904+
watched_paths_for_server
2905+
.get(&server.server_id())?
2906+
.read(cx)
2907+
.worktree_paths
2908+
.get(&worktree_id)?
2909+
.is_match(worktree_path),
2910+
)
2911+
})
2912+
.unwrap_or_default();
2913+
if !should_notify {
2914+
continue;
2915+
}
29002916
if let Some(include_text) = include_text(server.as_ref()) {
29012917
let text = if include_text {
29022918
Some(buffer.read(cx).text())

crates/project/src/project_tests.rs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,34 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
386386

387387
// A server is started up, and it is notified about Rust files.
388388
let mut fake_rust_server = fake_rust_servers.next().await.unwrap();
389+
fake_rust_server
390+
.request::<lsp::request::RegisterCapability>(lsp::RegistrationParams {
391+
registrations: vec![lsp::Registration {
392+
id: Default::default(),
393+
method: "workspace/didChangeWatchedFiles".to_string(),
394+
register_options: serde_json::to_value(
395+
lsp::DidChangeWatchedFilesRegistrationOptions {
396+
watchers: vec![
397+
lsp::FileSystemWatcher {
398+
glob_pattern: lsp::GlobPattern::String(
399+
"/the-root/Cargo.toml".to_string(),
400+
),
401+
kind: None,
402+
},
403+
lsp::FileSystemWatcher {
404+
glob_pattern: lsp::GlobPattern::String(
405+
"/the-root/*.rs".to_string(),
406+
),
407+
kind: None,
408+
},
409+
],
410+
},
411+
)
412+
.ok(),
413+
}],
414+
})
415+
.await
416+
.unwrap();
389417
assert_eq!(
390418
fake_rust_server
391419
.receive_notification::<lsp::notification::DidOpenTextDocument>()
@@ -433,6 +461,24 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
433461

434462
// A json language server is started up and is only notified about the json buffer.
435463
let mut fake_json_server = fake_json_servers.next().await.unwrap();
464+
fake_json_server
465+
.request::<lsp::request::RegisterCapability>(lsp::RegistrationParams {
466+
registrations: vec![lsp::Registration {
467+
id: Default::default(),
468+
method: "workspace/didChangeWatchedFiles".to_string(),
469+
register_options: serde_json::to_value(
470+
lsp::DidChangeWatchedFilesRegistrationOptions {
471+
watchers: vec![lsp::FileSystemWatcher {
472+
glob_pattern: lsp::GlobPattern::String("/the-root/*.json".to_string()),
473+
kind: None,
474+
}],
475+
},
476+
)
477+
.ok(),
478+
}],
479+
})
480+
.await
481+
.unwrap();
436482
assert_eq!(
437483
fake_json_server
438484
.receive_notification::<lsp::notification::DidOpenTextDocument>()
@@ -483,7 +529,7 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
483529
)
484530
);
485531

486-
// Save notifications are reported to all servers.
532+
// Save notifications are reported only to servers that signed up for a given extension.
487533
project
488534
.update(cx, |project, cx| project.save_buffer(toml_buffer, cx))
489535
.await
@@ -495,13 +541,6 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
495541
.text_document,
496542
lsp::TextDocumentIdentifier::new(lsp::Url::from_file_path("/the-root/Cargo.toml").unwrap())
497543
);
498-
assert_eq!(
499-
fake_json_server
500-
.receive_notification::<lsp::notification::DidSaveTextDocument>()
501-
.await
502-
.text_document,
503-
lsp::TextDocumentIdentifier::new(lsp::Url::from_file_path("/the-root/Cargo.toml").unwrap())
504-
);
505544

506545
// Renames are reported only to servers matching the buffer's language.
507546
fs.rename(

0 commit comments

Comments
 (0)