From 6970ab2040394e64afb633fcffe8a0e9847cca5e Mon Sep 17 00:00:00 2001 From: Bartosz Kaszubowski Date: Thu, 2 Oct 2025 14:39:18 +0200 Subject: [PATCH] markdown_preview: Stylize links using accented text color (#39149) # How Emphasize links in Markdown Preview text using accented text color. > [!note] > I have chosen the accent color for links since it was looking fine with all bundled by default themes, but I'm happy to alter the color to use different theme value, if you have better candidates. Release Notes: - Stylize links using accented text color in Markdown Preview # Preview ### Before Screenshot 2025-09-29 at 22 19 38 ### After Screenshot 2025-09-29 at 22 18 20 Screenshot 2025-09-29 at 22 18 47 **Release notes** Screenshot 2025-09-29 at 22 36 33 Screenshot 2025-09-29 at 22 40 41 --- .../markdown_preview/src/markdown_elements.rs | 19 +++++++++++++++++-- .../markdown_preview/src/markdown_parser.rs | 4 ++-- .../markdown_preview/src/markdown_renderer.rs | 5 ++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/crates/markdown_preview/src/markdown_elements.rs b/crates/markdown_preview/src/markdown_elements.rs index 560e468439..4da6c4ca5a 100644 --- a/crates/markdown_preview/src/markdown_elements.rs +++ b/crates/markdown_preview/src/markdown_elements.rs @@ -1,5 +1,5 @@ use gpui::{ - DefiniteLength, FontStyle, FontWeight, HighlightStyle, SharedString, StrikethroughStyle, + DefiniteLength, FontStyle, FontWeight, HighlightStyle, Hsla, SharedString, StrikethroughStyle, UnderlineStyle, px, }; use language::HighlightId; @@ -175,7 +175,11 @@ pub enum MarkdownHighlight { impl MarkdownHighlight { /// Converts this [`MarkdownHighlight`] to a [`HighlightStyle`]. - pub fn to_highlight_style(&self, theme: &theme::SyntaxTheme) -> Option { + pub fn to_highlight_style( + &self, + theme: &theme::SyntaxTheme, + link_color: Hsla, + ) -> Option { match self { MarkdownHighlight::Style(style) => { let mut highlight = HighlightStyle::default(); @@ -202,6 +206,15 @@ impl MarkdownHighlight { highlight.font_weight = Some(style.weight); } + if style.link { + highlight.underline = Some(UnderlineStyle { + thickness: px(1.), + color: Some(link_color), + ..Default::default() + }); + highlight.color = Some(link_color); + } + Some(highlight) } @@ -221,6 +234,8 @@ pub struct MarkdownHighlightStyle { pub strikethrough: bool, /// The weight of the text. pub weight: FontWeight, + /// Whether the text should be stylized as link. + pub link: bool, } /// A parsed region in a Markdown document. diff --git a/crates/markdown_preview/src/markdown_parser.rs b/crates/markdown_preview/src/markdown_parser.rs index d76ecb15a9..d995f07f3d 100644 --- a/crates/markdown_preview/src/markdown_parser.rs +++ b/crates/markdown_preview/src/markdown_parser.rs @@ -261,7 +261,7 @@ impl<'a> MarkdownParser<'a> { code: false, link: Some(link), }); - style.underline = true; + style.link = true; prev_len } else { // Manually scan for links @@ -329,7 +329,7 @@ impl<'a> MarkdownParser<'a> { highlights.push(( prev_len..text.len(), MarkdownHighlight::Style(MarkdownHighlightStyle { - underline: true, + link: true, ..Default::default() }), )); diff --git a/crates/markdown_preview/src/markdown_renderer.rs b/crates/markdown_preview/src/markdown_renderer.rs index de5018ff3d..4ac08df093 100644 --- a/crates/markdown_preview/src/markdown_renderer.rs +++ b/crates/markdown_preview/src/markdown_renderer.rs @@ -53,6 +53,7 @@ pub struct RenderContext { border_color: Hsla, element_background_color: Hsla, text_color: Hsla, + link_color: Hsla, window_rem_size: Pixels, text_muted_color: Hsla, code_block_background_color: Hsla, @@ -87,6 +88,7 @@ impl RenderContext { border_color: theme.colors().border, element_background_color: theme.colors().element_background, text_color: theme.colors().text, + link_color: theme.colors().text_accent, window_rem_size: window.rem_size(), text_muted_color: theme.colors().text_muted, code_block_background_color: theme.colors().surface_background, @@ -656,6 +658,7 @@ fn render_markdown_text(parsed_new: &MarkdownParagraph, cx: &mut RenderContext) let workspace_clone = cx.workspace.clone(); let code_span_bg_color = cx.code_span_background_color; let text_style = cx.text_style.clone(); + let link_color = cx.link_color; for parsed_region in parsed_new { match parsed_region { @@ -665,7 +668,7 @@ fn render_markdown_text(parsed_new: &MarkdownParagraph, cx: &mut RenderContext) let highlights = gpui::combine_highlights( parsed.highlights.iter().filter_map(|(range, highlight)| { highlight - .to_highlight_style(&syntax_theme) + .to_highlight_style(&syntax_theme, link_color) .map(|style| (range.clone(), style)) }), parsed.regions.iter().zip(&parsed.region_ranges).filter_map(