From 9bce5e8b823a184e7702c51f94cf2541faf0e6ea Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 27 Mar 2024 14:30:27 -0700 Subject: [PATCH] Improve diagnostic header UI (#9888) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR rearranges the diagnostics to put the headers to the left of the diagnostic messages and adds an additional button to close the diagnostics. Screenshot 2024-03-27 at 2 01 19 PM Screenshot 2024-03-27 at 2 01 56 PM As a drive by, I also quieted a useless but loud log message. Release Notes: - Added a close button to the `f8` diagnostics. --- crates/copilot/src/copilot.rs | 2 +- crates/editor/src/editor.rs | 62 +++++++++++++------ crates/gpui/src/geometry.rs | 9 ++- .../ui/src/components/button/button_like.rs | 4 +- 4 files changed, 54 insertions(+), 23 deletions(-) diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index 83a0ed11c620b0b83ef7a2b3a42e968976c2a838..48b2d4102a96dd0cf3ee632414f1705d45089adb 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -797,7 +797,7 @@ impl Copilot { ) -> Task> { let server = match self.server.as_authenticated() { Ok(server) => server, - Err(error) => return Task::ready(Err(error)), + Err(_) => return Task::ready(Ok(())), }; let request = server diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 739f770a2795fada17b324538dee8faa452f1522..ff00acb0bb8aaf0b4fa4eb8851da91cf2f5dc470 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -59,12 +59,12 @@ use fuzzy::{StringMatch, StringMatchCandidate}; use git::diff_hunk_to_display; use gpui::{ div, impl_actions, point, prelude::*, px, relative, rems, size, uniform_list, Action, - AnyElement, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context, - DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusableView, FontId, FontStyle, - FontWeight, HighlightStyle, Hsla, InteractiveText, KeyContext, Model, MouseButton, - ParentElement, Pixels, Render, SharedString, StrikethroughStyle, Styled, StyledText, - Subscription, Task, TextStyle, UnderlineStyle, UniformListScrollHandle, View, ViewContext, - ViewInputHandler, VisualContext, WeakView, WhiteSpace, WindowContext, + AnyElement, AppContext, AsyncWindowContext, AvailableSpace, BackgroundExecutor, Bounds, + ClipboardItem, Context, DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusableView, + FontId, FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveText, KeyContext, Model, + MouseButton, ParentElement, Pixels, Render, SharedString, StrikethroughStyle, Styled, + StyledText, Subscription, Task, TextStyle, UnderlineStyle, UniformListScrollHandle, View, + ViewContext, ViewInputHandler, VisualContext, WeakView, WhiteSpace, WindowContext, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; use hover_popover::{hide_hover, HoverState}; @@ -10499,6 +10499,41 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, _is_valid: bool) -> Ren let mut text_style = cx.text_style().clone(); text_style.color = diagnostic_style(diagnostic.severity, true, cx.theme().status()); + let multi_line_diagnostic = diagnostic.message.contains('\n'); + + let buttons = |diagnostic: &Diagnostic, block_id: usize| { + if multi_line_diagnostic { + v_flex() + } else { + h_flex() + } + .children(diagnostic.is_primary.then(|| { + IconButton::new(("close-block", block_id), IconName::XCircle) + .icon_color(Color::Muted) + .size(ButtonSize::Compact) + .style(ButtonStyle::Transparent) + .visible_on_hover(group_id.clone()) + .on_click(move |_click, cx| cx.dispatch_action(Box::new(Cancel))) + .tooltip(|cx| Tooltip::for_action("Close Diagnostics", &Cancel, cx)) + })) + .child( + IconButton::new(("copy-block", block_id), IconName::Copy) + .icon_color(Color::Muted) + .size(ButtonSize::Compact) + .style(ButtonStyle::Transparent) + .visible_on_hover(group_id.clone()) + .on_click({ + let message = diagnostic.message.clone(); + move |_click, cx| cx.write_to_clipboard(ClipboardItem::new(message.clone())) + }) + .tooltip(|cx| Tooltip::text("Copy diagnostic message", cx)), + ) + }; + + let icon_size = buttons(&diagnostic, cx.block_id) + .into_any_element() + .measure(AvailableSpace::min_size(), cx); + h_flex() .id(cx.block_id) .group(group_id.clone()) @@ -10509,9 +10544,10 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, _is_valid: bool) -> Ren .child( div() .flex() - .w(cx.anchor_x - cx.gutter_dimensions.width) + .w(cx.anchor_x - cx.gutter_dimensions.width - icon_size.width) .flex_shrink(), ) + .child(buttons(&diagnostic, cx.block_id)) .child(div().flex().flex_shrink_0().child( StyledText::new(text_without_backticks.clone()).with_highlights( &text_style, @@ -10526,18 +10562,6 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, _is_valid: bool) -> Ren }), ), )) - .child( - IconButton::new(("copy-block", cx.block_id), IconName::Copy) - .icon_color(Color::Muted) - .size(ButtonSize::Compact) - .style(ButtonStyle::Transparent) - .visible_on_hover(group_id) - .on_click({ - let message = diagnostic.message.clone(); - move |_click, cx| cx.write_to_clipboard(ClipboardItem::new(message.clone())) - }) - .tooltip(|cx| Tooltip::text("Copy diagnostic message", cx)), - ) .into_any_element() }) } diff --git a/crates/gpui/src/geometry.rs b/crates/gpui/src/geometry.rs index 7fa50032d829da64bb8f7cb00177787a35cc309b..7eec24b2d18786922fdcf87c4306cc9c81ca65ea 100644 --- a/crates/gpui/src/geometry.rs +++ b/crates/gpui/src/geometry.rs @@ -2480,6 +2480,13 @@ impl From for f64 { #[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)] pub struct Rems(pub f32); +impl Rems { + /// Convert this Rem value to pixels. + pub fn to_pixels(&self, rem_size: Pixels) -> Pixels { + *self * rem_size + } +} + impl Mul for Rems { type Output = Pixels; @@ -2555,7 +2562,7 @@ impl AbsoluteLength { pub fn to_pixels(&self, rem_size: Pixels) -> Pixels { match self { AbsoluteLength::Pixels(pixels) => *pixels, - AbsoluteLength::Rems(rems) => *rems * rem_size, + AbsoluteLength::Rems(rems) => rems.to_pixels(rem_size), } } } diff --git a/crates/ui/src/components/button/button_like.rs b/crates/ui/src/components/button/button_like.rs index a2f6c8fc5496f7e541fa71c4dcaeb08dee983710..eaff3a6e7355204de47410cff447d727cb206676 100644 --- a/crates/ui/src/components/button/button_like.rs +++ b/crates/ui/src/components/button/button_like.rs @@ -276,7 +276,7 @@ pub enum ButtonSize { } impl ButtonSize { - fn height(self) -> Rems { + pub fn rems(self) -> Rems { match self { ButtonSize::Large => rems_from_px(32.), ButtonSize::Default => rems_from_px(22.), @@ -424,7 +424,7 @@ impl RenderOnce for ButtonLike { .id(self.id.clone()) .group("") .flex_none() - .h(self.height.unwrap_or(self.size.height().into())) + .h(self.height.unwrap_or(self.size.rems().into())) .when_some(self.width, |this, width| this.w(width).justify_center()) .when_some(self.rounding, |this, rounding| match rounding { ButtonLikeRounding::All => this.rounded_md(),