markdown: Refactor code block copy button visibility to use enum (#52817)

Release Notes:

- N/A

---------

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: Finn Evers <finn.evers@outlook.de>
Co-authored-by: MrSubidubi <finn@zed.dev>
This commit is contained in:
authored and GitHub committed 2026-04-01 09:05:03 +00:00
1 parent e6b79d9ea4
commit 416f296d80
11 files changed
+61 -77

No files matched your search

+6 -3
View File
@@ -13,7 +13,7 @@ use gpui::{
StyleRefinement, Subscription, Task, TextStyleRefinement, Window, actions, list, prelude::*,
};
use language::LanguageRegistry;
use markdown::{CodeBlockRenderer, Markdown, MarkdownElement, MarkdownStyle};
use markdown::{CodeBlockRenderer, CopyButtonVisibility, Markdown, MarkdownElement, MarkdownStyle};
use project::{AgentId, Project};
use settings::Settings;
use theme_settings::ThemeSettings;
@@ -384,8 +384,11 @@ impl AcpTools {
)
.code_block_renderer(
CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: expanded,
copy_button_visibility: if expanded {
CopyButtonVisibility::VisibleOnHover
} else {
CopyButtonVisibility::Hidden
},
border: false,
},
),
@@ -8,7 +8,7 @@ use editor::{
use gpui::{AppContext, Entity, Focusable, WeakEntity};
use language::{BufferId, Diagnostic, DiagnosticEntryRef, LanguageRegistry};
use lsp::DiagnosticSeverity;
use markdown::{Markdown, MarkdownElement};
use markdown::{CopyButtonVisibility, Markdown, MarkdownElement};
use settings::Settings;
use text::{AnchorRangeExt, Point};
use theme_settings::ThemeSettings;
@@ -239,8 +239,7 @@ impl DiagnosticBlock {
diagnostics_markdown_style(bcx.window, cx),
)
.code_block_renderer(markdown::CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
})
.on_url_click({
+2 -3
View File
@@ -9,7 +9,7 @@ use itertools::Itertools;
use language::CodeLabel;
use language::{Buffer, LanguageName, LanguageRegistry};
use lsp::CompletionItemTag;
use markdown::{Markdown, MarkdownElement};
use markdown::{CopyButtonVisibility, Markdown, MarkdownElement};
use multi_buffer::{Anchor, ExcerptId};
use ordered_float::OrderedFloat;
use project::lsp_store::CompletionDocumentation;
@@ -1118,8 +1118,7 @@ impl CompletionsMenu {
div().child(
MarkdownElement::new(markdown, hover_markdown_style(window, cx))
.code_block_renderer(markdown::CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
})
.on_url_click(open_markdown_url),
+3 -5
View File
@@ -17,7 +17,7 @@ use gpui::{
use itertools::Itertools;
use language::{DiagnosticEntry, Language, LanguageRegistry};
use lsp::DiagnosticSeverity;
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
use markdown::{CopyButtonVisibility, Markdown, MarkdownElement, MarkdownStyle};
use multi_buffer::{MultiBufferOffset, ToOffset, ToPoint};
use project::{HoverBlock, HoverBlockKind, InlayHintLabelPart};
use settings::Settings;
@@ -1040,8 +1040,7 @@ impl InfoPopover {
.child(
MarkdownElement::new(markdown, hover_markdown_style(window, cx))
.code_block_renderer(markdown::CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
})
.on_url_click(open_markdown_url)
@@ -1155,8 +1154,7 @@ impl DiagnosticPopover {
diagnostics_markdown_style(window, cx),
)
.code_block_renderer(markdown::CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
})
.on_url_click(
+3 -5
View File
@@ -7,7 +7,7 @@ use gpui::{
};
use language::BufferSnapshot;
use markdown::{Markdown, MarkdownElement};
use markdown::{CopyButtonVisibility, Markdown, MarkdownElement};
use multi_buffer::{Anchor, MultiBufferOffset, ToOffset};
use settings::Settings;
use std::ops::Range;
@@ -408,9 +408,8 @@ impl SignatureHelpPopover {
hover_markdown_style(window, cx),
)
.code_block_renderer(markdown::CodeBlockRenderer::Default {
copy_button: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
copy_button_on_hover: false,
})
.on_url_click(open_markdown_url),
)
@@ -421,9 +420,8 @@ impl SignatureHelpPopover {
.child(
MarkdownElement::new(description, hover_markdown_style(window, cx))
.code_block_renderer(markdown::CodeBlockRenderer::Default {
copy_button: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
copy_button_on_hover: false,
})
.on_url_click(open_markdown_url),
)
+6 -5
View File
@@ -497,7 +497,10 @@ mod tests {
use gpui::{TestAppContext, size};
use ui::prelude::*;
use crate::{CodeBlockRenderer, Markdown, MarkdownElement, MarkdownOptions, MarkdownStyle};
use crate::{
CodeBlockRenderer, CopyButtonVisibility, Markdown, MarkdownElement, MarkdownOptions,
MarkdownStyle,
};
fn ensure_theme_initialized(cx: &mut TestAppContext) {
cx.update(|cx| {
@@ -530,8 +533,7 @@ mod tests {
|_window, _cx| {
MarkdownElement::new(markdown, MarkdownStyle::default()).code_block_renderer(
CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
},
)
@@ -591,8 +593,7 @@ mod tests {
|_window, _cx| {
MarkdownElement::new(markdown, MarkdownStyle::default()).code_block_renderer(
CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
},
)
+22 -39
View File
@@ -270,10 +270,16 @@ pub struct MarkdownOptions {
pub render_mermaid_diagrams: bool,
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum CopyButtonVisibility {
Hidden,
AlwaysVisible,
VisibleOnHover,
}
pub enum CodeBlockRenderer {
Default {
copy_button: bool,
copy_button_on_hover: bool,
copy_button_visibility: CopyButtonVisibility,
border: bool,
},
Custom {
@@ -826,8 +832,7 @@ impl MarkdownElement {
markdown,
style,
code_block_renderer: CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: true,
copy_button_visibility: CopyButtonVisibility::VisibleOnHover,
border: false,
},
on_url_click: None,
@@ -1686,38 +1691,10 @@ impl Element for MarkdownElement {
builder.pop_text_style();
if let CodeBlockRenderer::Default {
copy_button: true, ..
} = &self.code_block_renderer
{
builder.modify_current_div(|el| {
let content_range = parser::extract_code_block_content_range(
&parsed_markdown.source()[range.clone()],
);
let content_range = content_range.start + range.start
..content_range.end + range.start;
let code = parsed_markdown.source()[content_range].to_string();
let codeblock = render_copy_code_block_button(
range.end,
code,
self.markdown.clone(),
);
el.child(
h_flex()
.w_4()
.absolute()
.top_1p5()
.right_1p5()
.justify_end()
.child(codeblock),
)
});
}
if let CodeBlockRenderer::Default {
copy_button_on_hover: true,
copy_button_visibility,
..
} = &self.code_block_renderer
&& *copy_button_visibility != CopyButtonVisibility::Hidden
{
builder.modify_current_div(|el| {
let content_range = parser::extract_code_block_content_range(
@@ -1736,10 +1713,17 @@ impl Element for MarkdownElement {
h_flex()
.w_4()
.absolute()
.top_0()
.right_0()
.justify_end()
.visible_on_hover("code_block")
.when_else(
*copy_button_visibility
== CopyButtonVisibility::VisibleOnHover,
|this| {
this.top_0()
.right_0()
.visible_on_hover("code_block")
},
|this| this.top_1p5().right_1p5(),
)
.child(codeblock),
)
});
@@ -2772,8 +2756,7 @@ mod tests {
|_window, _cx| {
MarkdownElement::new(markdown, MarkdownStyle::default()).code_block_renderer(
CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
},
)
+6 -5
View File
@@ -266,7 +266,10 @@ mod tests {
CachedMermaidDiagram, MermaidDiagramCache, MermaidState,
ParsedMarkdownMermaidDiagramContents, extract_mermaid_diagrams, parse_mermaid_info,
};
use crate::{CodeBlockRenderer, Markdown, MarkdownElement, MarkdownOptions, MarkdownStyle};
use crate::{
CodeBlockRenderer, CopyButtonVisibility, Markdown, MarkdownElement, MarkdownOptions,
MarkdownStyle,
};
use collections::HashMap;
use gpui::{Context, IntoElement, Render, RenderImage, TestAppContext, Window, size};
use std::sync::Arc;
@@ -309,8 +312,7 @@ mod tests {
|_window, _cx| {
MarkdownElement::new(markdown, MarkdownStyle::default()).code_block_renderer(
CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
},
)
@@ -581,8 +583,7 @@ mod tests {
|_window, _cx| {
MarkdownElement::new(markdown.clone(), MarkdownStyle::default())
.code_block_renderer(CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
})
},
@@ -13,7 +13,8 @@ use gpui::{
};
use language::LanguageRegistry;
use markdown::{
CodeBlockRenderer, Markdown, MarkdownElement, MarkdownFont, MarkdownOptions, MarkdownStyle,
CodeBlockRenderer, CopyButtonVisibility, Markdown, MarkdownElement, MarkdownFont,
MarkdownOptions, MarkdownStyle,
};
use settings::Settings;
use theme_settings::ThemeSettings;
@@ -593,8 +594,7 @@ impl MarkdownPreviewView {
MarkdownStyle::themed(MarkdownFont::Editor, window, cx),
)
.code_block_renderer(CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: true,
copy_button_visibility: CopyButtonVisibility::VisibleOnHover,
border: false,
})
.scroll_handle(self.scroll_handle.clone())
+2 -3
View File
@@ -5,7 +5,7 @@ use gpui::{
DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, PromptLevel, Render, ScrollHandle,
Task, TextStyleRefinement, UnderlineStyle, WeakEntity, svg,
};
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
use markdown::{CopyButtonVisibility, Markdown, MarkdownElement, MarkdownStyle};
use parking_lot::Mutex;
use project::project_settings::ProjectSettings;
use settings::Settings;
@@ -401,8 +401,7 @@ impl Render for LanguageServerPrompt {
MarkdownElement::new(self.markdown.clone(), markdown_style(window, cx))
.text_size(TextSize::Small.rems(cx))
.code_block_renderer(markdown::CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: false,
copy_button_visibility: CopyButtonVisibility::Hidden,
border: false,
})
.on_url_click(|link, _, cx| cx.open_url(&link)),
+6 -3
View File
@@ -12,7 +12,7 @@ use gpui::{
StyleRefinement, Task, TextStyleRefinement, Window, list, prelude::*,
};
use language::LanguageRegistry;
use markdown::{CodeBlockRenderer, Markdown, MarkdownElement, MarkdownStyle};
use markdown::{CodeBlockRenderer, CopyButtonVisibility, Markdown, MarkdownElement, MarkdownStyle};
use project::Project;
use settings::Settings;
use telemetry_events::{Event, EventWrapper};
@@ -424,8 +424,11 @@ impl TelemetryLogView {
},
)
.code_block_renderer(CodeBlockRenderer::Default {
copy_button: false,
copy_button_on_hover: expanded,
copy_button_visibility: if expanded {
CopyButtonVisibility::VisibleOnHover
} else {
CopyButtonVisibility::Hidden
},
border: false,
}),
),