Improve diagnostic header UI (#9888)

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.

<img width="394" alt="Screenshot 2024-03-27 at 2 01 19 PM"
src="https://github.com/zed-industries/zed/assets/2280405/83be4051-6441-47c6-9b48-77c75ce9c8eb">

<img width="326" alt="Screenshot 2024-03-27 at 2 01 56 PM"
src="https://github.com/zed-industries/zed/assets/2280405/d849ca34-91e9-4de6-9d9c-503b75e97d60">

As a drive by, I also quieted a useless but loud log message.

Release Notes:

- Added a close button to the `f8` diagnostics.
This commit is contained in:
Mikayla Maki 2024-03-27 14:30:27 -07:00 committed by GitHub
parent 80242584e7
commit 9bce5e8b82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 54 additions and 23 deletions

View file

@ -797,7 +797,7 @@ impl Copilot {
) -> Task<Result<()>> { ) -> Task<Result<()>> {
let server = match self.server.as_authenticated() { let server = match self.server.as_authenticated() {
Ok(server) => server, Ok(server) => server,
Err(error) => return Task::ready(Err(error)), Err(_) => return Task::ready(Ok(())),
}; };
let request = let request =
server server

View file

@ -59,12 +59,12 @@ use fuzzy::{StringMatch, StringMatchCandidate};
use git::diff_hunk_to_display; use git::diff_hunk_to_display;
use gpui::{ use gpui::{
div, impl_actions, point, prelude::*, px, relative, rems, size, uniform_list, Action, div, impl_actions, point, prelude::*, px, relative, rems, size, uniform_list, Action,
AnyElement, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context, AnyElement, AppContext, AsyncWindowContext, AvailableSpace, BackgroundExecutor, Bounds,
DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusableView, FontId, FontStyle, ClipboardItem, Context, DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusableView,
FontWeight, HighlightStyle, Hsla, InteractiveText, KeyContext, Model, MouseButton, FontId, FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveText, KeyContext, Model,
ParentElement, Pixels, Render, SharedString, StrikethroughStyle, Styled, StyledText, MouseButton, ParentElement, Pixels, Render, SharedString, StrikethroughStyle, Styled,
Subscription, Task, TextStyle, UnderlineStyle, UniformListScrollHandle, View, ViewContext, StyledText, Subscription, Task, TextStyle, UnderlineStyle, UniformListScrollHandle, View,
ViewInputHandler, VisualContext, WeakView, WhiteSpace, WindowContext, ViewContext, ViewInputHandler, VisualContext, WeakView, WhiteSpace, WindowContext,
}; };
use highlight_matching_bracket::refresh_matching_bracket_highlights; use highlight_matching_bracket::refresh_matching_bracket_highlights;
use hover_popover::{hide_hover, HoverState}; 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(); let mut text_style = cx.text_style().clone();
text_style.color = diagnostic_style(diagnostic.severity, true, cx.theme().status()); 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() h_flex()
.id(cx.block_id) .id(cx.block_id)
.group(group_id.clone()) .group(group_id.clone())
@ -10509,9 +10544,10 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, _is_valid: bool) -> Ren
.child( .child(
div() div()
.flex() .flex()
.w(cx.anchor_x - cx.gutter_dimensions.width) .w(cx.anchor_x - cx.gutter_dimensions.width - icon_size.width)
.flex_shrink(), .flex_shrink(),
) )
.child(buttons(&diagnostic, cx.block_id))
.child(div().flex().flex_shrink_0().child( .child(div().flex().flex_shrink_0().child(
StyledText::new(text_without_backticks.clone()).with_highlights( StyledText::new(text_without_backticks.clone()).with_highlights(
&text_style, &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() .into_any_element()
}) })
} }

View file

@ -2480,6 +2480,13 @@ impl From<ScaledPixels> for f64 {
#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)] #[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
pub struct Rems(pub f32); 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<Pixels> for Rems { impl Mul<Pixels> for Rems {
type Output = Pixels; type Output = Pixels;
@ -2555,7 +2562,7 @@ impl AbsoluteLength {
pub fn to_pixels(&self, rem_size: Pixels) -> Pixels { pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
match self { match self {
AbsoluteLength::Pixels(pixels) => *pixels, AbsoluteLength::Pixels(pixels) => *pixels,
AbsoluteLength::Rems(rems) => *rems * rem_size, AbsoluteLength::Rems(rems) => rems.to_pixels(rem_size),
} }
} }
} }

View file

@ -276,7 +276,7 @@ pub enum ButtonSize {
} }
impl ButtonSize { impl ButtonSize {
fn height(self) -> Rems { pub fn rems(self) -> Rems {
match self { match self {
ButtonSize::Large => rems_from_px(32.), ButtonSize::Large => rems_from_px(32.),
ButtonSize::Default => rems_from_px(22.), ButtonSize::Default => rems_from_px(22.),
@ -424,7 +424,7 @@ impl RenderOnce for ButtonLike {
.id(self.id.clone()) .id(self.id.clone())
.group("") .group("")
.flex_none() .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.width, |this, width| this.w(width).justify_center())
.when_some(self.rounding, |this, rounding| match rounding { .when_some(self.rounding, |this, rounding| match rounding {
ButtonLikeRounding::All => this.rounded_md(), ButtonLikeRounding::All => this.rounded_md(),