This removes around 900 unnecessary clones, ranging from cloning a few ints all the way to large data structures and images. A lot of these were fixed using `cargo clippy --fix --workspace --all-targets`, however it often breaks other lints and needs to be run again. This was then followed up with some manual fixing. I understand this is a large diff, but all the changes are pretty trivial. Rust is doing some heavy lifting here for us. Once I get it up to speed with main, I'd appreciate this getting merged rather sooner than later. Release Notes: - N/A
94 lines
2.9 KiB
Rust
94 lines
2.9 KiB
Rust
use anyhow::Result;
|
|
use gpui::{
|
|
App, ClipboardItem, Context, Entity, RetainAllImageCache, Task, Window, div, prelude::*,
|
|
};
|
|
use language::Buffer;
|
|
use markdown_preview::{
|
|
markdown_elements::ParsedMarkdown, markdown_parser::parse_markdown,
|
|
markdown_renderer::render_markdown_block,
|
|
};
|
|
use ui::v_flex;
|
|
|
|
use crate::outputs::OutputContent;
|
|
|
|
pub struct MarkdownView {
|
|
raw_text: String,
|
|
image_cache: Entity<RetainAllImageCache>,
|
|
contents: Option<ParsedMarkdown>,
|
|
parsing_markdown_task: Option<Task<Result<()>>>,
|
|
}
|
|
|
|
impl MarkdownView {
|
|
pub fn from(text: String, cx: &mut Context<Self>) -> Self {
|
|
let parsed = {
|
|
let text = text.clone();
|
|
cx.background_spawn(async move { parse_markdown(&text.clone(), None, None).await })
|
|
};
|
|
let task = cx.spawn(async move |markdown_view, cx| {
|
|
let content = parsed.await;
|
|
|
|
markdown_view.update(cx, |markdown, cx| {
|
|
markdown.parsing_markdown_task.take();
|
|
markdown.contents = Some(content);
|
|
cx.notify();
|
|
})
|
|
});
|
|
|
|
Self {
|
|
raw_text: text,
|
|
image_cache: RetainAllImageCache::new(cx),
|
|
contents: None,
|
|
parsing_markdown_task: Some(task),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl OutputContent for MarkdownView {
|
|
fn clipboard_content(&self, _window: &Window, _cx: &App) -> Option<ClipboardItem> {
|
|
Some(ClipboardItem::new_string(self.raw_text.clone()))
|
|
}
|
|
|
|
fn has_clipboard_content(&self, _window: &Window, _cx: &App) -> bool {
|
|
true
|
|
}
|
|
|
|
fn has_buffer_content(&self, _window: &Window, _cx: &App) -> bool {
|
|
true
|
|
}
|
|
|
|
fn buffer_content(&mut self, _: &mut Window, cx: &mut App) -> Option<Entity<Buffer>> {
|
|
let buffer = cx.new(|cx| {
|
|
// TODO: Bring in the language registry so we can set the language to markdown
|
|
let mut buffer = Buffer::local(self.raw_text.clone(), cx)
|
|
.with_language(language::PLAIN_TEXT.clone(), cx);
|
|
buffer.set_capability(language::Capability::ReadOnly, cx);
|
|
buffer
|
|
});
|
|
Some(buffer)
|
|
}
|
|
}
|
|
|
|
impl Render for MarkdownView {
|
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
|
let Some(parsed) = self.contents.as_ref() else {
|
|
return div().into_any_element();
|
|
};
|
|
|
|
let mut markdown_render_context =
|
|
markdown_preview::markdown_renderer::RenderContext::new(None, window, cx);
|
|
|
|
v_flex()
|
|
.image_cache(self.image_cache.clone())
|
|
.gap_3()
|
|
.py_4()
|
|
.children(parsed.children.iter().map(|child| {
|
|
div().relative().child(
|
|
div()
|
|
.relative()
|
|
.child(render_markdown_block(child, &mut markdown_render_context)),
|
|
)
|
|
}))
|
|
.into_any_element()
|
|
}
|
|
}
|