markdown: Don't retain MarkdownStyle
in favor of using MarkdownElement
directly (#28255)
This PR removes the retained `MarkdownStyle` on the `Markdown` entity in favor of using the `MarkdownElement` directly and passing the `MarkdownStyle` to it. This makes it so switching themes will be reflected live in the code block styles. Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <me@as-cii.com> Co-authored-by: Agus Zubiaga <hi@aguz.me>
This commit is contained in:
parent
aa026156f2
commit
b6ee367ee0
@ -22,7 +22,7 @@ use gpui::{
|
||||
};
|
||||
use language::{Buffer, LanguageRegistry};
|
||||
use language_model::{ConfiguredModel, LanguageModelRegistry, LanguageModelToolUseId, Role};
|
||||
use markdown::{Markdown, MarkdownStyle};
|
||||
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||
use project::ProjectItem as _;
|
||||
use settings::{Settings as _, update_settings_file};
|
||||
use std::rc::Rc;
|
||||
@ -77,7 +77,6 @@ impl RenderedMessage {
|
||||
segments: &[MessageSegment],
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &Window,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
let mut this = Self {
|
||||
@ -85,18 +84,12 @@ impl RenderedMessage {
|
||||
segments: Vec::with_capacity(segments.len()),
|
||||
};
|
||||
for segment in segments {
|
||||
this.push_segment(segment, workspace.clone(), window, cx);
|
||||
this.push_segment(segment, workspace.clone(), cx);
|
||||
}
|
||||
this
|
||||
}
|
||||
|
||||
fn append_thinking(
|
||||
&mut self,
|
||||
text: &String,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &Window,
|
||||
cx: &mut App,
|
||||
) {
|
||||
fn append_thinking(&mut self, text: &String, workspace: WeakEntity<Workspace>, cx: &mut App) {
|
||||
if let Some(RenderedMessageSegment::Thinking {
|
||||
content,
|
||||
scroll_handle,
|
||||
@ -112,7 +105,6 @@ impl RenderedMessage {
|
||||
text.into(),
|
||||
self.language_registry.clone(),
|
||||
workspace,
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
scroll_handle: ScrollHandle::default(),
|
||||
@ -120,13 +112,7 @@ impl RenderedMessage {
|
||||
}
|
||||
}
|
||||
|
||||
fn append_text(
|
||||
&mut self,
|
||||
text: &String,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &Window,
|
||||
cx: &mut App,
|
||||
) {
|
||||
fn append_text(&mut self, text: &String, workspace: WeakEntity<Workspace>, cx: &mut App) {
|
||||
if let Some(RenderedMessageSegment::Text(markdown)) = self.segments.last_mut() {
|
||||
markdown.update(cx, |markdown, cx| markdown.append(text, cx));
|
||||
} else {
|
||||
@ -135,7 +121,6 @@ impl RenderedMessage {
|
||||
SharedString::from(text),
|
||||
self.language_registry.clone(),
|
||||
workspace,
|
||||
window,
|
||||
cx,
|
||||
)));
|
||||
}
|
||||
@ -145,7 +130,6 @@ impl RenderedMessage {
|
||||
&mut self,
|
||||
segment: &MessageSegment,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &Window,
|
||||
cx: &mut App,
|
||||
) {
|
||||
let rendered_segment = match segment {
|
||||
@ -154,7 +138,6 @@ impl RenderedMessage {
|
||||
text.into(),
|
||||
self.language_registry.clone(),
|
||||
workspace,
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
scroll_handle: ScrollHandle::default(),
|
||||
@ -163,7 +146,6 @@ impl RenderedMessage {
|
||||
text.into(),
|
||||
self.language_registry.clone(),
|
||||
workspace,
|
||||
window,
|
||||
cx,
|
||||
)),
|
||||
};
|
||||
@ -183,9 +165,16 @@ fn render_markdown(
|
||||
text: SharedString,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &Window,
|
||||
cx: &mut App,
|
||||
) -> Entity<Markdown> {
|
||||
cx.new(|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 {
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let colors = cx.theme().colors();
|
||||
let ui_font_size = TextSize::Default.rems(cx);
|
||||
@ -201,7 +190,7 @@ fn render_markdown(
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let markdown_style = MarkdownStyle {
|
||||
MarkdownStyle {
|
||||
base_text_style: text_style,
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
selection_background_color: cx.theme().players().local().selection,
|
||||
@ -266,24 +255,23 @@ fn render_markdown(
|
||||
}
|
||||
})),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
cx.new(|cx| {
|
||||
Markdown::new(text, markdown_style, Some(language_registry), None, cx).open_url(
|
||||
move |text, window, cx| {
|
||||
open_markdown_link(text, workspace.clone(), window, cx);
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn render_tool_use_markdown(
|
||||
text: SharedString,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &Window,
|
||||
cx: &mut App,
|
||||
) -> Entity<Markdown> {
|
||||
cx.new(|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 {
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let colors = cx.theme().colors();
|
||||
let ui_font_size = TextSize::Default.rems(cx);
|
||||
@ -299,7 +287,7 @@ fn render_tool_use_markdown(
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let markdown_style = MarkdownStyle {
|
||||
MarkdownStyle {
|
||||
base_text_style: text_style,
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
selection_background_color: cx.theme().players().local().selection,
|
||||
@ -334,15 +322,7 @@ fn render_tool_use_markdown(
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
cx.new(|cx| {
|
||||
Markdown::new(text, markdown_style, Some(language_registry), None, cx).open_url(
|
||||
move |text, window, cx| {
|
||||
open_markdown_link(text, workspace.clone(), window, cx);
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn open_markdown_link(
|
||||
@ -473,7 +453,6 @@ impl ActiveThread {
|
||||
tool_use.ui_text.clone(),
|
||||
&tool_use.input,
|
||||
tool_use.status.text(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
@ -516,7 +495,7 @@ impl ActiveThread {
|
||||
&mut self,
|
||||
id: &MessageId,
|
||||
segments: &[MessageSegment],
|
||||
window: &mut Window,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let old_len = self.messages.len();
|
||||
@ -527,7 +506,6 @@ impl ActiveThread {
|
||||
segments,
|
||||
self.language_registry.clone(),
|
||||
self.workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
self.rendered_messages_by_id.insert(*id, rendered_message);
|
||||
@ -537,7 +515,7 @@ impl ActiveThread {
|
||||
&mut self,
|
||||
id: &MessageId,
|
||||
segments: &[MessageSegment],
|
||||
window: &mut Window,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(index) = self.messages.iter().position(|message_id| message_id == id) else {
|
||||
@ -548,7 +526,6 @@ impl ActiveThread {
|
||||
segments,
|
||||
self.language_registry.clone(),
|
||||
self.workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
self.rendered_messages_by_id.insert(*id, rendered_message);
|
||||
@ -569,7 +546,6 @@ impl ActiveThread {
|
||||
tool_label: impl Into<SharedString>,
|
||||
tool_input: &serde_json::Value,
|
||||
tool_output: SharedString,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let rendered = RenderedToolUse {
|
||||
@ -577,7 +553,6 @@ impl ActiveThread {
|
||||
tool_label.into(),
|
||||
self.language_registry.clone(),
|
||||
self.workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
input: render_tool_use_markdown(
|
||||
@ -588,14 +563,12 @@ impl ActiveThread {
|
||||
.into(),
|
||||
self.language_registry.clone(),
|
||||
self.workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
output: render_tool_use_markdown(
|
||||
tool_output,
|
||||
self.language_registry.clone(),
|
||||
self.workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
};
|
||||
@ -640,12 +613,12 @@ impl ActiveThread {
|
||||
}
|
||||
ThreadEvent::StreamedAssistantText(message_id, text) => {
|
||||
if let Some(rendered_message) = self.rendered_messages_by_id.get_mut(&message_id) {
|
||||
rendered_message.append_text(text, self.workspace.clone(), window, cx);
|
||||
rendered_message.append_text(text, self.workspace.clone(), cx);
|
||||
}
|
||||
}
|
||||
ThreadEvent::StreamedAssistantThinking(message_id, text) => {
|
||||
if let Some(rendered_message) = self.rendered_messages_by_id.get_mut(&message_id) {
|
||||
rendered_message.append_thinking(text, self.workspace.clone(), window, cx);
|
||||
rendered_message.append_thinking(text, self.workspace.clone(), cx);
|
||||
}
|
||||
}
|
||||
ThreadEvent::MessageAdded(message_id) => {
|
||||
@ -690,7 +663,6 @@ impl ActiveThread {
|
||||
tool_use.ui_text.clone(),
|
||||
&tool_use.input,
|
||||
"".into(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
@ -711,7 +683,6 @@ impl ActiveThread {
|
||||
.tool_result(&tool_use.id)
|
||||
.map(|result| result.content.clone().into())
|
||||
.unwrap_or("".into()),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
@ -1204,6 +1175,7 @@ impl ActiveThread {
|
||||
message_id,
|
||||
rendered_message,
|
||||
has_tool_uses,
|
||||
window,
|
||||
cx,
|
||||
))
|
||||
.into_any()
|
||||
@ -1370,7 +1342,7 @@ impl ActiveThread {
|
||||
div().children(
|
||||
tool_uses
|
||||
.into_iter()
|
||||
.map(|tool_use| self.render_tool_use(tool_use, cx)),
|
||||
.map(|tool_use| self.render_tool_use(tool_use, window, cx)),
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -1540,6 +1512,7 @@ impl ActiveThread {
|
||||
message_id: MessageId,
|
||||
rendered_message: &RenderedMessage,
|
||||
has_tool_uses: bool,
|
||||
window: &Window,
|
||||
cx: &Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let is_last_message = self.messages.last() == Some(&message_id);
|
||||
@ -1572,12 +1545,16 @@ impl ActiveThread {
|
||||
content.clone(),
|
||||
&scroll_handle,
|
||||
Some(index) == pending_thinking_segment_index,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.into_any_element(),
|
||||
RenderedMessageSegment::Text(markdown) => {
|
||||
div().child(markdown.clone()).into_any_element()
|
||||
}
|
||||
RenderedMessageSegment::Text(markdown) => div()
|
||||
.child(MarkdownElement::new(
|
||||
markdown.clone(),
|
||||
default_markdown_style(window, cx),
|
||||
))
|
||||
.into_any_element(),
|
||||
},
|
||||
),
|
||||
)
|
||||
@ -1601,6 +1578,7 @@ impl ActiveThread {
|
||||
markdown: Entity<Markdown>,
|
||||
scroll_handle: &ScrollHandle,
|
||||
pending: bool,
|
||||
window: &Window,
|
||||
cx: &Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let is_open = self
|
||||
@ -1734,7 +1712,10 @@ impl ActiveThread {
|
||||
.h_20()
|
||||
.track_scroll(scroll_handle)
|
||||
.text_ui_sm(cx)
|
||||
.child(markdown.clone())
|
||||
.child(MarkdownElement::new(
|
||||
markdown.clone(),
|
||||
default_markdown_style(window, cx),
|
||||
))
|
||||
.overflow_hidden(),
|
||||
)
|
||||
.child(gradient_overlay),
|
||||
@ -1749,7 +1730,10 @@ impl ActiveThread {
|
||||
.rounded_b_lg()
|
||||
.bg(editor_bg)
|
||||
.text_ui_sm(cx)
|
||||
.child(markdown.clone()),
|
||||
.child(MarkdownElement::new(
|
||||
markdown.clone(),
|
||||
default_markdown_style(window, cx),
|
||||
)),
|
||||
)
|
||||
}),
|
||||
)
|
||||
@ -1758,6 +1742,7 @@ impl ActiveThread {
|
||||
fn render_tool_use(
|
||||
&self,
|
||||
tool_use: ToolUse,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement + use<> {
|
||||
let is_open = self
|
||||
@ -1804,103 +1789,109 @@ impl ActiveThread {
|
||||
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 = v_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
results_content_container()
|
||||
.child(
|
||||
Label::new("Input")
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
)
|
||||
.child(
|
||||
div().w_full().text_ui_sm(cx).children(
|
||||
rendered_tool_use
|
||||
.as_ref()
|
||||
.map(|rendered| rendered.input.clone()),
|
||||
),
|
||||
),
|
||||
)
|
||||
.map(|container| match tool_use.status {
|
||||
ToolUseStatus::Finished(_) => container.child(
|
||||
let results_content =
|
||||
v_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
results_content_container()
|
||||
.border_t_1()
|
||||
.border_color(self.tool_card_border_color(cx))
|
||||
.child(
|
||||
Label::new("Result")
|
||||
Label::new("Input")
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
)
|
||||
.child(
|
||||
div().w_full().text_ui_sm(cx).children(
|
||||
rendered_tool_use
|
||||
.as_ref()
|
||||
.map(|rendered| rendered.output.clone()),
|
||||
),
|
||||
),
|
||||
),
|
||||
ToolUseStatus::Running => container.child(
|
||||
results_content_container().child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.pb_1()
|
||||
.child(div().w_full().text_ui_sm(cx).children(
|
||||
rendered_tool_use.as_ref().map(|rendered| {
|
||||
MarkdownElement::new(
|
||||
rendered.input.clone(),
|
||||
tool_use_markdown_style(window, cx),
|
||||
)
|
||||
}),
|
||||
)),
|
||||
)
|
||||
.map(|container| match tool_use.status {
|
||||
ToolUseStatus::Finished(_) => container.child(
|
||||
results_content_container()
|
||||
.border_t_1()
|
||||
.border_color(self.tool_card_border_color(cx))
|
||||
.child(
|
||||
Icon::new(IconName::ArrowCircle)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Accent)
|
||||
.with_animation(
|
||||
"arrow-circle",
|
||||
Animation::new(Duration::from_secs(2)).repeat(),
|
||||
|icon, delta| {
|
||||
icon.transform(Transformation::rotate(percentage(
|
||||
delta,
|
||||
)))
|
||||
},
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Label::new("Running…")
|
||||
Label::new("Result")
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
)
|
||||
.child(div().w_full().text_ui_sm(cx).children(
|
||||
rendered_tool_use.as_ref().map(|rendered| {
|
||||
MarkdownElement::new(
|
||||
rendered.output.clone(),
|
||||
tool_use_markdown_style(window, cx),
|
||||
)
|
||||
}),
|
||||
)),
|
||||
),
|
||||
ToolUseStatus::Running => container.child(
|
||||
results_content_container().child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.pb_1()
|
||||
.border_t_1()
|
||||
.border_color(self.tool_card_border_color(cx))
|
||||
.child(
|
||||
Icon::new(IconName::ArrowCircle)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Accent)
|
||||
.with_animation(
|
||||
"arrow-circle",
|
||||
Animation::new(Duration::from_secs(2)).repeat(),
|
||||
|icon, delta| {
|
||||
icon.transform(Transformation::rotate(percentage(
|
||||
delta,
|
||||
)))
|
||||
},
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Label::new("Running…")
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
),
|
||||
),
|
||||
),
|
||||
ToolUseStatus::Error(_) => {
|
||||
container.child(
|
||||
results_content_container()
|
||||
.border_t_1()
|
||||
.border_color(self.tool_card_border_color(cx))
|
||||
.child(
|
||||
Label::new("Error")
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
)
|
||||
.child(div().text_ui_sm(cx).children(
|
||||
rendered_tool_use.as_ref().map(|rendered| {
|
||||
MarkdownElement::new(
|
||||
rendered.output.clone(),
|
||||
tool_use_markdown_style(window, cx),
|
||||
)
|
||||
}),
|
||||
)),
|
||||
)
|
||||
}
|
||||
ToolUseStatus::Pending => container,
|
||||
ToolUseStatus::NeedsConfirmation => container.child(
|
||||
results_content_container()
|
||||
.border_t_1()
|
||||
.border_color(self.tool_card_border_color(cx))
|
||||
.child(
|
||||
Label::new("Asking Permission")
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
),
|
||||
),
|
||||
),
|
||||
ToolUseStatus::Error(_) => container.child(
|
||||
results_content_container()
|
||||
.border_t_1()
|
||||
.border_color(self.tool_card_border_color(cx))
|
||||
.child(
|
||||
Label::new("Error")
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
)
|
||||
.child(
|
||||
div().text_ui_sm(cx).children(
|
||||
rendered_tool_use
|
||||
.as_ref()
|
||||
.map(|rendered| rendered.output.clone()),
|
||||
),
|
||||
),
|
||||
),
|
||||
ToolUseStatus::Pending => container,
|
||||
ToolUseStatus::NeedsConfirmation => container.child(
|
||||
results_content_container()
|
||||
.border_t_1()
|
||||
.border_color(self.tool_card_border_color(cx))
|
||||
.child(
|
||||
Label::new("Asking Permission")
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted)
|
||||
.buffer_font(cx),
|
||||
),
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
let gradient_overlay = |color: Hsla| {
|
||||
div()
|
||||
@ -1948,7 +1939,7 @@ impl ActiveThread {
|
||||
)
|
||||
.child(
|
||||
h_flex().pr_8().text_ui_sm(cx).children(
|
||||
rendered_tool_use.map(|rendered| rendered.label)
|
||||
rendered_tool_use.map(|rendered| MarkdownElement::new(rendered.label, tool_use_markdown_style(window, cx)))
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -2036,7 +2027,7 @@ impl ActiveThread {
|
||||
)
|
||||
.child(
|
||||
h_flex().pr_8().text_ui_sm(cx).children(
|
||||
rendered_tool_use.map(|rendered| rendered.label)
|
||||
rendered_tool_use.map(|rendered| MarkdownElement::new(rendered.label, tool_use_markdown_style(window, cx)))
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ use gpui::{
|
||||
};
|
||||
use language::Buffer;
|
||||
use language::CodeLabel;
|
||||
use markdown::Markdown;
|
||||
use markdown::{Markdown, MarkdownElement};
|
||||
use multi_buffer::{Anchor, ExcerptId};
|
||||
use ordered_float::OrderedFloat;
|
||||
use project::CompletionSource;
|
||||
@ -622,21 +622,18 @@ impl CompletionsMenu {
|
||||
let language = editor
|
||||
.language_at(self.initial_position, cx)
|
||||
.map(|l| l.name().to_proto());
|
||||
Markdown::new(
|
||||
SharedString::default(),
|
||||
hover_markdown_style(window, cx),
|
||||
languages,
|
||||
language,
|
||||
cx,
|
||||
)
|
||||
.copy_code_block_buttons(false)
|
||||
.open_url(open_markdown_url)
|
||||
Markdown::new(SharedString::default(), languages, language, cx)
|
||||
.copy_code_block_buttons(false)
|
||||
.open_url(open_markdown_url)
|
||||
})
|
||||
});
|
||||
markdown.update(cx, |markdown, cx| {
|
||||
markdown.reset(parsed.clone(), cx);
|
||||
});
|
||||
div().child(markdown.clone())
|
||||
div().child(MarkdownElement::new(
|
||||
markdown.clone(),
|
||||
hover_markdown_style(window, cx),
|
||||
))
|
||||
}
|
||||
CompletionDocumentation::MultiLineMarkdown(_) => return None,
|
||||
CompletionDocumentation::SingleLine(_) => return None,
|
||||
|
@ -3912,9 +3912,13 @@ impl EditorElement {
|
||||
);
|
||||
|
||||
let hover_popovers = self.editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.hover_state
|
||||
.render(snapshot, visible_display_row_range.clone(), max_size, cx)
|
||||
editor.hover_state.render(
|
||||
snapshot,
|
||||
visible_display_row_range.clone(),
|
||||
max_size,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
let Some((position, hover_popovers)) = hover_popovers else {
|
||||
return;
|
||||
|
@ -14,7 +14,7 @@ use gpui::{
|
||||
use itertools::Itertools;
|
||||
use language::{DiagnosticEntry, Language, LanguageRegistry};
|
||||
use lsp::DiagnosticSeverity;
|
||||
use markdown::{Markdown, MarkdownStyle};
|
||||
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||
use multi_buffer::{MultiOrSingleBufferOffsetRange, ToOffset};
|
||||
use project::{HoverBlock, HoverBlockKind, InlayHintLabelPart};
|
||||
use settings::Settings;
|
||||
@ -310,7 +310,7 @@ fn show_hover(
|
||||
let mut background_color: Option<Hsla> = None;
|
||||
|
||||
let parsed_content = cx
|
||||
.new_window_entity(|window, cx| {
|
||||
.new_window_entity(|_window, cx| {
|
||||
let status_colors = cx.theme().status();
|
||||
|
||||
match local_diagnostic.diagnostic.severity {
|
||||
@ -335,32 +335,8 @@ fn show_hover(
|
||||
border_color = Some(status_colors.ignored_border);
|
||||
}
|
||||
};
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let mut base_text_style = window.text_style();
|
||||
base_text_style.refine(&TextStyleRefinement {
|
||||
font_family: Some(settings.ui_font.family.clone()),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: Some(settings.ui_font_size(cx).into()),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
background_color: Some(gpui::transparent_black()),
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style,
|
||||
selection_background_color: { cx.theme().players().local().selection },
|
||||
link: TextStyleRefinement {
|
||||
underline: Some(gpui::UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
Markdown::new_text(SharedString::new(text), markdown_style.clone(), cx)
|
||||
.open_url(open_markdown_url)
|
||||
Markdown::new_text(SharedString::new(text), cx).open_url(open_markdown_url)
|
||||
})
|
||||
.ok();
|
||||
|
||||
@ -563,10 +539,9 @@ async fn parse_blocks(
|
||||
.join("\n\n");
|
||||
|
||||
let rendered_block = cx
|
||||
.new_window_entity(|window, cx| {
|
||||
.new_window_entity(|_window, cx| {
|
||||
Markdown::new(
|
||||
combined_text.into(),
|
||||
hover_markdown_style(window, cx),
|
||||
Some(language_registry.clone()),
|
||||
fallback_language_name,
|
||||
cx,
|
||||
@ -704,6 +679,7 @@ impl HoverState {
|
||||
snapshot: &EditorSnapshot,
|
||||
visible_rows: Range<DisplayRow>,
|
||||
max_size: Size<Pixels>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> Option<(DisplayPoint, Vec<AnyElement>)> {
|
||||
// If there is a diagnostic, position the popovers based on that.
|
||||
@ -738,10 +714,10 @@ impl HoverState {
|
||||
let mut elements = Vec::new();
|
||||
|
||||
if let Some(diagnostic_popover) = self.diagnostic_popover.as_ref() {
|
||||
elements.push(diagnostic_popover.render(max_size, cx));
|
||||
elements.push(diagnostic_popover.render(max_size, window, cx));
|
||||
}
|
||||
for info_popover in &mut self.info_popovers {
|
||||
elements.push(info_popover.render(max_size, cx));
|
||||
elements.push(info_popover.render(max_size, window, cx));
|
||||
}
|
||||
|
||||
Some((point, elements))
|
||||
@ -781,6 +757,7 @@ impl InfoPopover {
|
||||
pub(crate) fn render(
|
||||
&mut self,
|
||||
max_size: Size<Pixels>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> AnyElement {
|
||||
let keyboard_grace = Rc::clone(&self.keyboard_grace);
|
||||
@ -806,7 +783,10 @@ impl InfoPopover {
|
||||
.max_h(max_size.height)
|
||||
.p_2()
|
||||
.track_scroll(&self.scroll_handle)
|
||||
.child(markdown.clone()),
|
||||
.child(MarkdownElement::new(
|
||||
markdown.clone(),
|
||||
hover_markdown_style(window, cx),
|
||||
)),
|
||||
)
|
||||
.child(self.render_vertical_scrollbar(cx));
|
||||
}
|
||||
@ -868,11 +848,41 @@ pub struct DiagnosticPopover {
|
||||
}
|
||||
|
||||
impl DiagnosticPopover {
|
||||
pub fn render(&self, max_size: Size<Pixels>, cx: &mut Context<Editor>) -> AnyElement {
|
||||
pub fn render(
|
||||
&self,
|
||||
max_size: Size<Pixels>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> AnyElement {
|
||||
let keyboard_grace = Rc::clone(&self.keyboard_grace);
|
||||
let mut markdown_div = div().py_1().px_2();
|
||||
if let Some(markdown) = &self.parsed_content {
|
||||
markdown_div = markdown_div.child(markdown.clone());
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let mut base_text_style = window.text_style();
|
||||
base_text_style.refine(&TextStyleRefinement {
|
||||
font_family: Some(settings.ui_font.family.clone()),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: Some(settings.ui_font_size(cx).into()),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
background_color: Some(gpui::transparent_black()),
|
||||
..Default::default()
|
||||
});
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style,
|
||||
selection_background_color: { cx.theme().players().local().selection },
|
||||
link: TextStyleRefinement {
|
||||
underline: Some(gpui::UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
markdown_div =
|
||||
markdown_div.child(MarkdownElement::new(markdown.clone(), markdown_style));
|
||||
}
|
||||
|
||||
if let Some(background_color) = &self.background_color {
|
||||
|
@ -95,14 +95,13 @@ impl BlameRenderer for GitBlameRenderer {
|
||||
)
|
||||
}
|
||||
})
|
||||
.hoverable_tooltip(move |window, cx| {
|
||||
.hoverable_tooltip(move |_window, cx| {
|
||||
cx.new(|cx| {
|
||||
CommitTooltip::blame_entry(
|
||||
&blame_entry,
|
||||
details.clone(),
|
||||
repository.clone(),
|
||||
workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
@ -145,14 +144,13 @@ impl BlameRenderer for GitBlameRenderer {
|
||||
.child(Icon::new(IconName::FileGit).color(Color::Hint))
|
||||
.child(text)
|
||||
.gap_2()
|
||||
.hoverable_tooltip(move |window, cx| {
|
||||
.hoverable_tooltip(move |_window, cx| {
|
||||
let tooltip = cx.new(|cx| {
|
||||
CommitTooltip::blame_entry(
|
||||
&blame_entry,
|
||||
details.clone(),
|
||||
repository.clone(),
|
||||
workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
@ -8,7 +8,7 @@ use gpui::{
|
||||
App, Asset, ClipboardItem, Element, Entity, MouseButton, ParentElement, Render, ScrollHandle,
|
||||
StatefulInteractiveElement, WeakEntity, prelude::*,
|
||||
};
|
||||
use markdown::Markdown;
|
||||
use markdown::{Markdown, MarkdownElement};
|
||||
use project::git_store::Repository;
|
||||
use settings::Settings;
|
||||
use std::hash::Hash;
|
||||
@ -118,7 +118,6 @@ impl CommitTooltip {
|
||||
details: Option<ParsedCommitMessage>,
|
||||
repository: Entity<Repository>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let commit_time = blame
|
||||
@ -140,7 +139,6 @@ impl CommitTooltip {
|
||||
},
|
||||
repository,
|
||||
workspace,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
@ -149,13 +147,8 @@ impl CommitTooltip {
|
||||
commit: CommitDetails,
|
||||
repository: Entity<Repository>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let mut style = hover_markdown_style(window, cx);
|
||||
if let Some(code_block) = &style.code_block.text {
|
||||
style.base_text_style.refine(code_block);
|
||||
}
|
||||
let markdown = cx.new(|cx| {
|
||||
Markdown::new(
|
||||
commit
|
||||
@ -163,7 +156,6 @@ impl CommitTooltip {
|
||||
.as_ref()
|
||||
.map(|message| message.message.clone())
|
||||
.unwrap_or_default(),
|
||||
style,
|
||||
None,
|
||||
None,
|
||||
cx,
|
||||
@ -199,12 +191,19 @@ impl Render for CommitTooltip {
|
||||
OffsetDateTime::now_utc(),
|
||||
time_format::TimestampFormat::MediumAbsolute,
|
||||
);
|
||||
let markdown_style = {
|
||||
let mut style = hover_markdown_style(window, cx);
|
||||
if let Some(code_block) = &style.code_block.text {
|
||||
style.base_text_style.refine(code_block);
|
||||
}
|
||||
style
|
||||
};
|
||||
|
||||
let message = self
|
||||
.commit
|
||||
.message
|
||||
.as_ref()
|
||||
.map(|_| self.markdown.clone().into_any_element())
|
||||
.map(|_| MarkdownElement::new(self.markdown.clone(), markdown_style).into_any())
|
||||
.unwrap_or("<no commit message>".into_any());
|
||||
|
||||
let pull_request = self
|
||||
|
@ -3927,9 +3927,9 @@ impl GitPanelMessageTooltip {
|
||||
}),
|
||||
};
|
||||
|
||||
this.update_in(cx, |this: &mut GitPanelMessageTooltip, window, cx| {
|
||||
this.update(cx, |this: &mut GitPanelMessageTooltip, cx| {
|
||||
this.commit_tooltip = Some(cx.new(move |cx| {
|
||||
CommitTooltip::new(commit_details, repository, workspace, window, cx)
|
||||
CommitTooltip::new(commit_details, repository, workspace, cx)
|
||||
}));
|
||||
cx.notify();
|
||||
})
|
||||
|
@ -1,7 +1,7 @@
|
||||
use assets::Assets;
|
||||
use gpui::{Application, Entity, KeyBinding, StyleRefinement, WindowOptions, prelude::*, rgb};
|
||||
use language::{LanguageRegistry, language_settings::AllLanguageSettings};
|
||||
use markdown::{Markdown, MarkdownStyle};
|
||||
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||
use node_runtime::NodeRuntime;
|
||||
use settings::SettingsStore;
|
||||
use std::sync::Arc;
|
||||
@ -47,54 +47,7 @@ pub fn main() {
|
||||
|
||||
cx.activate(true);
|
||||
cx.open_window(WindowOptions::default(), |_, cx| {
|
||||
cx.new(|cx| {
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style: gpui::TextStyle {
|
||||
font_family: "Zed Plex Sans".into(),
|
||||
color: cx.theme().colors().terminal_ansi_black,
|
||||
..Default::default()
|
||||
},
|
||||
code_block: StyleRefinement::default()
|
||||
.font_family("Zed Plex Mono")
|
||||
.m(rems(1.))
|
||||
.bg(rgb(0xAAAAAAA)),
|
||||
inline_code: gpui::TextStyleRefinement {
|
||||
font_family: Some("Zed Mono".into()),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
background_color: Some(cx.theme().colors().editor_background),
|
||||
..Default::default()
|
||||
},
|
||||
rule_color: Color::Muted.color(cx),
|
||||
block_quote_border_color: Color::Muted.color(cx),
|
||||
block_quote: gpui::TextStyleRefinement {
|
||||
color: Some(Color::Muted.color(cx)),
|
||||
..Default::default()
|
||||
},
|
||||
link: gpui::TextStyleRefinement {
|
||||
color: Some(Color::Accent.color(cx)),
|
||||
underline: Some(gpui::UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: Some(Color::Accent.color(cx)),
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
selection_background_color: {
|
||||
let mut selection = cx.theme().players().local().selection;
|
||||
selection.fade_out(0.7);
|
||||
selection
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
MarkdownExample::new(
|
||||
MARKDOWN_EXAMPLE.into(),
|
||||
markdown_style,
|
||||
language_registry,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
cx.new(|cx| MarkdownExample::new(MARKDOWN_EXAMPLE.into(), language_registry, cx))
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
@ -105,16 +58,10 @@ struct MarkdownExample {
|
||||
}
|
||||
|
||||
impl MarkdownExample {
|
||||
pub fn new(
|
||||
text: SharedString,
|
||||
style: MarkdownStyle,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
pub fn new(text: SharedString, language_registry: Arc<LanguageRegistry>, cx: &mut App) -> Self {
|
||||
let markdown = cx.new(|cx| {
|
||||
Markdown::new(
|
||||
text,
|
||||
style,
|
||||
Some(language_registry),
|
||||
Some("TypeScript".to_string()),
|
||||
cx,
|
||||
@ -125,7 +72,47 @@ impl MarkdownExample {
|
||||
}
|
||||
|
||||
impl Render for MarkdownExample {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style: gpui::TextStyle {
|
||||
font_family: "Zed Plex Sans".into(),
|
||||
color: cx.theme().colors().terminal_ansi_black,
|
||||
..Default::default()
|
||||
},
|
||||
code_block: StyleRefinement::default()
|
||||
.font_family("Zed Plex Mono")
|
||||
.m(rems(1.))
|
||||
.bg(rgb(0xAAAAAAA)),
|
||||
inline_code: gpui::TextStyleRefinement {
|
||||
font_family: Some("Zed Mono".into()),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
background_color: Some(cx.theme().colors().editor_background),
|
||||
..Default::default()
|
||||
},
|
||||
rule_color: Color::Muted.color(cx),
|
||||
block_quote_border_color: Color::Muted.color(cx),
|
||||
block_quote: gpui::TextStyleRefinement {
|
||||
color: Some(Color::Muted.color(cx)),
|
||||
..Default::default()
|
||||
},
|
||||
link: gpui::TextStyleRefinement {
|
||||
color: Some(Color::Accent.color(cx)),
|
||||
underline: Some(gpui::UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: Some(Color::Accent.color(cx)),
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
selection_background_color: {
|
||||
let mut selection = cx.theme().players().local().selection;
|
||||
selection.fade_out(0.7);
|
||||
selection
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
div()
|
||||
.id("markdown-example")
|
||||
.debug_selector(|| "foo".into())
|
||||
@ -134,6 +121,6 @@ impl Render for MarkdownExample {
|
||||
.size_full()
|
||||
.p_4()
|
||||
.overflow_y_scroll()
|
||||
.child(self.markdown.clone())
|
||||
.child(MarkdownElement::new(self.markdown.clone(), markdown_style))
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use assets::Assets;
|
||||
use gpui::{Application, Entity, KeyBinding, Length, StyleRefinement, WindowOptions, rgb};
|
||||
use language::{LanguageRegistry, language_settings::AllLanguageSettings};
|
||||
use markdown::{Markdown, MarkdownStyle};
|
||||
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||
use node_runtime::NodeRuntime;
|
||||
use settings::SettingsStore;
|
||||
use std::sync::Arc;
|
||||
@ -37,58 +37,7 @@ pub fn main() {
|
||||
cx.activate(true);
|
||||
let _ = cx.open_window(WindowOptions::default(), |_, cx| {
|
||||
cx.new(|cx| {
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style: gpui::TextStyle {
|
||||
font_family: "Zed Mono".into(),
|
||||
color: cx.theme().colors().text,
|
||||
..Default::default()
|
||||
},
|
||||
code_block: StyleRefinement {
|
||||
text: Some(gpui::TextStyleRefinement {
|
||||
font_family: Some("Zed Mono".into()),
|
||||
background_color: Some(cx.theme().colors().editor_background),
|
||||
..Default::default()
|
||||
}),
|
||||
margin: gpui::EdgesRefinement {
|
||||
top: Some(Length::Definite(rems(4.).into())),
|
||||
left: Some(Length::Definite(rems(4.).into())),
|
||||
right: Some(Length::Definite(rems(4.).into())),
|
||||
bottom: Some(Length::Definite(rems(4.).into())),
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
inline_code: gpui::TextStyleRefinement {
|
||||
font_family: Some("Zed Mono".into()),
|
||||
background_color: Some(cx.theme().colors().editor_background),
|
||||
..Default::default()
|
||||
},
|
||||
rule_color: Color::Muted.color(cx),
|
||||
block_quote_border_color: Color::Muted.color(cx),
|
||||
block_quote: gpui::TextStyleRefinement {
|
||||
color: Some(Color::Muted.color(cx)),
|
||||
..Default::default()
|
||||
},
|
||||
link: gpui::TextStyleRefinement {
|
||||
color: Some(Color::Accent.color(cx)),
|
||||
underline: Some(gpui::UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: Some(Color::Accent.color(cx)),
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
selection_background_color: {
|
||||
let mut selection = cx.theme().players().local().selection;
|
||||
selection.fade_out(0.7);
|
||||
selection
|
||||
},
|
||||
heading: Default::default(),
|
||||
..Default::default()
|
||||
};
|
||||
let markdown = cx.new(|cx| {
|
||||
Markdown::new(MARKDOWN_EXAMPLE.into(), markdown_style, None, None, cx)
|
||||
});
|
||||
let markdown = cx.new(|cx| Markdown::new(MARKDOWN_EXAMPLE.into(), None, None, cx));
|
||||
|
||||
HelloWorld { markdown }
|
||||
})
|
||||
@ -100,7 +49,57 @@ struct HelloWorld {
|
||||
}
|
||||
|
||||
impl Render for HelloWorld {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style: gpui::TextStyle {
|
||||
font_family: "Zed Mono".into(),
|
||||
color: cx.theme().colors().text,
|
||||
..Default::default()
|
||||
},
|
||||
code_block: StyleRefinement {
|
||||
text: Some(gpui::TextStyleRefinement {
|
||||
font_family: Some("Zed Mono".into()),
|
||||
background_color: Some(cx.theme().colors().editor_background),
|
||||
..Default::default()
|
||||
}),
|
||||
margin: gpui::EdgesRefinement {
|
||||
top: Some(Length::Definite(rems(4.).into())),
|
||||
left: Some(Length::Definite(rems(4.).into())),
|
||||
right: Some(Length::Definite(rems(4.).into())),
|
||||
bottom: Some(Length::Definite(rems(4.).into())),
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
inline_code: gpui::TextStyleRefinement {
|
||||
font_family: Some("Zed Mono".into()),
|
||||
background_color: Some(cx.theme().colors().editor_background),
|
||||
..Default::default()
|
||||
},
|
||||
rule_color: Color::Muted.color(cx),
|
||||
block_quote_border_color: Color::Muted.color(cx),
|
||||
block_quote: gpui::TextStyleRefinement {
|
||||
color: Some(Color::Muted.color(cx)),
|
||||
..Default::default()
|
||||
},
|
||||
link: gpui::TextStyleRefinement {
|
||||
color: Some(Color::Accent.color(cx)),
|
||||
underline: Some(gpui::UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: Some(Color::Accent.color(cx)),
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
selection_background_color: {
|
||||
let mut selection = cx.theme().players().local().selection;
|
||||
selection.fade_out(0.7);
|
||||
selection
|
||||
},
|
||||
heading: Default::default(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
div()
|
||||
.flex()
|
||||
.bg(rgb(0x2e7d32))
|
||||
@ -112,6 +111,10 @@ impl Render for HelloWorld {
|
||||
.border_color(rgb(0x0000ff))
|
||||
.text_xl()
|
||||
.text_color(rgb(0xffffff))
|
||||
.child(div().child(self.markdown.clone()).p_20())
|
||||
.child(
|
||||
div()
|
||||
.child(MarkdownElement::new(self.markdown.clone(), markdown_style))
|
||||
.p_20(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use std::time::Duration;
|
||||
use gpui::{
|
||||
AnyElement, App, BorderStyle, Bounds, ClipboardItem, CursorStyle, DispatchPhase, Edges, Entity,
|
||||
FocusHandle, Focusable, FontStyle, FontWeight, GlobalElementId, Hitbox, Hsla, KeyContext,
|
||||
Length, MouseDownEvent, MouseEvent, MouseMoveEvent, MouseUpEvent, Point, Render, Stateful,
|
||||
Length, MouseDownEvent, MouseEvent, MouseMoveEvent, MouseUpEvent, Point, Stateful,
|
||||
StrikethroughStyle, StyleRefinement, StyledText, Task, TextLayout, TextRun, TextStyle,
|
||||
TextStyleRefinement, actions, point, quad,
|
||||
};
|
||||
@ -74,7 +74,6 @@ pub struct Markdown {
|
||||
selection: Selection,
|
||||
pressed_link: Option<RenderedLink>,
|
||||
autoscroll_request: Option<usize>,
|
||||
style: MarkdownStyle,
|
||||
parsed_markdown: ParsedMarkdown,
|
||||
should_reparse: bool,
|
||||
pending_parse: Option<Task<Option<()>>>,
|
||||
@ -97,7 +96,6 @@ actions!(markdown, [Copy]);
|
||||
impl Markdown {
|
||||
pub fn new(
|
||||
source: SharedString,
|
||||
style: MarkdownStyle,
|
||||
language_registry: Option<Arc<LanguageRegistry>>,
|
||||
fallback_code_block_language: Option<String>,
|
||||
cx: &mut Context<Self>,
|
||||
@ -108,7 +106,6 @@ impl Markdown {
|
||||
selection: Selection::default(),
|
||||
pressed_link: None,
|
||||
autoscroll_request: None,
|
||||
style,
|
||||
should_reparse: false,
|
||||
parsed_markdown: ParsedMarkdown::default(),
|
||||
pending_parse: None,
|
||||
@ -136,14 +133,13 @@ impl Markdown {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_text(source: SharedString, style: MarkdownStyle, cx: &mut Context<Self>) -> Self {
|
||||
pub fn new_text(source: SharedString, cx: &mut Context<Self>) -> Self {
|
||||
let focus_handle = cx.focus_handle();
|
||||
let mut this = Self {
|
||||
source,
|
||||
selection: Selection::default(),
|
||||
pressed_link: None,
|
||||
autoscroll_request: None,
|
||||
style,
|
||||
should_reparse: false,
|
||||
parsed_markdown: ParsedMarkdown::default(),
|
||||
pending_parse: None,
|
||||
@ -275,12 +271,6 @@ impl Markdown {
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Markdown {
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
MarkdownElement::new(cx.entity().clone(), self.style.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for Markdown {
|
||||
fn focus_handle(&self, _cx: &App) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
@ -341,7 +331,7 @@ pub struct MarkdownElement {
|
||||
}
|
||||
|
||||
impl MarkdownElement {
|
||||
fn new(markdown: Entity<Markdown>, style: MarkdownStyle) -> Self {
|
||||
pub fn new(markdown: Entity<Markdown>, style: MarkdownStyle) -> Self {
|
||||
Self { markdown, style }
|
||||
}
|
||||
|
||||
@ -638,6 +628,10 @@ impl Element for MarkdownElement {
|
||||
// If the path actually exists in the project, render a link to it.
|
||||
if let Some(project_path) =
|
||||
window.root::<Workspace>().flatten().and_then(|workspace| {
|
||||
if path_range.path.is_absolute() {
|
||||
return None;
|
||||
}
|
||||
|
||||
workspace
|
||||
.read(cx)
|
||||
.project()
|
||||
|
@ -13,7 +13,7 @@ use gpui::{
|
||||
};
|
||||
|
||||
use language::CursorShape;
|
||||
use markdown::{Markdown, MarkdownStyle};
|
||||
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||
use release_channel::ReleaseChannel;
|
||||
use remote::ssh_session::{ConnectionIdentifier, SshPortForwardOption};
|
||||
use remote::{SshConnectionOptions, SshPlatform, SshRemoteClient};
|
||||
@ -182,7 +182,6 @@ impl SshPrompt {
|
||||
) {
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
|
||||
let mut text_style = window.text_style();
|
||||
let refinement = TextStyleRefinement {
|
||||
font_family: Some(theme.buffer_font.family.clone()),
|
||||
font_features: Some(FontFeatures::disable_ligatures()),
|
||||
@ -192,7 +191,6 @@ impl SshPrompt {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
text_style.refine(&refinement);
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
if prompt.contains("yes/no") {
|
||||
editor.set_masked(false, cx);
|
||||
@ -202,12 +200,8 @@ impl SshPrompt {
|
||||
editor.set_text_style_refinement(refinement);
|
||||
editor.set_cursor_shape(CursorShape::Block, cx);
|
||||
});
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style: text_style,
|
||||
selection_background_color: cx.theme().players().local().selection,
|
||||
..Default::default()
|
||||
};
|
||||
let markdown = cx.new(|cx| Markdown::new_text(prompt.into(), markdown_style, cx));
|
||||
|
||||
let markdown = cx.new(|cx| Markdown::new_text(prompt.into(), cx));
|
||||
self.prompt = Some((markdown, tx));
|
||||
self.status_message.take();
|
||||
window.focus(&self.editor.focus_handle(cx));
|
||||
@ -231,7 +225,26 @@ impl SshPrompt {
|
||||
}
|
||||
|
||||
impl Render for SshPrompt {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let theme = ThemeSettings::get_global(cx);
|
||||
|
||||
let mut text_style = window.text_style();
|
||||
let refinement = TextStyleRefinement {
|
||||
font_family: Some(theme.buffer_font.family.clone()),
|
||||
font_features: Some(FontFeatures::disable_ligatures()),
|
||||
font_size: Some(theme.buffer_font_size(cx).into()),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
background_color: Some(gpui::transparent_black()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
text_style.refine(&refinement);
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style: text_style,
|
||||
selection_background_color: cx.theme().players().local().selection,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
v_flex()
|
||||
.key_context("PasswordPrompt")
|
||||
.py_2()
|
||||
@ -266,7 +279,7 @@ impl Render for SshPrompt {
|
||||
div()
|
||||
.size_full()
|
||||
.overflow_hidden()
|
||||
.child(prompt.0.clone())
|
||||
.child(MarkdownElement::new(prompt.0.clone(), markdown_style))
|
||||
.child(self.editor.clone()),
|
||||
)
|
||||
})
|
||||
|
@ -4,7 +4,7 @@ use gpui::{
|
||||
Refineable, Render, RenderablePromptHandle, SharedString, Styled, TextStyleRefinement, Window,
|
||||
div,
|
||||
};
|
||||
use markdown::{Markdown, MarkdownStyle};
|
||||
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||
use settings::{Settings, SettingsStore};
|
||||
use theme::ThemeSettings;
|
||||
use ui::{
|
||||
@ -47,24 +47,9 @@ fn zed_prompt_renderer(
|
||||
actions: actions.iter().map(ToString::to_string).collect(),
|
||||
focus: cx.focus_handle(),
|
||||
active_action_id: 0,
|
||||
detail: detail.filter(|text| !text.is_empty()).map(|text| {
|
||||
cx.new(|cx| {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let mut base_text_style = window.text_style();
|
||||
base_text_style.refine(&TextStyleRefinement {
|
||||
font_family: Some(settings.ui_font.family.clone()),
|
||||
font_size: Some(settings.ui_font_size(cx).into()),
|
||||
color: Some(ui::Color::Muted.color(cx)),
|
||||
..Default::default()
|
||||
});
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style,
|
||||
selection_background_color: { cx.theme().players().local().selection },
|
||||
..Default::default()
|
||||
};
|
||||
Markdown::new(SharedString::new(text), markdown_style, None, None, cx)
|
||||
})
|
||||
}),
|
||||
detail: detail
|
||||
.filter(|text| !text.is_empty())
|
||||
.map(|text| cx.new(|cx| Markdown::new(SharedString::new(text), None, None, cx))),
|
||||
}
|
||||
});
|
||||
|
||||
@ -127,7 +112,7 @@ impl ZedPromptRenderer {
|
||||
}
|
||||
|
||||
impl Render for ZedPromptRenderer {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let font_family = settings.ui_font.family.clone();
|
||||
let prompt = v_flex()
|
||||
@ -153,11 +138,26 @@ impl Render for ZedPromptRenderer {
|
||||
.child(self.message.clone())
|
||||
.text_color(ui::Color::Default.color(cx)),
|
||||
)
|
||||
.children(
|
||||
self.detail
|
||||
.clone()
|
||||
.map(|detail| div().w_full().text_xs().child(detail)),
|
||||
)
|
||||
.children(self.detail.clone().map(|detail| {
|
||||
div()
|
||||
.w_full()
|
||||
.text_xs()
|
||||
.child(MarkdownElement::new(detail, {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let mut base_text_style = window.text_style();
|
||||
base_text_style.refine(&TextStyleRefinement {
|
||||
font_family: Some(settings.ui_font.family.clone()),
|
||||
font_size: Some(settings.ui_font_size(cx).into()),
|
||||
color: Some(ui::Color::Muted.color(cx)),
|
||||
..Default::default()
|
||||
});
|
||||
MarkdownStyle {
|
||||
base_text_style,
|
||||
selection_background_color: { cx.theme().players().local().selection },
|
||||
..Default::default()
|
||||
}
|
||||
}))
|
||||
}))
|
||||
.child(h_flex().justify_end().gap_2().children(
|
||||
self.actions.iter().enumerate().rev().map(|(ix, action)| {
|
||||
ui::Button::new(ix, action.clone())
|
||||
|
Loading…
x
Reference in New Issue
Block a user