markdown: Move open_url
to the MarkdownElement
as on_url_click
(#28269)
Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
d3abc61728
commit
0414908c4a
6 changed files with 201 additions and 194 deletions
|
@ -76,7 +76,6 @@ impl RenderedMessage {
|
||||||
fn from_segments(
|
fn from_segments(
|
||||||
segments: &[MessageSegment],
|
segments: &[MessageSegment],
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
workspace: WeakEntity<Workspace>,
|
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
|
@ -84,12 +83,12 @@ impl RenderedMessage {
|
||||||
segments: Vec::with_capacity(segments.len()),
|
segments: Vec::with_capacity(segments.len()),
|
||||||
};
|
};
|
||||||
for segment in segments {
|
for segment in segments {
|
||||||
this.push_segment(segment, workspace.clone(), cx);
|
this.push_segment(segment, cx);
|
||||||
}
|
}
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_thinking(&mut self, text: &String, workspace: WeakEntity<Workspace>, cx: &mut App) {
|
fn append_thinking(&mut self, text: &String, cx: &mut App) {
|
||||||
if let Some(RenderedMessageSegment::Thinking {
|
if let Some(RenderedMessageSegment::Thinking {
|
||||||
content,
|
content,
|
||||||
scroll_handle,
|
scroll_handle,
|
||||||
|
@ -101,18 +100,13 @@ impl RenderedMessage {
|
||||||
scroll_handle.scroll_to_bottom();
|
scroll_handle.scroll_to_bottom();
|
||||||
} else {
|
} else {
|
||||||
self.segments.push(RenderedMessageSegment::Thinking {
|
self.segments.push(RenderedMessageSegment::Thinking {
|
||||||
content: render_markdown(
|
content: render_markdown(text.into(), self.language_registry.clone(), cx),
|
||||||
text.into(),
|
|
||||||
self.language_registry.clone(),
|
|
||||||
workspace,
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
scroll_handle: ScrollHandle::default(),
|
scroll_handle: ScrollHandle::default(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_text(&mut self, text: &String, workspace: WeakEntity<Workspace>, cx: &mut App) {
|
fn append_text(&mut self, text: &String, cx: &mut App) {
|
||||||
if let Some(RenderedMessageSegment::Text(markdown)) = self.segments.last_mut() {
|
if let Some(RenderedMessageSegment::Text(markdown)) = self.segments.last_mut() {
|
||||||
markdown.update(cx, |markdown, cx| markdown.append(text, cx));
|
markdown.update(cx, |markdown, cx| markdown.append(text, cx));
|
||||||
} else {
|
} else {
|
||||||
|
@ -120,32 +114,20 @@ impl RenderedMessage {
|
||||||
.push(RenderedMessageSegment::Text(render_markdown(
|
.push(RenderedMessageSegment::Text(render_markdown(
|
||||||
SharedString::from(text),
|
SharedString::from(text),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
workspace,
|
|
||||||
cx,
|
cx,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_segment(
|
fn push_segment(&mut self, segment: &MessageSegment, cx: &mut App) {
|
||||||
&mut self,
|
|
||||||
segment: &MessageSegment,
|
|
||||||
workspace: WeakEntity<Workspace>,
|
|
||||||
cx: &mut App,
|
|
||||||
) {
|
|
||||||
let rendered_segment = match segment {
|
let rendered_segment = match segment {
|
||||||
MessageSegment::Thinking(text) => RenderedMessageSegment::Thinking {
|
MessageSegment::Thinking(text) => RenderedMessageSegment::Thinking {
|
||||||
content: render_markdown(
|
content: render_markdown(text.into(), self.language_registry.clone(), cx),
|
||||||
text.into(),
|
|
||||||
self.language_registry.clone(),
|
|
||||||
workspace,
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
scroll_handle: ScrollHandle::default(),
|
scroll_handle: ScrollHandle::default(),
|
||||||
},
|
},
|
||||||
MessageSegment::Text(text) => RenderedMessageSegment::Text(render_markdown(
|
MessageSegment::Text(text) => RenderedMessageSegment::Text(render_markdown(
|
||||||
text.into(),
|
text.into(),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
workspace,
|
|
||||||
cx,
|
cx,
|
||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
|
@ -164,14 +146,9 @@ enum RenderedMessageSegment {
|
||||||
fn render_markdown(
|
fn render_markdown(
|
||||||
text: SharedString,
|
text: SharedString,
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
workspace: WeakEntity<Workspace>,
|
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Entity<Markdown> {
|
) -> Entity<Markdown> {
|
||||||
cx.new(|cx| {
|
cx.new(|cx| Markdown::new(text, Some(language_registry), None, cx))
|
||||||
Markdown::new(text, Some(language_registry), None, cx).open_url(move |text, window, cx| {
|
|
||||||
open_markdown_link(text, workspace.clone(), window, cx);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
|
fn default_markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
|
||||||
|
@ -261,14 +238,9 @@ fn default_markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
|
||||||
fn render_tool_use_markdown(
|
fn render_tool_use_markdown(
|
||||||
text: SharedString,
|
text: SharedString,
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
workspace: WeakEntity<Workspace>,
|
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Entity<Markdown> {
|
) -> Entity<Markdown> {
|
||||||
cx.new(|cx| {
|
cx.new(|cx| Markdown::new(text, Some(language_registry), None, cx))
|
||||||
Markdown::new(text, Some(language_registry), None, cx).open_url(move |text, window, cx| {
|
|
||||||
open_markdown_link(text, workspace.clone(), window, cx);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tool_use_markdown_style(window: &Window, cx: &mut App) -> MarkdownStyle {
|
fn tool_use_markdown_style(window: &Window, cx: &mut App) -> MarkdownStyle {
|
||||||
|
@ -502,12 +474,8 @@ impl ActiveThread {
|
||||||
self.messages.push(*id);
|
self.messages.push(*id);
|
||||||
self.list_state.splice(old_len..old_len, 1);
|
self.list_state.splice(old_len..old_len, 1);
|
||||||
|
|
||||||
let rendered_message = RenderedMessage::from_segments(
|
let rendered_message =
|
||||||
segments,
|
RenderedMessage::from_segments(segments, self.language_registry.clone(), cx);
|
||||||
self.language_registry.clone(),
|
|
||||||
self.workspace.clone(),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
self.rendered_messages_by_id.insert(*id, rendered_message);
|
self.rendered_messages_by_id.insert(*id, rendered_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,12 +490,8 @@ impl ActiveThread {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
self.list_state.splice(index..index + 1, 1);
|
self.list_state.splice(index..index + 1, 1);
|
||||||
let rendered_message = RenderedMessage::from_segments(
|
let rendered_message =
|
||||||
segments,
|
RenderedMessage::from_segments(segments, self.language_registry.clone(), cx);
|
||||||
self.language_registry.clone(),
|
|
||||||
self.workspace.clone(),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
self.rendered_messages_by_id.insert(*id, rendered_message);
|
self.rendered_messages_by_id.insert(*id, rendered_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,12 +513,7 @@ impl ActiveThread {
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let rendered = RenderedToolUse {
|
let rendered = RenderedToolUse {
|
||||||
label: render_tool_use_markdown(
|
label: render_tool_use_markdown(tool_label.into(), self.language_registry.clone(), cx),
|
||||||
tool_label.into(),
|
|
||||||
self.language_registry.clone(),
|
|
||||||
self.workspace.clone(),
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
input: render_tool_use_markdown(
|
input: render_tool_use_markdown(
|
||||||
format!(
|
format!(
|
||||||
"```json\n{}\n```",
|
"```json\n{}\n```",
|
||||||
|
@ -562,15 +521,9 @@ impl ActiveThread {
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
self.workspace.clone(),
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
output: render_tool_use_markdown(
|
|
||||||
tool_output,
|
|
||||||
self.language_registry.clone(),
|
|
||||||
self.workspace.clone(),
|
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
|
output: render_tool_use_markdown(tool_output, self.language_registry.clone(), cx),
|
||||||
};
|
};
|
||||||
self.rendered_tool_uses
|
self.rendered_tool_uses
|
||||||
.insert(tool_use_id.clone(), rendered);
|
.insert(tool_use_id.clone(), rendered);
|
||||||
|
@ -613,12 +566,12 @@ impl ActiveThread {
|
||||||
}
|
}
|
||||||
ThreadEvent::StreamedAssistantText(message_id, text) => {
|
ThreadEvent::StreamedAssistantText(message_id, text) => {
|
||||||
if let Some(rendered_message) = self.rendered_messages_by_id.get_mut(&message_id) {
|
if let Some(rendered_message) = self.rendered_messages_by_id.get_mut(&message_id) {
|
||||||
rendered_message.append_text(text, self.workspace.clone(), cx);
|
rendered_message.append_text(text, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ThreadEvent::StreamedAssistantThinking(message_id, text) => {
|
ThreadEvent::StreamedAssistantThinking(message_id, text) => {
|
||||||
if let Some(rendered_message) = self.rendered_messages_by_id.get_mut(&message_id) {
|
if let Some(rendered_message) = self.rendered_messages_by_id.get_mut(&message_id) {
|
||||||
rendered_message.append_thinking(text, self.workspace.clone(), cx);
|
rendered_message.append_thinking(text, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ThreadEvent::MessageAdded(message_id) => {
|
ThreadEvent::MessageAdded(message_id) => {
|
||||||
|
@ -1550,10 +1503,18 @@ impl ActiveThread {
|
||||||
)
|
)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
RenderedMessageSegment::Text(markdown) => div()
|
RenderedMessageSegment::Text(markdown) => div()
|
||||||
.child(MarkdownElement::new(
|
.child(
|
||||||
|
MarkdownElement::new(
|
||||||
markdown.clone(),
|
markdown.clone(),
|
||||||
default_markdown_style(window, cx),
|
default_markdown_style(window, cx),
|
||||||
))
|
)
|
||||||
|
.on_url_click({
|
||||||
|
let workspace = self.workspace.clone();
|
||||||
|
move |text, window, cx| {
|
||||||
|
open_markdown_link(text, workspace.clone(), window, cx);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -1712,10 +1673,23 @@ impl ActiveThread {
|
||||||
.h_20()
|
.h_20()
|
||||||
.track_scroll(scroll_handle)
|
.track_scroll(scroll_handle)
|
||||||
.text_ui_sm(cx)
|
.text_ui_sm(cx)
|
||||||
.child(MarkdownElement::new(
|
.child(
|
||||||
|
MarkdownElement::new(
|
||||||
markdown.clone(),
|
markdown.clone(),
|
||||||
default_markdown_style(window, cx),
|
default_markdown_style(window, cx),
|
||||||
))
|
)
|
||||||
|
.on_url_click({
|
||||||
|
let workspace = self.workspace.clone();
|
||||||
|
move |text, window, cx| {
|
||||||
|
open_markdown_link(
|
||||||
|
text,
|
||||||
|
workspace.clone(),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
.overflow_hidden(),
|
.overflow_hidden(),
|
||||||
)
|
)
|
||||||
.child(gradient_overlay),
|
.child(gradient_overlay),
|
||||||
|
@ -1730,10 +1704,18 @@ impl ActiveThread {
|
||||||
.rounded_b_lg()
|
.rounded_b_lg()
|
||||||
.bg(editor_bg)
|
.bg(editor_bg)
|
||||||
.text_ui_sm(cx)
|
.text_ui_sm(cx)
|
||||||
.child(MarkdownElement::new(
|
.child(
|
||||||
|
MarkdownElement::new(
|
||||||
markdown.clone(),
|
markdown.clone(),
|
||||||
default_markdown_style(window, cx),
|
default_markdown_style(window, cx),
|
||||||
)),
|
)
|
||||||
|
.on_url_click({
|
||||||
|
let workspace = self.workspace.clone();
|
||||||
|
move |text, window, cx| {
|
||||||
|
open_markdown_link(text, workspace.clone(), window, cx);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -1789,8 +1771,7 @@ impl ActiveThread {
|
||||||
let rendered_tool_use = self.rendered_tool_uses.get(&tool_use.id).cloned();
|
let rendered_tool_use = self.rendered_tool_uses.get(&tool_use.id).cloned();
|
||||||
let results_content_container = || v_flex().p_2().gap_0p5();
|
let results_content_container = || v_flex().p_2().gap_0p5();
|
||||||
|
|
||||||
let results_content =
|
let results_content = v_flex()
|
||||||
v_flex()
|
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(
|
.child(
|
||||||
results_content_container()
|
results_content_container()
|
||||||
|
@ -1800,14 +1781,23 @@ impl ActiveThread {
|
||||||
.color(Color::Muted)
|
.color(Color::Muted)
|
||||||
.buffer_font(cx),
|
.buffer_font(cx),
|
||||||
)
|
)
|
||||||
.child(div().w_full().text_ui_sm(cx).children(
|
.child(
|
||||||
rendered_tool_use.as_ref().map(|rendered| {
|
div()
|
||||||
|
.w_full()
|
||||||
|
.text_ui_sm(cx)
|
||||||
|
.children(rendered_tool_use.as_ref().map(|rendered| {
|
||||||
MarkdownElement::new(
|
MarkdownElement::new(
|
||||||
rendered.input.clone(),
|
rendered.input.clone(),
|
||||||
tool_use_markdown_style(window, cx),
|
tool_use_markdown_style(window, cx),
|
||||||
)
|
)
|
||||||
}),
|
.on_url_click({
|
||||||
)),
|
let workspace = self.workspace.clone();
|
||||||
|
move |text, window, cx| {
|
||||||
|
open_markdown_link(text, workspace.clone(), window, cx);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.map(|container| match tool_use.status {
|
.map(|container| match tool_use.status {
|
||||||
ToolUseStatus::Finished(_) => container.child(
|
ToolUseStatus::Finished(_) => container.child(
|
||||||
|
@ -1826,6 +1816,12 @@ impl ActiveThread {
|
||||||
rendered.output.clone(),
|
rendered.output.clone(),
|
||||||
tool_use_markdown_style(window, cx),
|
tool_use_markdown_style(window, cx),
|
||||||
)
|
)
|
||||||
|
.on_url_click({
|
||||||
|
let workspace = self.workspace.clone();
|
||||||
|
move |text, window, cx| {
|
||||||
|
open_markdown_link(text, workspace.clone(), window, cx);
|
||||||
|
}
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
@ -1858,8 +1854,7 @@ impl ActiveThread {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ToolUseStatus::Error(_) => {
|
ToolUseStatus::Error(_) => container.child(
|
||||||
container.child(
|
|
||||||
results_content_container()
|
results_content_container()
|
||||||
.border_t_1()
|
.border_t_1()
|
||||||
.border_color(self.tool_card_border_color(cx))
|
.border_color(self.tool_card_border_color(cx))
|
||||||
|
@ -1869,16 +1864,23 @@ impl ActiveThread {
|
||||||
.color(Color::Muted)
|
.color(Color::Muted)
|
||||||
.buffer_font(cx),
|
.buffer_font(cx),
|
||||||
)
|
)
|
||||||
.child(div().text_ui_sm(cx).children(
|
.child(
|
||||||
rendered_tool_use.as_ref().map(|rendered| {
|
div()
|
||||||
|
.text_ui_sm(cx)
|
||||||
|
.children(rendered_tool_use.as_ref().map(|rendered| {
|
||||||
MarkdownElement::new(
|
MarkdownElement::new(
|
||||||
rendered.output.clone(),
|
rendered.output.clone(),
|
||||||
tool_use_markdown_style(window, cx),
|
tool_use_markdown_style(window, cx),
|
||||||
)
|
)
|
||||||
}),
|
.on_url_click({
|
||||||
)),
|
let workspace = self.workspace.clone();
|
||||||
)
|
move |text, window, cx| {
|
||||||
|
open_markdown_link(text, workspace.clone(), window, cx);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
),
|
||||||
ToolUseStatus::Pending => container,
|
ToolUseStatus::Pending => container,
|
||||||
ToolUseStatus::NeedsConfirmation => container.child(
|
ToolUseStatus::NeedsConfirmation => container.child(
|
||||||
results_content_container()
|
results_content_container()
|
||||||
|
@ -1939,7 +1941,9 @@ impl ActiveThread {
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex().pr_8().text_ui_sm(cx).children(
|
h_flex().pr_8().text_ui_sm(cx).children(
|
||||||
rendered_tool_use.map(|rendered| MarkdownElement::new(rendered.label, tool_use_markdown_style(window, cx)))
|
rendered_tool_use.map(|rendered| MarkdownElement::new(rendered.label, tool_use_markdown_style(window, cx)).on_url_click({let workspace = self.workspace.clone(); move |text, window, cx| {
|
||||||
|
open_markdown_link(text, workspace.clone(), window, cx);
|
||||||
|
}}))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -2027,7 +2031,9 @@ impl ActiveThread {
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex().pr_8().text_ui_sm(cx).children(
|
h_flex().pr_8().text_ui_sm(cx).children(
|
||||||
rendered_tool_use.map(|rendered| MarkdownElement::new(rendered.label, tool_use_markdown_style(window, cx)))
|
rendered_tool_use.map(|rendered| MarkdownElement::new(rendered.label, tool_use_markdown_style(window, cx)).on_url_click({let workspace = self.workspace.clone(); move |text, window, cx| {
|
||||||
|
open_markdown_link(text, workspace.clone(), window, cx);
|
||||||
|
}}))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -792,15 +792,11 @@ impl editor::Addon for AgentDiffAddon {
|
||||||
|
|
||||||
pub struct AgentDiffToolbar {
|
pub struct AgentDiffToolbar {
|
||||||
agent_diff: Option<WeakEntity<AgentDiff>>,
|
agent_diff: Option<WeakEntity<AgentDiff>>,
|
||||||
_workspace: WeakEntity<Workspace>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AgentDiffToolbar {
|
impl AgentDiffToolbar {
|
||||||
pub fn new(workspace: &Workspace, _: &mut Context<Self>) -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self { agent_diff: None }
|
||||||
agent_diff: None,
|
|
||||||
_workspace: workspace.weak_handle(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn agent_diff(&self, _: &App) -> Option<Entity<AgentDiff>> {
|
fn agent_diff(&self, _: &App) -> Option<Entity<AgentDiff>> {
|
||||||
|
|
|
@ -624,16 +624,15 @@ impl CompletionsMenu {
|
||||||
.map(|l| l.name().to_proto());
|
.map(|l| l.name().to_proto());
|
||||||
Markdown::new(SharedString::default(), languages, language, cx)
|
Markdown::new(SharedString::default(), languages, language, cx)
|
||||||
.copy_code_block_buttons(false)
|
.copy_code_block_buttons(false)
|
||||||
.open_url(open_markdown_url)
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
markdown.update(cx, |markdown, cx| {
|
markdown.update(cx, |markdown, cx| {
|
||||||
markdown.reset(parsed.clone(), cx);
|
markdown.reset(parsed.clone(), cx);
|
||||||
});
|
});
|
||||||
div().child(MarkdownElement::new(
|
div().child(
|
||||||
markdown.clone(),
|
MarkdownElement::new(markdown.clone(), hover_markdown_style(window, cx))
|
||||||
hover_markdown_style(window, cx),
|
.on_url_click(open_markdown_url),
|
||||||
))
|
)
|
||||||
}
|
}
|
||||||
CompletionDocumentation::MultiLineMarkdown(_) => return None,
|
CompletionDocumentation::MultiLineMarkdown(_) => return None,
|
||||||
CompletionDocumentation::SingleLine(_) => return None,
|
CompletionDocumentation::SingleLine(_) => return None,
|
||||||
|
|
|
@ -336,7 +336,7 @@ fn show_hover(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Markdown::new_text(SharedString::new(text), cx).open_url(open_markdown_url)
|
Markdown::new_text(SharedString::new(text), cx)
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
@ -547,7 +547,6 @@ async fn parse_blocks(
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
.copy_code_block_buttons(false)
|
.copy_code_block_buttons(false)
|
||||||
.open_url(open_markdown_url)
|
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
@ -783,10 +782,13 @@ impl InfoPopover {
|
||||||
.max_h(max_size.height)
|
.max_h(max_size.height)
|
||||||
.p_2()
|
.p_2()
|
||||||
.track_scroll(&self.scroll_handle)
|
.track_scroll(&self.scroll_handle)
|
||||||
.child(MarkdownElement::new(
|
.child(
|
||||||
|
MarkdownElement::new(
|
||||||
markdown.clone(),
|
markdown.clone(),
|
||||||
hover_markdown_style(window, cx),
|
hover_markdown_style(window, cx),
|
||||||
)),
|
)
|
||||||
|
.on_url_click(open_markdown_url),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.child(self.render_vertical_scrollbar(cx));
|
.child(self.render_vertical_scrollbar(cx));
|
||||||
}
|
}
|
||||||
|
@ -881,8 +883,10 @@ impl DiagnosticPopover {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
markdown_div =
|
markdown_div = markdown_div.child(
|
||||||
markdown_div.child(MarkdownElement::new(markdown.clone(), markdown_style));
|
MarkdownElement::new(markdown.clone(), markdown_style)
|
||||||
|
.on_url_click(open_markdown_url),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(background_color) = &self.background_color {
|
if let Some(background_color) = &self.background_color {
|
||||||
|
|
|
@ -80,7 +80,6 @@ pub struct Markdown {
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
language_registry: Option<Arc<LanguageRegistry>>,
|
language_registry: Option<Arc<LanguageRegistry>>,
|
||||||
fallback_code_block_language: Option<String>,
|
fallback_code_block_language: Option<String>,
|
||||||
open_url: Option<Box<dyn Fn(SharedString, &mut Window, &mut App)>>,
|
|
||||||
options: Options,
|
options: Options,
|
||||||
copied_code_blocks: HashSet<ElementId>,
|
copied_code_blocks: HashSet<ElementId>,
|
||||||
}
|
}
|
||||||
|
@ -116,23 +115,12 @@ impl Markdown {
|
||||||
parse_links_only: false,
|
parse_links_only: false,
|
||||||
copy_code_block_buttons: true,
|
copy_code_block_buttons: true,
|
||||||
},
|
},
|
||||||
open_url: None,
|
|
||||||
copied_code_blocks: HashSet::new(),
|
copied_code_blocks: HashSet::new(),
|
||||||
};
|
};
|
||||||
this.parse(cx);
|
this.parse(cx);
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_url(
|
|
||||||
self,
|
|
||||||
open_url: impl Fn(SharedString, &mut Window, &mut App) + 'static,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
open_url: Some(Box::new(open_url)),
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_text(source: SharedString, cx: &mut Context<Self>) -> Self {
|
pub fn new_text(source: SharedString, cx: &mut Context<Self>) -> Self {
|
||||||
let focus_handle = cx.focus_handle();
|
let focus_handle = cx.focus_handle();
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
|
@ -150,7 +138,6 @@ impl Markdown {
|
||||||
parse_links_only: true,
|
parse_links_only: true,
|
||||||
copy_code_block_buttons: true,
|
copy_code_block_buttons: true,
|
||||||
},
|
},
|
||||||
open_url: None,
|
|
||||||
copied_code_blocks: HashSet::new(),
|
copied_code_blocks: HashSet::new(),
|
||||||
};
|
};
|
||||||
this.parse(cx);
|
this.parse(cx);
|
||||||
|
@ -328,11 +315,24 @@ impl ParsedMarkdown {
|
||||||
pub struct MarkdownElement {
|
pub struct MarkdownElement {
|
||||||
markdown: Entity<Markdown>,
|
markdown: Entity<Markdown>,
|
||||||
style: MarkdownStyle,
|
style: MarkdownStyle,
|
||||||
|
on_url_click: Option<Box<dyn Fn(SharedString, &mut Window, &mut App)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MarkdownElement {
|
impl MarkdownElement {
|
||||||
pub fn new(markdown: Entity<Markdown>, style: MarkdownStyle) -> Self {
|
pub fn new(markdown: Entity<Markdown>, style: MarkdownStyle) -> Self {
|
||||||
Self { markdown, style }
|
Self {
|
||||||
|
markdown,
|
||||||
|
style,
|
||||||
|
on_url_click: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_url_click(
|
||||||
|
mut self,
|
||||||
|
handler: impl Fn(SharedString, &mut Window, &mut App) + 'static,
|
||||||
|
) -> Self {
|
||||||
|
self.on_url_click = Some(Box::new(handler));
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_selection(
|
fn paint_selection(
|
||||||
|
@ -404,7 +404,7 @@ impl MarkdownElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_mouse_listeners(
|
fn paint_mouse_listeners(
|
||||||
&self,
|
&mut self,
|
||||||
hitbox: &Hitbox,
|
hitbox: &Hitbox,
|
||||||
rendered_text: &RenderedText,
|
rendered_text: &RenderedText,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
|
@ -422,6 +422,8 @@ impl MarkdownElement {
|
||||||
window.set_cursor_style(CursorStyle::IBeam, Some(hitbox));
|
window.set_cursor_style(CursorStyle::IBeam, Some(hitbox));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let on_open_url = self.on_url_click.take();
|
||||||
|
|
||||||
self.on_mouse_event(window, cx, {
|
self.on_mouse_event(window, cx, {
|
||||||
let rendered_text = rendered_text.clone();
|
let rendered_text = rendered_text.clone();
|
||||||
let hitbox = hitbox.clone();
|
let hitbox = hitbox.clone();
|
||||||
|
@ -493,7 +495,7 @@ impl MarkdownElement {
|
||||||
if phase.bubble() {
|
if phase.bubble() {
|
||||||
if let Some(pressed_link) = markdown.pressed_link.take() {
|
if let Some(pressed_link) = markdown.pressed_link.take() {
|
||||||
if Some(&pressed_link) == rendered_text.link_for_position(event.position) {
|
if Some(&pressed_link) == rendered_text.link_for_position(event.position) {
|
||||||
if let Some(open_url) = markdown.open_url.as_mut() {
|
if let Some(open_url) = on_open_url.as_ref() {
|
||||||
open_url(pressed_link.destination_url, window, cx);
|
open_url(pressed_link.destination_url, window, cx);
|
||||||
} else {
|
} else {
|
||||||
cx.open_url(&pressed_link.destination_url);
|
cx.open_url(&pressed_link.destination_url);
|
||||||
|
|
|
@ -938,7 +938,7 @@ fn initialize_pane(
|
||||||
toolbar.add_item(migration_banner, window, cx);
|
toolbar.add_item(migration_banner, window, cx);
|
||||||
let project_diff_toolbar = cx.new(|cx| ProjectDiffToolbar::new(workspace, cx));
|
let project_diff_toolbar = cx.new(|cx| ProjectDiffToolbar::new(workspace, cx));
|
||||||
toolbar.add_item(project_diff_toolbar, window, cx);
|
toolbar.add_item(project_diff_toolbar, window, cx);
|
||||||
let agent_diff_toolbar = cx.new(|cx| AgentDiffToolbar::new(workspace, cx));
|
let agent_diff_toolbar = cx.new(|_cx| AgentDiffToolbar::new());
|
||||||
toolbar.add_item(agent_diff_toolbar, window, cx);
|
toolbar.add_item(agent_diff_toolbar, window, cx);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue