From aaab9f69602df78d79116ad8c91679d83f2c39da Mon Sep 17 00:00:00 2001 From: Rocky Shi Date: Tue, 30 Dec 2025 01:31:29 +1300 Subject: [PATCH] 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: image --------- Co-authored-by: Danilo Leal --- crates/editor/src/hover_popover.rs | 36 +++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index 64415005ec61b1ce942e4fbedaabc70919f5e61d..784b27d327dba7c64690fd6f87599d9566ab2ab6 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -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::()