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::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::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::< + ::Result, + >( + lsp_types::request::ShowMessageRequest::METHOD, &result + ) { + this.send_notification::(()); + } + }, + ), + false => self.send_notification::( + 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::(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 }