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
12 changed files with 370 additions and 374 deletions
|
@ -22,7 +22,7 @@ use gpui::{
|
||||||
};
|
};
|
||||||
use language::{Buffer, LanguageRegistry};
|
use language::{Buffer, LanguageRegistry};
|
||||||
use language_model::{ConfiguredModel, LanguageModelRegistry, LanguageModelToolUseId, Role};
|
use language_model::{ConfiguredModel, LanguageModelRegistry, LanguageModelToolUseId, Role};
|
||||||
use markdown::{Markdown, MarkdownStyle};
|
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||||
use project::ProjectItem as _;
|
use project::ProjectItem as _;
|
||||||
use settings::{Settings as _, update_settings_file};
|
use settings::{Settings as _, update_settings_file};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -77,7 +77,6 @@ impl RenderedMessage {
|
||||||
segments: &[MessageSegment],
|
segments: &[MessageSegment],
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
window: &Window,
|
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
|
@ -85,18 +84,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(), window, cx);
|
this.push_segment(segment, workspace.clone(), cx);
|
||||||
}
|
}
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_thinking(
|
fn append_thinking(&mut self, text: &String, workspace: WeakEntity<Workspace>, cx: &mut App) {
|
||||||
&mut self,
|
|
||||||
text: &String,
|
|
||||||
workspace: WeakEntity<Workspace>,
|
|
||||||
window: &Window,
|
|
||||||
cx: &mut App,
|
|
||||||
) {
|
|
||||||
if let Some(RenderedMessageSegment::Thinking {
|
if let Some(RenderedMessageSegment::Thinking {
|
||||||
content,
|
content,
|
||||||
scroll_handle,
|
scroll_handle,
|
||||||
|
@ -112,7 +105,6 @@ impl RenderedMessage {
|
||||||
text.into(),
|
text.into(),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
workspace,
|
workspace,
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
scroll_handle: ScrollHandle::default(),
|
scroll_handle: ScrollHandle::default(),
|
||||||
|
@ -120,13 +112,7 @@ impl RenderedMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_text(
|
fn append_text(&mut self, text: &String, workspace: WeakEntity<Workspace>, cx: &mut App) {
|
||||||
&mut self,
|
|
||||||
text: &String,
|
|
||||||
workspace: WeakEntity<Workspace>,
|
|
||||||
window: &Window,
|
|
||||||
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 {
|
||||||
|
@ -135,7 +121,6 @@ impl RenderedMessage {
|
||||||
SharedString::from(text),
|
SharedString::from(text),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
workspace,
|
workspace,
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -145,7 +130,6 @@ impl RenderedMessage {
|
||||||
&mut self,
|
&mut self,
|
||||||
segment: &MessageSegment,
|
segment: &MessageSegment,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
window: &Window,
|
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) {
|
) {
|
||||||
let rendered_segment = match segment {
|
let rendered_segment = match segment {
|
||||||
|
@ -154,7 +138,6 @@ impl RenderedMessage {
|
||||||
text.into(),
|
text.into(),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
workspace,
|
workspace,
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
scroll_handle: ScrollHandle::default(),
|
scroll_handle: ScrollHandle::default(),
|
||||||
|
@ -163,7 +146,6 @@ impl RenderedMessage {
|
||||||
text.into(),
|
text.into(),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
workspace,
|
workspace,
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
|
@ -183,9 +165,16 @@ fn render_markdown(
|
||||||
text: SharedString,
|
text: SharedString,
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
window: &Window,
|
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Entity<Markdown> {
|
) -> 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 theme_settings = ThemeSettings::get_global(cx);
|
||||||
let colors = cx.theme().colors();
|
let colors = cx.theme().colors();
|
||||||
let ui_font_size = TextSize::Default.rems(cx);
|
let ui_font_size = TextSize::Default.rems(cx);
|
||||||
|
@ -201,7 +190,7 @@ fn render_markdown(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
let markdown_style = MarkdownStyle {
|
MarkdownStyle {
|
||||||
base_text_style: text_style,
|
base_text_style: text_style,
|
||||||
syntax: cx.theme().syntax().clone(),
|
syntax: cx.theme().syntax().clone(),
|
||||||
selection_background_color: cx.theme().players().local().selection,
|
selection_background_color: cx.theme().players().local().selection,
|
||||||
|
@ -266,24 +255,23 @@ fn render_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 render_tool_use_markdown(
|
fn render_tool_use_markdown(
|
||||||
text: SharedString,
|
text: SharedString,
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
window: &Window,
|
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Entity<Markdown> {
|
) -> 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 theme_settings = ThemeSettings::get_global(cx);
|
||||||
let colors = cx.theme().colors();
|
let colors = cx.theme().colors();
|
||||||
let ui_font_size = TextSize::Default.rems(cx);
|
let ui_font_size = TextSize::Default.rems(cx);
|
||||||
|
@ -299,7 +287,7 @@ fn render_tool_use_markdown(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
let markdown_style = MarkdownStyle {
|
MarkdownStyle {
|
||||||
base_text_style: text_style,
|
base_text_style: text_style,
|
||||||
syntax: cx.theme().syntax().clone(),
|
syntax: cx.theme().syntax().clone(),
|
||||||
selection_background_color: cx.theme().players().local().selection,
|
selection_background_color: cx.theme().players().local().selection,
|
||||||
|
@ -334,15 +322,7 @@ fn render_tool_use_markdown(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
..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(
|
fn open_markdown_link(
|
||||||
|
@ -473,7 +453,6 @@ impl ActiveThread {
|
||||||
tool_use.ui_text.clone(),
|
tool_use.ui_text.clone(),
|
||||||
&tool_use.input,
|
&tool_use.input,
|
||||||
tool_use.status.text(),
|
tool_use.status.text(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -516,7 +495,7 @@ impl ActiveThread {
|
||||||
&mut self,
|
&mut self,
|
||||||
id: &MessageId,
|
id: &MessageId,
|
||||||
segments: &[MessageSegment],
|
segments: &[MessageSegment],
|
||||||
window: &mut Window,
|
_window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let old_len = self.messages.len();
|
let old_len = self.messages.len();
|
||||||
|
@ -527,7 +506,6 @@ impl ActiveThread {
|
||||||
segments,
|
segments,
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
self.workspace.clone(),
|
self.workspace.clone(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
self.rendered_messages_by_id.insert(*id, rendered_message);
|
self.rendered_messages_by_id.insert(*id, rendered_message);
|
||||||
|
@ -537,7 +515,7 @@ impl ActiveThread {
|
||||||
&mut self,
|
&mut self,
|
||||||
id: &MessageId,
|
id: &MessageId,
|
||||||
segments: &[MessageSegment],
|
segments: &[MessageSegment],
|
||||||
window: &mut Window,
|
_window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let Some(index) = self.messages.iter().position(|message_id| message_id == id) else {
|
let Some(index) = self.messages.iter().position(|message_id| message_id == id) else {
|
||||||
|
@ -548,7 +526,6 @@ impl ActiveThread {
|
||||||
segments,
|
segments,
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
self.workspace.clone(),
|
self.workspace.clone(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
self.rendered_messages_by_id.insert(*id, rendered_message);
|
self.rendered_messages_by_id.insert(*id, rendered_message);
|
||||||
|
@ -569,7 +546,6 @@ impl ActiveThread {
|
||||||
tool_label: impl Into<SharedString>,
|
tool_label: impl Into<SharedString>,
|
||||||
tool_input: &serde_json::Value,
|
tool_input: &serde_json::Value,
|
||||||
tool_output: SharedString,
|
tool_output: SharedString,
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let rendered = RenderedToolUse {
|
let rendered = RenderedToolUse {
|
||||||
|
@ -577,7 +553,6 @@ impl ActiveThread {
|
||||||
tool_label.into(),
|
tool_label.into(),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
self.workspace.clone(),
|
self.workspace.clone(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
input: render_tool_use_markdown(
|
input: render_tool_use_markdown(
|
||||||
|
@ -588,14 +563,12 @@ impl ActiveThread {
|
||||||
.into(),
|
.into(),
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
self.workspace.clone(),
|
self.workspace.clone(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
output: render_tool_use_markdown(
|
output: render_tool_use_markdown(
|
||||||
tool_output,
|
tool_output,
|
||||||
self.language_registry.clone(),
|
self.language_registry.clone(),
|
||||||
self.workspace.clone(),
|
self.workspace.clone(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
@ -640,12 +613,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(), window, cx);
|
rendered_message.append_text(text, self.workspace.clone(), 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(), window, cx);
|
rendered_message.append_thinking(text, self.workspace.clone(), cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ThreadEvent::MessageAdded(message_id) => {
|
ThreadEvent::MessageAdded(message_id) => {
|
||||||
|
@ -690,7 +663,6 @@ impl ActiveThread {
|
||||||
tool_use.ui_text.clone(),
|
tool_use.ui_text.clone(),
|
||||||
&tool_use.input,
|
&tool_use.input,
|
||||||
"".into(),
|
"".into(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -711,7 +683,6 @@ impl ActiveThread {
|
||||||
.tool_result(&tool_use.id)
|
.tool_result(&tool_use.id)
|
||||||
.map(|result| result.content.clone().into())
|
.map(|result| result.content.clone().into())
|
||||||
.unwrap_or("".into()),
|
.unwrap_or("".into()),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1204,6 +1175,7 @@ impl ActiveThread {
|
||||||
message_id,
|
message_id,
|
||||||
rendered_message,
|
rendered_message,
|
||||||
has_tool_uses,
|
has_tool_uses,
|
||||||
|
window,
|
||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
.into_any()
|
.into_any()
|
||||||
|
@ -1370,7 +1342,7 @@ impl ActiveThread {
|
||||||
div().children(
|
div().children(
|
||||||
tool_uses
|
tool_uses
|
||||||
.into_iter()
|
.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,
|
message_id: MessageId,
|
||||||
rendered_message: &RenderedMessage,
|
rendered_message: &RenderedMessage,
|
||||||
has_tool_uses: bool,
|
has_tool_uses: bool,
|
||||||
|
window: &Window,
|
||||||
cx: &Context<Self>,
|
cx: &Context<Self>,
|
||||||
) -> impl IntoElement {
|
) -> impl IntoElement {
|
||||||
let is_last_message = self.messages.last() == Some(&message_id);
|
let is_last_message = self.messages.last() == Some(&message_id);
|
||||||
|
@ -1572,12 +1545,16 @@ impl ActiveThread {
|
||||||
content.clone(),
|
content.clone(),
|
||||||
&scroll_handle,
|
&scroll_handle,
|
||||||
Some(index) == pending_thinking_segment_index,
|
Some(index) == pending_thinking_segment_index,
|
||||||
|
window,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
RenderedMessageSegment::Text(markdown) => {
|
RenderedMessageSegment::Text(markdown) => div()
|
||||||
div().child(markdown.clone()).into_any_element()
|
.child(MarkdownElement::new(
|
||||||
}
|
markdown.clone(),
|
||||||
|
default_markdown_style(window, cx),
|
||||||
|
))
|
||||||
|
.into_any_element(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1601,6 +1578,7 @@ impl ActiveThread {
|
||||||
markdown: Entity<Markdown>,
|
markdown: Entity<Markdown>,
|
||||||
scroll_handle: &ScrollHandle,
|
scroll_handle: &ScrollHandle,
|
||||||
pending: bool,
|
pending: bool,
|
||||||
|
window: &Window,
|
||||||
cx: &Context<Self>,
|
cx: &Context<Self>,
|
||||||
) -> impl IntoElement {
|
) -> impl IntoElement {
|
||||||
let is_open = self
|
let is_open = self
|
||||||
|
@ -1734,7 +1712,10 @@ impl ActiveThread {
|
||||||
.h_20()
|
.h_20()
|
||||||
.track_scroll(scroll_handle)
|
.track_scroll(scroll_handle)
|
||||||
.text_ui_sm(cx)
|
.text_ui_sm(cx)
|
||||||
.child(markdown.clone())
|
.child(MarkdownElement::new(
|
||||||
|
markdown.clone(),
|
||||||
|
default_markdown_style(window, cx),
|
||||||
|
))
|
||||||
.overflow_hidden(),
|
.overflow_hidden(),
|
||||||
)
|
)
|
||||||
.child(gradient_overlay),
|
.child(gradient_overlay),
|
||||||
|
@ -1749,7 +1730,10 @@ impl ActiveThread {
|
||||||
.rounded_b_lg()
|
.rounded_b_lg()
|
||||||
.bg(editor_bg)
|
.bg(editor_bg)
|
||||||
.text_ui_sm(cx)
|
.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(
|
fn render_tool_use(
|
||||||
&self,
|
&self,
|
||||||
tool_use: ToolUse,
|
tool_use: ToolUse,
|
||||||
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> impl IntoElement + use<> {
|
) -> impl IntoElement + use<> {
|
||||||
let is_open = self
|
let is_open = self
|
||||||
|
@ -1804,103 +1789,109 @@ 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 = v_flex()
|
let results_content =
|
||||||
.gap_1()
|
v_flex()
|
||||||
.child(
|
.gap_1()
|
||||||
results_content_container()
|
.child(
|
||||||
.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(
|
|
||||||
results_content_container()
|
results_content_container()
|
||||||
.border_t_1()
|
|
||||||
.border_color(self.tool_card_border_color(cx))
|
|
||||||
.child(
|
.child(
|
||||||
Label::new("Result")
|
Label::new("Input")
|
||||||
.size(LabelSize::XSmall)
|
.size(LabelSize::XSmall)
|
||||||
.color(Color::Muted)
|
.color(Color::Muted)
|
||||||
.buffer_font(cx),
|
.buffer_font(cx),
|
||||||
)
|
)
|
||||||
.child(
|
.child(div().w_full().text_ui_sm(cx).children(
|
||||||
div().w_full().text_ui_sm(cx).children(
|
rendered_tool_use.as_ref().map(|rendered| {
|
||||||
rendered_tool_use
|
MarkdownElement::new(
|
||||||
.as_ref()
|
rendered.input.clone(),
|
||||||
.map(|rendered| rendered.output.clone()),
|
tool_use_markdown_style(window, cx),
|
||||||
),
|
)
|
||||||
),
|
}),
|
||||||
),
|
)),
|
||||||
ToolUseStatus::Running => container.child(
|
)
|
||||||
results_content_container().child(
|
.map(|container| match tool_use.status {
|
||||||
h_flex()
|
ToolUseStatus::Finished(_) => container.child(
|
||||||
.gap_1()
|
results_content_container()
|
||||||
.pb_1()
|
|
||||||
.border_t_1()
|
.border_t_1()
|
||||||
.border_color(self.tool_card_border_color(cx))
|
.border_color(self.tool_card_border_color(cx))
|
||||||
.child(
|
.child(
|
||||||
Icon::new(IconName::ArrowCircle)
|
Label::new("Result")
|
||||||
.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)
|
.size(LabelSize::XSmall)
|
||||||
.color(Color::Muted)
|
.color(Color::Muted)
|
||||||
.buffer_font(cx),
|
.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| {
|
let gradient_overlay = |color: Hsla| {
|
||||||
div()
|
div()
|
||||||
|
@ -1948,7 +1939,7 @@ 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| rendered.label)
|
rendered_tool_use.map(|rendered| MarkdownElement::new(rendered.label, tool_use_markdown_style(window, cx)))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -2036,7 +2027,7 @@ 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| 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::Buffer;
|
||||||
use language::CodeLabel;
|
use language::CodeLabel;
|
||||||
use markdown::Markdown;
|
use markdown::{Markdown, MarkdownElement};
|
||||||
use multi_buffer::{Anchor, ExcerptId};
|
use multi_buffer::{Anchor, ExcerptId};
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use project::CompletionSource;
|
use project::CompletionSource;
|
||||||
|
@ -622,21 +622,18 @@ impl CompletionsMenu {
|
||||||
let language = editor
|
let language = editor
|
||||||
.language_at(self.initial_position, cx)
|
.language_at(self.initial_position, cx)
|
||||||
.map(|l| l.name().to_proto());
|
.map(|l| l.name().to_proto());
|
||||||
Markdown::new(
|
Markdown::new(SharedString::default(), languages, language, cx)
|
||||||
SharedString::default(),
|
.copy_code_block_buttons(false)
|
||||||
hover_markdown_style(window, cx),
|
.open_url(open_markdown_url)
|
||||||
languages,
|
|
||||||
language,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
.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(markdown.clone())
|
div().child(MarkdownElement::new(
|
||||||
|
markdown.clone(),
|
||||||
|
hover_markdown_style(window, cx),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
CompletionDocumentation::MultiLineMarkdown(_) => return None,
|
CompletionDocumentation::MultiLineMarkdown(_) => return None,
|
||||||
CompletionDocumentation::SingleLine(_) => return None,
|
CompletionDocumentation::SingleLine(_) => return None,
|
||||||
|
|
|
@ -3912,9 +3912,13 @@ impl EditorElement {
|
||||||
);
|
);
|
||||||
|
|
||||||
let hover_popovers = self.editor.update(cx, |editor, cx| {
|
let hover_popovers = self.editor.update(cx, |editor, cx| {
|
||||||
editor
|
editor.hover_state.render(
|
||||||
.hover_state
|
snapshot,
|
||||||
.render(snapshot, visible_display_row_range.clone(), max_size, cx)
|
visible_display_row_range.clone(),
|
||||||
|
max_size,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
let Some((position, hover_popovers)) = hover_popovers else {
|
let Some((position, hover_popovers)) = hover_popovers else {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -14,7 +14,7 @@ use gpui::{
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{DiagnosticEntry, Language, LanguageRegistry};
|
use language::{DiagnosticEntry, Language, LanguageRegistry};
|
||||||
use lsp::DiagnosticSeverity;
|
use lsp::DiagnosticSeverity;
|
||||||
use markdown::{Markdown, MarkdownStyle};
|
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||||
use multi_buffer::{MultiOrSingleBufferOffsetRange, ToOffset};
|
use multi_buffer::{MultiOrSingleBufferOffsetRange, ToOffset};
|
||||||
use project::{HoverBlock, HoverBlockKind, InlayHintLabelPart};
|
use project::{HoverBlock, HoverBlockKind, InlayHintLabelPart};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
@ -310,7 +310,7 @@ fn show_hover(
|
||||||
let mut background_color: Option<Hsla> = None;
|
let mut background_color: Option<Hsla> = None;
|
||||||
|
|
||||||
let parsed_content = cx
|
let parsed_content = cx
|
||||||
.new_window_entity(|window, cx| {
|
.new_window_entity(|_window, cx| {
|
||||||
let status_colors = cx.theme().status();
|
let status_colors = cx.theme().status();
|
||||||
|
|
||||||
match local_diagnostic.diagnostic.severity {
|
match local_diagnostic.diagnostic.severity {
|
||||||
|
@ -335,32 +335,8 @@ fn show_hover(
|
||||||
border_color = Some(status_colors.ignored_border);
|
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()
|
Markdown::new_text(SharedString::new(text), cx).open_url(open_markdown_url)
|
||||||
});
|
|
||||||
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)
|
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
@ -563,10 +539,9 @@ async fn parse_blocks(
|
||||||
.join("\n\n");
|
.join("\n\n");
|
||||||
|
|
||||||
let rendered_block = cx
|
let rendered_block = cx
|
||||||
.new_window_entity(|window, cx| {
|
.new_window_entity(|_window, cx| {
|
||||||
Markdown::new(
|
Markdown::new(
|
||||||
combined_text.into(),
|
combined_text.into(),
|
||||||
hover_markdown_style(window, cx),
|
|
||||||
Some(language_registry.clone()),
|
Some(language_registry.clone()),
|
||||||
fallback_language_name,
|
fallback_language_name,
|
||||||
cx,
|
cx,
|
||||||
|
@ -704,6 +679,7 @@ impl HoverState {
|
||||||
snapshot: &EditorSnapshot,
|
snapshot: &EditorSnapshot,
|
||||||
visible_rows: Range<DisplayRow>,
|
visible_rows: Range<DisplayRow>,
|
||||||
max_size: Size<Pixels>,
|
max_size: Size<Pixels>,
|
||||||
|
window: &mut Window,
|
||||||
cx: &mut Context<Editor>,
|
cx: &mut Context<Editor>,
|
||||||
) -> Option<(DisplayPoint, Vec<AnyElement>)> {
|
) -> Option<(DisplayPoint, Vec<AnyElement>)> {
|
||||||
// If there is a diagnostic, position the popovers based on that.
|
// If there is a diagnostic, position the popovers based on that.
|
||||||
|
@ -738,10 +714,10 @@ impl HoverState {
|
||||||
let mut elements = Vec::new();
|
let mut elements = Vec::new();
|
||||||
|
|
||||||
if let Some(diagnostic_popover) = self.diagnostic_popover.as_ref() {
|
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 {
|
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))
|
Some((point, elements))
|
||||||
|
@ -781,6 +757,7 @@ impl InfoPopover {
|
||||||
pub(crate) fn render(
|
pub(crate) fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
max_size: Size<Pixels>,
|
max_size: Size<Pixels>,
|
||||||
|
window: &mut Window,
|
||||||
cx: &mut Context<Editor>,
|
cx: &mut Context<Editor>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
let keyboard_grace = Rc::clone(&self.keyboard_grace);
|
let keyboard_grace = Rc::clone(&self.keyboard_grace);
|
||||||
|
@ -806,7 +783,10 @@ 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(markdown.clone()),
|
.child(MarkdownElement::new(
|
||||||
|
markdown.clone(),
|
||||||
|
hover_markdown_style(window, cx),
|
||||||
|
)),
|
||||||
)
|
)
|
||||||
.child(self.render_vertical_scrollbar(cx));
|
.child(self.render_vertical_scrollbar(cx));
|
||||||
}
|
}
|
||||||
|
@ -868,11 +848,41 @@ pub struct DiagnosticPopover {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 keyboard_grace = Rc::clone(&self.keyboard_grace);
|
||||||
let mut markdown_div = div().py_1().px_2();
|
let mut markdown_div = div().py_1().px_2();
|
||||||
if let Some(markdown) = &self.parsed_content {
|
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 {
|
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| {
|
cx.new(|cx| {
|
||||||
CommitTooltip::blame_entry(
|
CommitTooltip::blame_entry(
|
||||||
&blame_entry,
|
&blame_entry,
|
||||||
details.clone(),
|
details.clone(),
|
||||||
repository.clone(),
|
repository.clone(),
|
||||||
workspace.clone(),
|
workspace.clone(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -145,14 +144,13 @@ impl BlameRenderer for GitBlameRenderer {
|
||||||
.child(Icon::new(IconName::FileGit).color(Color::Hint))
|
.child(Icon::new(IconName::FileGit).color(Color::Hint))
|
||||||
.child(text)
|
.child(text)
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.hoverable_tooltip(move |window, cx| {
|
.hoverable_tooltip(move |_window, cx| {
|
||||||
let tooltip = cx.new(|cx| {
|
let tooltip = cx.new(|cx| {
|
||||||
CommitTooltip::blame_entry(
|
CommitTooltip::blame_entry(
|
||||||
&blame_entry,
|
&blame_entry,
|
||||||
details.clone(),
|
details.clone(),
|
||||||
repository.clone(),
|
repository.clone(),
|
||||||
workspace.clone(),
|
workspace.clone(),
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,7 +8,7 @@ use gpui::{
|
||||||
App, Asset, ClipboardItem, Element, Entity, MouseButton, ParentElement, Render, ScrollHandle,
|
App, Asset, ClipboardItem, Element, Entity, MouseButton, ParentElement, Render, ScrollHandle,
|
||||||
StatefulInteractiveElement, WeakEntity, prelude::*,
|
StatefulInteractiveElement, WeakEntity, prelude::*,
|
||||||
};
|
};
|
||||||
use markdown::Markdown;
|
use markdown::{Markdown, MarkdownElement};
|
||||||
use project::git_store::Repository;
|
use project::git_store::Repository;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
@ -118,7 +118,6 @@ impl CommitTooltip {
|
||||||
details: Option<ParsedCommitMessage>,
|
details: Option<ParsedCommitMessage>,
|
||||||
repository: Entity<Repository>,
|
repository: Entity<Repository>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let commit_time = blame
|
let commit_time = blame
|
||||||
|
@ -140,7 +139,6 @@ impl CommitTooltip {
|
||||||
},
|
},
|
||||||
repository,
|
repository,
|
||||||
workspace,
|
workspace,
|
||||||
window,
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -149,13 +147,8 @@ impl CommitTooltip {
|
||||||
commit: CommitDetails,
|
commit: CommitDetails,
|
||||||
repository: Entity<Repository>,
|
repository: Entity<Repository>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> 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| {
|
let markdown = cx.new(|cx| {
|
||||||
Markdown::new(
|
Markdown::new(
|
||||||
commit
|
commit
|
||||||
|
@ -163,7 +156,6 @@ impl CommitTooltip {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|message| message.message.clone())
|
.map(|message| message.message.clone())
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
style,
|
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
cx,
|
cx,
|
||||||
|
@ -199,12 +191,19 @@ impl Render for CommitTooltip {
|
||||||
OffsetDateTime::now_utc(),
|
OffsetDateTime::now_utc(),
|
||||||
time_format::TimestampFormat::MediumAbsolute,
|
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
|
let message = self
|
||||||
.commit
|
.commit
|
||||||
.message
|
.message
|
||||||
.as_ref()
|
.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());
|
.unwrap_or("<no commit message>".into_any());
|
||||||
|
|
||||||
let pull_request = self
|
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| {
|
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();
|
cx.notify();
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use assets::Assets;
|
use assets::Assets;
|
||||||
use gpui::{Application, Entity, KeyBinding, StyleRefinement, WindowOptions, prelude::*, rgb};
|
use gpui::{Application, Entity, KeyBinding, StyleRefinement, WindowOptions, prelude::*, rgb};
|
||||||
use language::{LanguageRegistry, language_settings::AllLanguageSettings};
|
use language::{LanguageRegistry, language_settings::AllLanguageSettings};
|
||||||
use markdown::{Markdown, MarkdownStyle};
|
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -47,54 +47,7 @@ pub fn main() {
|
||||||
|
|
||||||
cx.activate(true);
|
cx.activate(true);
|
||||||
cx.open_window(WindowOptions::default(), |_, cx| {
|
cx.open_window(WindowOptions::default(), |_, cx| {
|
||||||
cx.new(|cx| {
|
cx.new(|cx| MarkdownExample::new(MARKDOWN_EXAMPLE.into(), language_registry, 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,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
});
|
});
|
||||||
|
@ -105,16 +58,10 @@ struct MarkdownExample {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MarkdownExample {
|
impl MarkdownExample {
|
||||||
pub fn new(
|
pub fn new(text: SharedString, language_registry: Arc<LanguageRegistry>, cx: &mut App) -> Self {
|
||||||
text: SharedString,
|
|
||||||
style: MarkdownStyle,
|
|
||||||
language_registry: Arc<LanguageRegistry>,
|
|
||||||
cx: &mut App,
|
|
||||||
) -> Self {
|
|
||||||
let markdown = cx.new(|cx| {
|
let markdown = cx.new(|cx| {
|
||||||
Markdown::new(
|
Markdown::new(
|
||||||
text,
|
text,
|
||||||
style,
|
|
||||||
Some(language_registry),
|
Some(language_registry),
|
||||||
Some("TypeScript".to_string()),
|
Some("TypeScript".to_string()),
|
||||||
cx,
|
cx,
|
||||||
|
@ -125,7 +72,47 @@ impl MarkdownExample {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for 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()
|
div()
|
||||||
.id("markdown-example")
|
.id("markdown-example")
|
||||||
.debug_selector(|| "foo".into())
|
.debug_selector(|| "foo".into())
|
||||||
|
@ -134,6 +121,6 @@ impl Render for MarkdownExample {
|
||||||
.size_full()
|
.size_full()
|
||||||
.p_4()
|
.p_4()
|
||||||
.overflow_y_scroll()
|
.overflow_y_scroll()
|
||||||
.child(self.markdown.clone())
|
.child(MarkdownElement::new(self.markdown.clone(), markdown_style))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use assets::Assets;
|
use assets::Assets;
|
||||||
use gpui::{Application, Entity, KeyBinding, Length, StyleRefinement, WindowOptions, rgb};
|
use gpui::{Application, Entity, KeyBinding, Length, StyleRefinement, WindowOptions, rgb};
|
||||||
use language::{LanguageRegistry, language_settings::AllLanguageSettings};
|
use language::{LanguageRegistry, language_settings::AllLanguageSettings};
|
||||||
use markdown::{Markdown, MarkdownStyle};
|
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -37,58 +37,7 @@ pub fn main() {
|
||||||
cx.activate(true);
|
cx.activate(true);
|
||||||
let _ = cx.open_window(WindowOptions::default(), |_, cx| {
|
let _ = cx.open_window(WindowOptions::default(), |_, cx| {
|
||||||
cx.new(|cx| {
|
cx.new(|cx| {
|
||||||
let markdown_style = MarkdownStyle {
|
let markdown = cx.new(|cx| Markdown::new(MARKDOWN_EXAMPLE.into(), None, None, cx));
|
||||||
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)
|
|
||||||
});
|
|
||||||
|
|
||||||
HelloWorld { markdown }
|
HelloWorld { markdown }
|
||||||
})
|
})
|
||||||
|
@ -100,7 +49,57 @@ struct HelloWorld {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for 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()
|
div()
|
||||||
.flex()
|
.flex()
|
||||||
.bg(rgb(0x2e7d32))
|
.bg(rgb(0x2e7d32))
|
||||||
|
@ -112,6 +111,10 @@ impl Render for HelloWorld {
|
||||||
.border_color(rgb(0x0000ff))
|
.border_color(rgb(0x0000ff))
|
||||||
.text_xl()
|
.text_xl()
|
||||||
.text_color(rgb(0xffffff))
|
.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::{
|
use gpui::{
|
||||||
AnyElement, App, BorderStyle, Bounds, ClipboardItem, CursorStyle, DispatchPhase, Edges, Entity,
|
AnyElement, App, BorderStyle, Bounds, ClipboardItem, CursorStyle, DispatchPhase, Edges, Entity,
|
||||||
FocusHandle, Focusable, FontStyle, FontWeight, GlobalElementId, Hitbox, Hsla, KeyContext,
|
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,
|
StrikethroughStyle, StyleRefinement, StyledText, Task, TextLayout, TextRun, TextStyle,
|
||||||
TextStyleRefinement, actions, point, quad,
|
TextStyleRefinement, actions, point, quad,
|
||||||
};
|
};
|
||||||
|
@ -74,7 +74,6 @@ pub struct Markdown {
|
||||||
selection: Selection,
|
selection: Selection,
|
||||||
pressed_link: Option<RenderedLink>,
|
pressed_link: Option<RenderedLink>,
|
||||||
autoscroll_request: Option<usize>,
|
autoscroll_request: Option<usize>,
|
||||||
style: MarkdownStyle,
|
|
||||||
parsed_markdown: ParsedMarkdown,
|
parsed_markdown: ParsedMarkdown,
|
||||||
should_reparse: bool,
|
should_reparse: bool,
|
||||||
pending_parse: Option<Task<Option<()>>>,
|
pending_parse: Option<Task<Option<()>>>,
|
||||||
|
@ -97,7 +96,6 @@ actions!(markdown, [Copy]);
|
||||||
impl Markdown {
|
impl Markdown {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
source: SharedString,
|
source: SharedString,
|
||||||
style: MarkdownStyle,
|
|
||||||
language_registry: Option<Arc<LanguageRegistry>>,
|
language_registry: Option<Arc<LanguageRegistry>>,
|
||||||
fallback_code_block_language: Option<String>,
|
fallback_code_block_language: Option<String>,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
|
@ -108,7 +106,6 @@ impl Markdown {
|
||||||
selection: Selection::default(),
|
selection: Selection::default(),
|
||||||
pressed_link: None,
|
pressed_link: None,
|
||||||
autoscroll_request: None,
|
autoscroll_request: None,
|
||||||
style,
|
|
||||||
should_reparse: false,
|
should_reparse: false,
|
||||||
parsed_markdown: ParsedMarkdown::default(),
|
parsed_markdown: ParsedMarkdown::default(),
|
||||||
pending_parse: None,
|
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 focus_handle = cx.focus_handle();
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
source,
|
source,
|
||||||
selection: Selection::default(),
|
selection: Selection::default(),
|
||||||
pressed_link: None,
|
pressed_link: None,
|
||||||
autoscroll_request: None,
|
autoscroll_request: None,
|
||||||
style,
|
|
||||||
should_reparse: false,
|
should_reparse: false,
|
||||||
parsed_markdown: ParsedMarkdown::default(),
|
parsed_markdown: ParsedMarkdown::default(),
|
||||||
pending_parse: None,
|
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 {
|
impl Focusable for Markdown {
|
||||||
fn focus_handle(&self, _cx: &App) -> FocusHandle {
|
fn focus_handle(&self, _cx: &App) -> FocusHandle {
|
||||||
self.focus_handle.clone()
|
self.focus_handle.clone()
|
||||||
|
@ -341,7 +331,7 @@ pub struct MarkdownElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MarkdownElement {
|
impl MarkdownElement {
|
||||||
fn new(markdown: Entity<Markdown>, style: MarkdownStyle) -> Self {
|
pub fn new(markdown: Entity<Markdown>, style: MarkdownStyle) -> Self {
|
||||||
Self { markdown, style }
|
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 the path actually exists in the project, render a link to it.
|
||||||
if let Some(project_path) =
|
if let Some(project_path) =
|
||||||
window.root::<Workspace>().flatten().and_then(|workspace| {
|
window.root::<Workspace>().flatten().and_then(|workspace| {
|
||||||
|
if path_range.path.is_absolute() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
workspace
|
workspace
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.project()
|
.project()
|
||||||
|
|
|
@ -13,7 +13,7 @@ use gpui::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use language::CursorShape;
|
use language::CursorShape;
|
||||||
use markdown::{Markdown, MarkdownStyle};
|
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||||
use release_channel::ReleaseChannel;
|
use release_channel::ReleaseChannel;
|
||||||
use remote::ssh_session::{ConnectionIdentifier, SshPortForwardOption};
|
use remote::ssh_session::{ConnectionIdentifier, SshPortForwardOption};
|
||||||
use remote::{SshConnectionOptions, SshPlatform, SshRemoteClient};
|
use remote::{SshConnectionOptions, SshPlatform, SshRemoteClient};
|
||||||
|
@ -182,7 +182,6 @@ impl SshPrompt {
|
||||||
) {
|
) {
|
||||||
let theme = ThemeSettings::get_global(cx);
|
let theme = ThemeSettings::get_global(cx);
|
||||||
|
|
||||||
let mut text_style = window.text_style();
|
|
||||||
let refinement = TextStyleRefinement {
|
let refinement = TextStyleRefinement {
|
||||||
font_family: Some(theme.buffer_font.family.clone()),
|
font_family: Some(theme.buffer_font.family.clone()),
|
||||||
font_features: Some(FontFeatures::disable_ligatures()),
|
font_features: Some(FontFeatures::disable_ligatures()),
|
||||||
|
@ -192,7 +191,6 @@ impl SshPrompt {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
text_style.refine(&refinement);
|
|
||||||
self.editor.update(cx, |editor, cx| {
|
self.editor.update(cx, |editor, cx| {
|
||||||
if prompt.contains("yes/no") {
|
if prompt.contains("yes/no") {
|
||||||
editor.set_masked(false, cx);
|
editor.set_masked(false, cx);
|
||||||
|
@ -202,12 +200,8 @@ impl SshPrompt {
|
||||||
editor.set_text_style_refinement(refinement);
|
editor.set_text_style_refinement(refinement);
|
||||||
editor.set_cursor_shape(CursorShape::Block, cx);
|
editor.set_cursor_shape(CursorShape::Block, cx);
|
||||||
});
|
});
|
||||||
let markdown_style = MarkdownStyle {
|
|
||||||
base_text_style: text_style,
|
let markdown = cx.new(|cx| Markdown::new_text(prompt.into(), cx));
|
||||||
selection_background_color: cx.theme().players().local().selection,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let markdown = cx.new(|cx| Markdown::new_text(prompt.into(), markdown_style, cx));
|
|
||||||
self.prompt = Some((markdown, tx));
|
self.prompt = Some((markdown, tx));
|
||||||
self.status_message.take();
|
self.status_message.take();
|
||||||
window.focus(&self.editor.focus_handle(cx));
|
window.focus(&self.editor.focus_handle(cx));
|
||||||
|
@ -231,7 +225,26 @@ impl SshPrompt {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for 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()
|
v_flex()
|
||||||
.key_context("PasswordPrompt")
|
.key_context("PasswordPrompt")
|
||||||
.py_2()
|
.py_2()
|
||||||
|
@ -266,7 +279,7 @@ impl Render for SshPrompt {
|
||||||
div()
|
div()
|
||||||
.size_full()
|
.size_full()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.child(prompt.0.clone())
|
.child(MarkdownElement::new(prompt.0.clone(), markdown_style))
|
||||||
.child(self.editor.clone()),
|
.child(self.editor.clone()),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,7 +4,7 @@ use gpui::{
|
||||||
Refineable, Render, RenderablePromptHandle, SharedString, Styled, TextStyleRefinement, Window,
|
Refineable, Render, RenderablePromptHandle, SharedString, Styled, TextStyleRefinement, Window,
|
||||||
div,
|
div,
|
||||||
};
|
};
|
||||||
use markdown::{Markdown, MarkdownStyle};
|
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||||
use settings::{Settings, SettingsStore};
|
use settings::{Settings, SettingsStore};
|
||||||
use theme::ThemeSettings;
|
use theme::ThemeSettings;
|
||||||
use ui::{
|
use ui::{
|
||||||
|
@ -47,24 +47,9 @@ fn zed_prompt_renderer(
|
||||||
actions: actions.iter().map(ToString::to_string).collect(),
|
actions: actions.iter().map(ToString::to_string).collect(),
|
||||||
focus: cx.focus_handle(),
|
focus: cx.focus_handle(),
|
||||||
active_action_id: 0,
|
active_action_id: 0,
|
||||||
detail: detail.filter(|text| !text.is_empty()).map(|text| {
|
detail: detail
|
||||||
cx.new(|cx| {
|
.filter(|text| !text.is_empty())
|
||||||
let settings = ThemeSettings::get_global(cx);
|
.map(|text| cx.new(|cx| Markdown::new(SharedString::new(text), None, None, 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)
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -127,7 +112,7 @@ impl ZedPromptRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for 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 settings = ThemeSettings::get_global(cx);
|
||||||
let font_family = settings.ui_font.family.clone();
|
let font_family = settings.ui_font.family.clone();
|
||||||
let prompt = v_flex()
|
let prompt = v_flex()
|
||||||
|
@ -153,11 +138,26 @@ impl Render for ZedPromptRenderer {
|
||||||
.child(self.message.clone())
|
.child(self.message.clone())
|
||||||
.text_color(ui::Color::Default.color(cx)),
|
.text_color(ui::Color::Default.color(cx)),
|
||||||
)
|
)
|
||||||
.children(
|
.children(self.detail.clone().map(|detail| {
|
||||||
self.detail
|
div()
|
||||||
.clone()
|
.w_full()
|
||||||
.map(|detail| div().w_full().text_xs().child(detail)),
|
.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(
|
.child(h_flex().justify_end().gap_2().children(
|
||||||
self.actions.iter().enumerate().rev().map(|(ix, action)| {
|
self.actions.iter().enumerate().rev().map(|(ix, action)| {
|
||||||
ui::Button::new(ix, action.clone())
|
ui::Button::new(ix, action.clone())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue