lsp: Serialize LSP notifications on background threads (#39403)
This should reduce hiccups when opening large files. Release Notes: - N/A
This commit is contained in:
@@ -406,15 +406,14 @@ impl LocalLspStore {
|
||||
adapter.clone(),
|
||||
);
|
||||
|
||||
let did_change_configuration_params =
|
||||
Arc::new(lsp::DidChangeConfigurationParams {
|
||||
settings: workspace_config,
|
||||
});
|
||||
let did_change_configuration_params = lsp::DidChangeConfigurationParams {
|
||||
settings: workspace_config,
|
||||
};
|
||||
let language_server = cx
|
||||
.update(|cx| {
|
||||
language_server.initialize(
|
||||
initialization_params,
|
||||
did_change_configuration_params.clone(),
|
||||
Arc::new(did_change_configuration_params.clone()),
|
||||
cx,
|
||||
)
|
||||
})?
|
||||
@@ -430,11 +429,9 @@ impl LocalLspStore {
|
||||
}
|
||||
})?;
|
||||
|
||||
language_server
|
||||
.notify::<lsp::notification::DidChangeConfiguration>(
|
||||
&did_change_configuration_params,
|
||||
)
|
||||
.ok();
|
||||
language_server.notify::<lsp::notification::DidChangeConfiguration>(
|
||||
did_change_configuration_params,
|
||||
)?;
|
||||
|
||||
anyhow::Ok(language_server)
|
||||
}
|
||||
@@ -7206,7 +7203,7 @@ impl LspStore {
|
||||
|
||||
language_server
|
||||
.notify::<lsp::notification::DidChangeTextDocument>(
|
||||
&lsp::DidChangeTextDocumentParams {
|
||||
lsp::DidChangeTextDocumentParams {
|
||||
text_document: lsp::VersionedTextDocumentIdentifier::new(
|
||||
uri.clone(),
|
||||
next_version,
|
||||
@@ -7243,7 +7240,7 @@ impl LspStore {
|
||||
};
|
||||
server
|
||||
.notify::<lsp::notification::DidSaveTextDocument>(
|
||||
&lsp::DidSaveTextDocumentParams {
|
||||
lsp::DidSaveTextDocumentParams {
|
||||
text_document: text_document.clone(),
|
||||
text,
|
||||
},
|
||||
@@ -7314,7 +7311,7 @@ impl LspStore {
|
||||
.ok()?;
|
||||
server
|
||||
.notify::<lsp::notification::DidChangeConfiguration>(
|
||||
&lsp::DidChangeConfigurationParams { settings },
|
||||
lsp::DidChangeConfigurationParams { settings },
|
||||
)
|
||||
.ok()?;
|
||||
Some(())
|
||||
@@ -8536,15 +8533,16 @@ impl LspStore {
|
||||
cx: AsyncApp,
|
||||
) -> Result<proto::Ack> {
|
||||
let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
|
||||
lsp_store.read_with(&cx, |lsp_store, _| {
|
||||
let task = lsp_store.read_with(&cx, |lsp_store, _| {
|
||||
if let Some(server) = lsp_store.language_server_for_id(server_id) {
|
||||
server
|
||||
.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
|
||||
.context("handling lsp ext cancel flycheck")
|
||||
Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
|
||||
} else {
|
||||
anyhow::Ok(())
|
||||
None
|
||||
}
|
||||
})??;
|
||||
})?;
|
||||
if let Some(task) = task {
|
||||
task.context("handling lsp ext cancel flycheck")?;
|
||||
}
|
||||
|
||||
Ok(proto::Ack {})
|
||||
}
|
||||
@@ -8578,14 +8576,11 @@ impl LspStore {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
server
|
||||
.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
|
||||
&lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
|
||||
)
|
||||
.context("handling lsp ext run flycheck")
|
||||
} else {
|
||||
anyhow::Ok(())
|
||||
server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
|
||||
lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
|
||||
)?;
|
||||
}
|
||||
anyhow::Ok(())
|
||||
})??;
|
||||
|
||||
Ok(proto::Ack {})
|
||||
@@ -8597,15 +8592,15 @@ impl LspStore {
|
||||
cx: AsyncApp,
|
||||
) -> Result<proto::Ack> {
|
||||
let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
|
||||
lsp_store.read_with(&cx, |lsp_store, _| {
|
||||
if let Some(server) = lsp_store.language_server_for_id(server_id) {
|
||||
server
|
||||
.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
|
||||
.context("handling lsp ext clear flycheck")
|
||||
} else {
|
||||
anyhow::Ok(())
|
||||
}
|
||||
})??;
|
||||
lsp_store
|
||||
.read_with(&cx, |lsp_store, _| {
|
||||
if let Some(server) = lsp_store.language_server_for_id(server_id) {
|
||||
Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.context("handling lsp ext clear flycheck")?;
|
||||
|
||||
Ok(proto::Ack {})
|
||||
}
|
||||
@@ -8744,7 +8739,7 @@ impl LspStore {
|
||||
|
||||
if filter.should_send_did_rename(&old_uri, is_dir) {
|
||||
language_server
|
||||
.notify::<DidRenameFiles>(&RenameFilesParams {
|
||||
.notify::<DidRenameFiles>(RenameFilesParams {
|
||||
files: vec![FileRename {
|
||||
old_uri: old_uri.clone(),
|
||||
new_uri: new_uri.clone(),
|
||||
@@ -8858,7 +8853,7 @@ impl LspStore {
|
||||
if !changes.is_empty() {
|
||||
server
|
||||
.notify::<lsp::notification::DidChangeWatchedFiles>(
|
||||
&lsp::DidChangeWatchedFilesParams { changes },
|
||||
lsp::DidChangeWatchedFilesParams { changes },
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
@@ -10668,7 +10663,7 @@ impl LspStore {
|
||||
if progress.is_cancellable {
|
||||
server
|
||||
.notify::<lsp::notification::WorkDoneProgressCancel>(
|
||||
&WorkDoneProgressCancelParams {
|
||||
WorkDoneProgressCancelParams {
|
||||
token: lsp::NumberOrString::String(token.clone()),
|
||||
},
|
||||
)
|
||||
@@ -10799,7 +10794,7 @@ impl LspStore {
|
||||
};
|
||||
if !params.changes.is_empty() {
|
||||
server
|
||||
.notify::<lsp::notification::DidChangeWatchedFiles>(¶ms)
|
||||
.notify::<lsp::notification::DidChangeWatchedFiles>(params)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ impl lsp::notification::Notification for SchemaContentsChanged {
|
||||
type Params = String;
|
||||
}
|
||||
|
||||
pub fn notify_schema_changed(lsp_store: Entity<LspStore>, uri: &String, cx: &App) {
|
||||
pub fn notify_schema_changed(lsp_store: Entity<LspStore>, uri: String, cx: &App) {
|
||||
zlog::trace!(LOGGER => "Notifying schema changed for URI: {:?}", uri);
|
||||
let servers = lsp_store.read_with(cx, |lsp_store, _| {
|
||||
let mut servers = Vec::new();
|
||||
@@ -65,7 +65,7 @@ pub fn notify_schema_changed(lsp_store: Entity<LspStore>, uri: &String, cx: &App
|
||||
for server in servers {
|
||||
zlog::trace!(LOGGER => "Notifying server {:?} of schema change for URI: {:?}", server.server_id(), &uri);
|
||||
// TODO: handle errors
|
||||
server.notify::<SchemaContentsChanged>(uri).ok();
|
||||
server.notify::<SchemaContentsChanged>(uri.clone()).ok();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,11 +119,12 @@ pub fn cancel_flycheck(
|
||||
lsp_store
|
||||
.read_with(cx, |lsp_store, _| {
|
||||
if let Some(server) = lsp_store.language_server_for_id(rust_analyzer_server) {
|
||||
server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())?;
|
||||
server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
anyhow::Ok(())
|
||||
})?
|
||||
.context("lsp ext cancel flycheck")?;
|
||||
})
|
||||
.context("lsp ext cancel flycheck")??;
|
||||
};
|
||||
anyhow::Ok(())
|
||||
})
|
||||
@@ -173,14 +174,15 @@ pub fn run_flycheck(
|
||||
.read_with(cx, |lsp_store, _| {
|
||||
if let Some(server) = lsp_store.language_server_for_id(rust_analyzer_server) {
|
||||
server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
|
||||
&lsp_store::lsp_ext_command::RunFlycheckParams {
|
||||
lsp_store::lsp_ext_command::RunFlycheckParams {
|
||||
text_document: None,
|
||||
},
|
||||
)?;
|
||||
)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
anyhow::Ok(())
|
||||
})?
|
||||
.context("lsp ext run flycheck")?;
|
||||
})
|
||||
.context("lsp ext run flycheck")??;
|
||||
};
|
||||
anyhow::Ok(())
|
||||
})
|
||||
@@ -224,11 +226,12 @@ pub fn clear_flycheck(
|
||||
lsp_store
|
||||
.read_with(cx, |lsp_store, _| {
|
||||
if let Some(server) = lsp_store.language_server_for_id(rust_analyzer_server) {
|
||||
server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())?;
|
||||
server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
anyhow::Ok(())
|
||||
})?
|
||||
.context("lsp ext clear flycheck")?;
|
||||
})
|
||||
.context("lsp ext clear flycheck")??;
|
||||
};
|
||||
anyhow::Ok(())
|
||||
})
|
||||
|
||||
@@ -1820,7 +1820,7 @@ async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
||||
}
|
||||
);
|
||||
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(&lsp::PublishDiagnosticsParams {
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
|
||||
uri: Uri::from_file_path(path!("/dir/a.rs")).unwrap(),
|
||||
version: None,
|
||||
diagnostics: vec![lsp::Diagnostic {
|
||||
@@ -1873,7 +1873,7 @@ async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
||||
});
|
||||
|
||||
// Ensure publishing empty diagnostics twice only results in one update event.
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(&lsp::PublishDiagnosticsParams {
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
|
||||
uri: Uri::from_file_path(path!("/dir/a.rs")).unwrap(),
|
||||
version: None,
|
||||
diagnostics: Default::default(),
|
||||
@@ -1886,7 +1886,7 @@ async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
||||
}
|
||||
);
|
||||
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(&lsp::PublishDiagnosticsParams {
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
|
||||
uri: Uri::from_file_path(path!("/dir/a.rs")).unwrap(),
|
||||
version: None,
|
||||
diagnostics: Default::default(),
|
||||
@@ -2018,7 +2018,7 @@ async fn test_restarting_server_with_diagnostics_published(cx: &mut gpui::TestAp
|
||||
|
||||
// Publish diagnostics
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(&lsp::PublishDiagnosticsParams {
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
|
||||
uri: Uri::from_file_path(path!("/dir/a.rs")).unwrap(),
|
||||
version: None,
|
||||
diagnostics: vec![lsp::Diagnostic {
|
||||
@@ -2099,7 +2099,7 @@ async fn test_restarted_server_reporting_invalid_buffer_version(cx: &mut gpui::T
|
||||
|
||||
// Before restarting the server, report diagnostics with an unknown buffer version.
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(&lsp::PublishDiagnosticsParams {
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
|
||||
uri: lsp::Uri::from_file_path(path!("/dir/a.rs")).unwrap(),
|
||||
version: Some(10000),
|
||||
diagnostics: Vec::new(),
|
||||
@@ -2350,7 +2350,7 @@ async fn test_transforming_diagnostics(cx: &mut gpui::TestAppContext) {
|
||||
assert!(change_notification_1.text_document.version > open_notification.text_document.version);
|
||||
|
||||
// Report some diagnostics for the initial version of the buffer
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(&lsp::PublishDiagnosticsParams {
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
|
||||
uri: lsp::Uri::from_file_path(path!("/dir/a.rs")).unwrap(),
|
||||
version: Some(open_notification.text_document.version),
|
||||
diagnostics: vec![
|
||||
@@ -2438,7 +2438,7 @@ async fn test_transforming_diagnostics(cx: &mut gpui::TestAppContext) {
|
||||
});
|
||||
|
||||
// Ensure overlapping diagnostics are highlighted correctly.
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(&lsp::PublishDiagnosticsParams {
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
|
||||
uri: lsp::Uri::from_file_path(path!("/dir/a.rs")).unwrap(),
|
||||
version: Some(open_notification.text_document.version),
|
||||
diagnostics: vec![
|
||||
@@ -2532,7 +2532,7 @@ async fn test_transforming_diagnostics(cx: &mut gpui::TestAppContext) {
|
||||
);
|
||||
|
||||
// Handle out-of-order diagnostics
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(&lsp::PublishDiagnosticsParams {
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
|
||||
uri: lsp::Uri::from_file_path(path!("/dir/a.rs")).unwrap(),
|
||||
version: Some(change_notification_2.text_document.version),
|
||||
diagnostics: vec![
|
||||
|
||||
Reference in New Issue
Block a user