lsp: Handle dynamic registration of workspace diagnostic capabilities (#40095)

Piotr Osiewicz created

Workspace diagnostics in Zed have a dedicated background task that
handles querying the language server based on workspace diagnostics
refresh requests issued by both Zed and language server itself.
We only spawned that task when language server declared support for
workspace diagnostics on boot-up. This made workspace diagnostics
unavailable
when a language server (say, Ty) declared support via a capability
registration.
Originally reported in
https://github.com/zed-industries/zed/issues/39144#issuecomment-3370320004

Release Notes:

- python: Fixed workspace diagnostics not working with Ty.

Change summary

crates/project/src/lsp_store.rs | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)

Detailed changes

crates/project/src/lsp_store.rs 🔗

@@ -11444,9 +11444,25 @@ impl LspStore {
                         .map(serde_json::from_value)
                         .transpose()?
                     {
+                        let state = self
+                            .as_local_mut()
+                            .context("Expected LSP Store to be local")?
+                            .language_servers
+                            .get_mut(&server_id)
+                            .context("Could not obtain Language Servers state")?;
                         server.update_capabilities(|capabilities| {
                             capabilities.diagnostic_provider = Some(caps);
                         });
+                        if let LanguageServerState::Running {
+                            workspace_refresh_task,
+                            ..
+                        } = state
+                            && workspace_refresh_task.is_none()
+                        {
+                            *workspace_refresh_task =
+                                lsp_workspace_diagnostics_refresh(server.clone(), cx)
+                        }
+
                         notify_server_capabilities_updated(&server, cx);
                     }
                 }
@@ -11610,6 +11626,19 @@ impl LspStore {
                     server.update_capabilities(|capabilities| {
                         capabilities.diagnostic_provider = None;
                     });
+                    let state = self
+                        .as_local_mut()
+                        .context("Expected LSP Store to be local")?
+                        .language_servers
+                        .get_mut(&server_id)
+                        .context("Could not obtain Language Servers state")?;
+                    if let LanguageServerState::Running {
+                        workspace_refresh_task,
+                        ..
+                    } = state
+                    {
+                        _ = workspace_refresh_task.take();
+                    }
                     notify_server_capabilities_updated(&server, cx);
                 }
                 "textDocument/documentColor" => {