diff --git a/crates/markdown/src/markdown.rs b/crates/markdown/src/markdown.rs index d111171cd9f482..99b3fd20118eb2 100644 --- a/crates/markdown/src/markdown.rs +++ b/crates/markdown/src/markdown.rs @@ -611,11 +611,13 @@ impl Markdown { } } - fn code_block_scroll_handle(&mut self, id: usize) -> ScrollHandle { - self.code_block_scroll_handles - .entry(id) - .or_insert_with(ScrollHandle::new) - .clone() + fn code_block_scroll_handle(&mut self, id: usize) -> Option { + (!self.is_code_block_wrapped(id)).then(|| { + self.code_block_scroll_handles + .entry(id) + .or_insert_with(ScrollHandle::new) + .clone() + }) } fn retain_code_block_scroll_handles(&mut self, ids: &HashSet) { @@ -2139,13 +2141,15 @@ impl Element for MarkdownElement { let is_indented = matches!(kind, CodeBlockKind::Indented); let scroll_handle = if self.style.code_block_overflow_x_scroll { - code_block_ids.insert(range.start); - Some(self.markdown.update(cx, |markdown, _| { + self.markdown.update(cx, |markdown, _| { markdown.code_block_scroll_handle(range.start) - })) + }) } else { None }; + if scroll_handle.is_some() { + code_block_ids.insert(range.start); + } match (&self.code_block_renderer, is_indented) { (CodeBlockRenderer::Default { .. }, _) | (_, true) => { @@ -2185,18 +2189,11 @@ impl Element for MarkdownElement { parent_container.style().refine(&self.style.code_block); builder.push_div(parent_container, range, markdown_end); - let is_wrapped = - self.markdown.read(cx).is_code_block_wrapped(range.start); - let code_block = div() .id(("code-block", range.start)) .rounded_lg() .map(|mut code_block| { - if is_wrapped { - code_block.w_full() - } else if let Some(scroll_handle) = - scroll_handle.as_ref() - { + if let Some(scroll_handle) = scroll_handle.as_ref() { code_block.style().restrict_scroll_to_axis = Some(true); code_block @@ -2477,7 +2474,7 @@ impl Element for MarkdownElement { == WrapButtonVisibility::AlwaysVisible; let use_hover = any_hover && !any_always; - let mut button_row = h_flex() + let button_row = h_flex() .gap_0p5() .absolute() .bg(cx.theme().colors().editor_background) @@ -2487,26 +2484,33 @@ impl Element for MarkdownElement { this.top_1().right_1().visible_on_hover("code_block") }, |this| this.top_1p5().right_1p5(), + ) + .when( + wrap_button_visibility != WrapButtonVisibility::Hidden, + |this| { + let is_wrapped = self + .markdown + .read(cx) + .is_code_block_wrapped(range.start); + + this.child(render_wrap_code_block_button( + range.start, + is_wrapped, + self.markdown.clone(), + )) + }, + ) + .when( + copy_button_visibility != CopyButtonVisibility::Hidden, + |this| { + this.child(render_copy_code_block_button( + range.end, + code, + self.markdown.clone(), + )) + }, ); - if wrap_button_visibility != WrapButtonVisibility::Hidden { - let is_wrapped = - self.markdown.read(cx).is_code_block_wrapped(range.start); - button_row = button_row.child(render_wrap_code_block_button( - range.start, - is_wrapped, - self.markdown.clone(), - )); - } - - if copy_button_visibility != CopyButtonVisibility::Hidden { - button_row = button_row.child(render_copy_code_block_button( - range.end, - code, - self.markdown.clone(), - )); - } - el.child(button_row) }); } @@ -3867,6 +3871,22 @@ mod tests { render_markdown_with_language_registry(markdown, None, cx) } + #[gpui::test] + fn test_wrapped_code_block_has_no_scroll_handle(cx: &mut TestAppContext) { + let markdown = + cx.new(|cx| Markdown::new("```rust\nlet value = 1;\n```".into(), None, None, cx)); + + markdown.update(cx, |markdown, _| { + assert!(markdown.code_block_scroll_handle(0).is_some()); + + markdown.toggle_code_block_wrap(0); + assert!(markdown.code_block_scroll_handle(0).is_none()); + + markdown.toggle_code_block_wrap(0); + assert!(markdown.code_block_scroll_handle(0).is_some()); + }); + } + #[gpui::test] fn test_frontmatter_renders_without_delimiters(cx: &mut TestAppContext) { let rendered = render_markdown_with_options(