lsp: Add support for ShowMessage notification (#14012)

Piotr Osiewicz created

When "one newer language" sends these messages, "one newer editor" will
display a pop-up for users to see. :)

Related to https://github.com/gleam-lang/gleam/issues/3274


![image](https://github.com/zed-industries/zed/assets/24362066/00d2c168-59f0-4033-91c8-af29c47516b3)

Release Notes:

- A certain popular language recently had to work around a missing LSP
notification. This has been fixed

Change summary

crates/project/src/project.rs | 65 +++++++++++++++++++++++++-----------
1 file changed, 44 insertions(+), 21 deletions(-)

Detailed changes

crates/project/src/project.rs 🔗

@@ -3676,29 +3676,26 @@ impl Project {
                     let this = this.clone();
                     let name = name.to_string();
                     async move {
-                        if let Some(actions) = params.actions {
-                            let (tx, mut rx) = smol::channel::bounded(1);
-                            let request = LanguageServerPromptRequest {
-                                level: match params.typ {
-                                    lsp::MessageType::ERROR => PromptLevel::Critical,
-                                    lsp::MessageType::WARNING => PromptLevel::Warning,
-                                    _ => PromptLevel::Info,
-                                },
-                                message: params.message,
-                                actions,
-                                response_channel: tx,
-                                lsp_name: name.clone(),
-                            };
+                        let actions = params.actions.unwrap_or_default();
+                        let (tx, mut rx) = smol::channel::bounded(1);
+                        let request = LanguageServerPromptRequest {
+                            level: match params.typ {
+                                lsp::MessageType::ERROR => PromptLevel::Critical,
+                                lsp::MessageType::WARNING => PromptLevel::Warning,
+                                _ => PromptLevel::Info,
+                            },
+                            message: params.message,
+                            actions,
+                            response_channel: tx,
+                            lsp_name: name.clone(),
+                        };
 
-                            if let Ok(_) = this.update(&mut cx, |_, cx| {
-                                cx.emit(Event::LanguageServerPrompt(request));
-                            }) {
-                                let response = rx.next().await;
+                        if let Ok(_) = this.update(&mut cx, |_, cx| {
+                            cx.emit(Event::LanguageServerPrompt(request));
+                        }) {
+                            let response = rx.next().await;
 
-                                Ok(response)
-                            } else {
-                                Ok(None)
-                            }
+                            Ok(response)
                         } else {
                             Ok(None)
                         }
@@ -3753,7 +3750,33 @@ impl Project {
                 }
             })
             .detach();
+        language_server
+            .on_notification::<lsp::notification::ShowMessage, _>({
+                let this = this.clone();
+                let name = name.to_string();
+                move |params, mut cx| {
+                    let this = this.clone();
+                    let name = name.to_string();
+
+                    let (tx, _) = smol::channel::bounded(1);
+                    let request = LanguageServerPromptRequest {
+                        level: match params.typ {
+                            lsp::MessageType::ERROR => PromptLevel::Critical,
+                            lsp::MessageType::WARNING => PromptLevel::Warning,
+                            _ => PromptLevel::Info,
+                        },
+                        message: params.message,
+                        actions: vec![],
+                        response_channel: tx,
+                        lsp_name: name.clone(),
+                    };
 
+                    let _ = this.update(&mut cx, |_, cx| {
+                        cx.emit(Event::LanguageServerPrompt(request));
+                    });
+                }
+            })
+            .detach();
         language_server
             .on_notification::<lsp::notification::Progress, _>(move |params, mut cx| {
                 if let Some(this) = this.upgrade() {