Add a button to copy diagnostic messages from the hover popover to the clipboard (#45625)

Closes https://github.com/zed-industries/zed/issues/45346

Release Notes:

- Added a button to copy diagnostic messages from the hove popover

Screenshot:

<img width="842" height="360" alt="image"
src="https://github.com/user-attachments/assets/9c00fba5-82aa-4179-95b1-afd5c1173889"
/>

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
Rocky Shi
2025-12-30 01:31:29 +13:00
committed by GitHub
parent 209cf0a48f
commit aaab9f6960

View File

@@ -8,8 +8,8 @@ use crate::{
};
use anyhow::Context as _;
use gpui::{
AnyElement, AsyncWindowContext, Context, Entity, Focusable as _, FontWeight, Hsla,
InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels, ScrollHandle, Size,
AnyElement, AsyncWindowContext, ClipboardItem, Context, Entity, Focusable as _, FontWeight,
Hsla, InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels, ScrollHandle, Size,
StatefulInteractiveElement, StyleRefinement, Styled, Subscription, Task, TextStyleRefinement,
Window, div, px,
};
@@ -24,7 +24,7 @@ use std::{borrow::Cow, cell::RefCell};
use std::{ops::Range, sync::Arc, time::Duration};
use std::{path::PathBuf, rc::Rc};
use theme::ThemeSettings;
use ui::{Scrollbars, WithScrollbar, prelude::*, theme_is_transparent};
use ui::{Scrollbars, Tooltip, WithScrollbar, prelude::*, theme_is_transparent};
use url::Url;
use util::TryFutureExt;
use workspace::{OpenOptions, OpenVisible, Workspace};
@@ -994,11 +994,13 @@ impl DiagnosticPopover {
.border_color(self.border_color)
.rounded_lg()
.child(
div()
h_flex()
.id("diagnostic-content-container")
.overflow_y_scroll()
.gap_1()
.items_start()
.max_w(max_size.width)
.max_h(max_size.height)
.overflow_y_scroll()
.track_scroll(&self.scroll_handle)
.child(
MarkdownElement::new(
@@ -1021,7 +1023,29 @@ impl DiagnosticPopover {
}
},
),
),
)
.child({
let message = self.local_diagnostic.diagnostic.message.clone();
let copied = cx
.read_from_clipboard()
.map(|item| item.text().as_ref() == Some(&message))
.unwrap_or(false);
let (icon, color) = if copied {
(IconName::Check, Color::Success)
} else {
(IconName::Copy, Color::Muted)
};
IconButton::new("copy-diagnostic", icon)
.icon_color(color)
.icon_size(IconSize::Small)
.tooltip(Tooltip::text("Copy Diagnostic"))
.on_click(move |_, _, cx| {
cx.write_to_clipboard(ClipboardItem::new_string(
message.clone(),
));
})
}),
)
.custom_scrollbars(
Scrollbars::for_settings::<EditorSettings>()