about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs40
-rw-r--r--crates/rust-analyzer/src/main_loop.rs17
-rw-r--r--crates/rust-analyzer/src/reload.rs25
3 files changed, 62 insertions, 20 deletions
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index 30f1c53c198..12e5caf2cc9 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -36,11 +36,41 @@ impl Progress {
 }
 
 impl GlobalState {
-    pub(crate) fn show_message(&mut self, typ: lsp_types::MessageType, message: String) {
-        let message = message;
-        self.send_notification::<lsp_types::notification::ShowMessage>(
-            lsp_types::ShowMessageParams { typ, message },
-        )
+    pub(crate) fn show_message(
+        &mut self,
+        typ: lsp_types::MessageType,
+        message: String,
+        show_open_log_button: bool,
+    ) {
+        match self.config.open_server_logs() && show_open_log_button  {
+            true => self.send_request::<lsp_types::request::ShowMessageRequest>(
+                lsp_types::ShowMessageRequestParams {
+                    typ,
+                    message,
+                    actions: Some(vec![lsp_types::MessageActionItem {
+                        title: "Open server logs".to_owned(),
+                        properties: Default::default(),
+                    }]),
+                },
+                |this, resp| {
+                    let lsp_server::Response { error: None, result: Some(result), .. } = resp
+                    else { return };
+                    if let Ok(Some(_item)) = crate::from_json::<
+                        <lsp_types::request::ShowMessageRequest as lsp_types::request::Request>::Result,
+                    >(
+                        lsp_types::request::ShowMessageRequest::METHOD, &result
+                    ) {
+                        this.send_notification::<lsp_ext::OpenServerLogs>(());
+                    }
+                },
+            ),
+            false => self.send_notification::<lsp_types::notification::ShowMessage>(
+                lsp_types::ShowMessageParams {
+                    typ,
+                    message,
+                },
+            ),
+        }
     }
 
     /// Sends a notification to the client containing the error `message`.
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index dd0804b4398..2752e710342 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -406,9 +406,19 @@ impl GlobalState {
 
             if self.config.server_status_notification() {
                 self.send_notification::<lsp_ext::ServerStatusNotification>(status);
-            } else if let (lsp_ext::Health::Error, Some(message)) = (status.health, &status.message)
-            {
-                self.show_and_log_error(message.clone(), None);
+            } else if let (health, Some(message)) = (status.health, &status.message) {
+                let open_log_button = tracing::enabled!(tracing::Level::ERROR)
+                    && (self.fetch_build_data_error().is_err()
+                        || self.fetch_workspace_error().is_err());
+                self.show_message(
+                    match health {
+                        lsp_ext::Health::Ok => lsp_types::MessageType::INFO,
+                        lsp_ext::Health::Warning => lsp_types::MessageType::WARNING,
+                        lsp_ext::Health::Error => lsp_types::MessageType::ERROR,
+                    },
+                    message.clone(),
+                    open_log_button,
+                );
             }
         }
     }
@@ -919,6 +929,7 @@ impl GlobalState {
                                         this.show_message(
                                             lsp_types::MessageType::WARNING,
                                             error.to_string(),
+                                            false,
                                         );
                                     }
                                     this.update_configuration(config);
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 28d37f5685a..ffbea4de16f 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -90,38 +90,39 @@ impl GlobalState {
             quiescent: self.is_quiescent(),
             message: None,
         };
+        let mut message = String::new();
 
         if self.proc_macro_changed {
             status.health = lsp_ext::Health::Warning;
-            status.message =
-                Some("Reload required due to source changes of a procedural macro.".into())
+            message.push_str("Reload required due to source changes of a procedural macro.\n\n");
         }
         if let Err(_) = self.fetch_build_data_error() {
             status.health = lsp_ext::Health::Warning;
-            status.message =
-                Some("Failed to run build scripts of some packages, check the logs.".to_string());
+            message.push_str("Failed to run build scripts of some packages.\n\n");
         }
         if !self.config.cargo_autoreload()
             && self.is_quiescent()
             && self.fetch_workspaces_queue.op_requested()
         {
             status.health = lsp_ext::Health::Warning;
-            status.message = Some("Workspace reload required".to_string())
+            message.push_str("Auto-reloading is disabled, a workspace reload required.\n\n");
         }
-
-        if let Err(_) = self.fetch_workspace_error() {
-            status.health = lsp_ext::Health::Error;
-            status.message = Some("Failed to load workspaces".to_string())
-        }
-
         if self.config.linked_projects().is_empty()
             && self.config.detached_files().is_empty()
             && self.config.notifications().cargo_toml_not_found
         {
             status.health = lsp_ext::Health::Warning;
-            status.message = Some("Failed to discover workspace".to_string())
+            message.push_str("Failed to discover workspace.\n\n");
         }
 
+        if let Err(_) = self.fetch_workspace_error() {
+            status.health = lsp_ext::Health::Error;
+            message.push_str("Failed to load workspaces\n\n");
+        }
+
+        if !message.is_empty() {
+            status.message = Some(message.trim_end().to_owned());
+        }
         status
     }