Reintroduce LSP diagnostic/status message

Julia and Antonio Scandurra created

Co-Authored-By: Antonio Scandurra <antonio@zed.dev>

Change summary

crates/activity_indicator2/src/activity_indicator.rs |  4 +-
crates/diagnostics2/src/items.rs                     | 22 ++++++++++++-
crates/workspace2/src/pane.rs                        | 17 ++++++++++
crates/workspace2/src/status_bar.rs                  |  9 +++++
4 files changed, 47 insertions(+), 5 deletions(-)

Detailed changes

crates/activity_indicator2/src/activity_indicator.rs πŸ”—

@@ -10,7 +10,7 @@ use language::{LanguageRegistry, LanguageServerBinaryStatus};
 use project::{LanguageServerProgress, Project};
 use smallvec::SmallVec;
 use std::{cmp::Reverse, fmt::Write, sync::Arc};
-use ui::h_stack;
+use ui::{h_stack, Label};
 use util::ResultExt;
 use workspace::{item::ItemHandle, StatusItemView, Workspace};
 
@@ -324,7 +324,7 @@ impl Render for ActivityIndicator {
 
         result
             .children(content.icon.map(|icon| svg().path(icon)))
-            .child(SharedString::from(content.message))
+            .child(Label::new(SharedString::from(content.message)))
     }
 }
 

crates/diagnostics2/src/items.rs πŸ”—

@@ -1,13 +1,13 @@
 use collections::HashSet;
 use editor::{Editor, GoToDiagnostic};
 use gpui::{
-    rems, Div, EventEmitter, InteractiveElement, ParentElement, Render, Stateful,
+    rems, Div, EventEmitter, InteractiveElement, IntoElement, ParentElement, Render, Stateful,
     StatefulInteractiveElement, Styled, Subscription, View, ViewContext, WeakView,
 };
 use language::Diagnostic;
 use lsp::LanguageServerId;
 use theme::ActiveTheme;
-use ui::{h_stack, Color, Icon, IconElement, Label, Tooltip};
+use ui::{h_stack, Button, Clickable, Color, Icon, IconElement, Label, Tooltip};
 use workspace::{item::ItemHandle, StatusItemView, ToolbarItemEvent, Workspace};
 
 use crate::ProjectDiagnosticsEditor;
@@ -43,13 +43,28 @@ impl Render for DiagnosticIndicator {
                 .child(Label::new(warning_count.to_string())),
         };
 
+        let status = if !self.in_progress_checks.is_empty() {
+            Some(Label::new("Checking…").into_any_element())
+        } else if let Some(diagnostic) = &self.current_diagnostic {
+            let message = diagnostic.message.split('\n').next().unwrap().to_string();
+            Some(
+                Button::new("diagnostic_message", message)
+                    .on_click(cx.listener(|this, _, cx| {
+                        this.go_to_next_diagnostic(&GoToDiagnostic, cx);
+                    }))
+                    .into_any_element(),
+            )
+        } else {
+            None
+        };
+
         h_stack()
             .id("diagnostic-indicator")
             .on_action(cx.listener(Self::go_to_next_diagnostic))
             .rounded_md()
             .flex_none()
             .h(rems(1.375))
-            .px_1()
+            .px_6()
             .cursor_pointer()
             .bg(cx.theme().colors().ghost_element_background)
             .hover(|style| style.bg(cx.theme().colors().ghost_element_hover))
@@ -63,6 +78,7 @@ impl Render for DiagnosticIndicator {
                 }
             }))
             .child(diagnostic_indicator)
+            .children(status)
     }
 }
 

crates/workspace2/src/pane.rs πŸ”—

@@ -789,6 +789,7 @@ impl Pane {
             }
 
             self.update_toolbar(cx);
+            self.update_status_bar(cx);
 
             if focus_item {
                 self.focus_active_item(cx);
@@ -1450,6 +1451,22 @@ impl Pane {
         });
     }
 
+    fn update_status_bar(&mut self, cx: &mut ViewContext<Self>) {
+        let Ok(status_bar) = self
+            .workspace
+            .update(cx, |workspace, _| workspace.status_bar.clone())
+        else {
+            return;
+        };
+
+        let pane = cx.view().clone();
+        cx.window_context().defer(move |cx| {
+            status_bar.update(cx, move |status_bar, cx| {
+                status_bar.set_active_pane(&pane, cx);
+            });
+        });
+    }
+
     fn render_tab(
         &self,
         ix: usize,

crates/workspace2/src/status_bar.rs πŸ”—

@@ -83,6 +83,9 @@ impl StatusBar {
     where
         T: 'static + StatusItemView,
     {
+        let active_pane_item = self.active_pane.read(cx).active_item();
+        item.set_active_pane_item(active_pane_item.as_deref(), cx);
+
         self.left_items.push(Box::new(item));
         cx.notify();
     }
@@ -119,6 +122,9 @@ impl StatusBar {
     ) where
         T: 'static + StatusItemView,
     {
+        let active_pane_item = self.active_pane.read(cx).active_item();
+        item.set_active_pane_item(active_pane_item.as_deref(), cx);
+
         if position < self.left_items.len() {
             self.left_items.insert(position + 1, Box::new(item))
         } else {
@@ -141,6 +147,9 @@ impl StatusBar {
     where
         T: 'static + StatusItemView,
     {
+        let active_pane_item = self.active_pane.read(cx).active_item();
+        item.set_active_pane_item(active_pane_item.as_deref(), cx);
+
         self.right_items.push(Box::new(item));
         cx.notify();
     }