markdown: Make push_div
work with Stateful<Div>
s (#22622)
This PR updates the `push_div` method in the `MarkdownElementBuilder` to support taking in a `Stateful<Div>`. This is some groundwork for supporting horizontal scrolling in Markdown code blocks. Release Notes: - N/A
This commit is contained in:
parent
bb24c085be
commit
7826d79a40
1 changed files with 55 additions and 8 deletions
|
@ -6,8 +6,8 @@ use gpui::{
|
||||||
actions, point, quad, AnyElement, AppContext, Bounds, ClipboardItem, CursorStyle,
|
actions, point, quad, AnyElement, AppContext, Bounds, ClipboardItem, CursorStyle,
|
||||||
DispatchPhase, Edges, FocusHandle, FocusableView, FontStyle, FontWeight, GlobalElementId,
|
DispatchPhase, Edges, FocusHandle, FocusableView, FontStyle, FontWeight, GlobalElementId,
|
||||||
Hitbox, Hsla, KeyContext, Length, MouseDownEvent, MouseEvent, MouseMoveEvent, MouseUpEvent,
|
Hitbox, Hsla, KeyContext, Length, MouseDownEvent, MouseEvent, MouseMoveEvent, MouseUpEvent,
|
||||||
Point, Render, StrikethroughStyle, StyleRefinement, StyledText, Task, TextLayout, TextRun,
|
Point, Render, Stateful, StrikethroughStyle, StyleRefinement, StyledText, Task, TextLayout,
|
||||||
TextStyle, TextStyleRefinement, View,
|
TextRun, TextStyle, TextStyleRefinement, View,
|
||||||
};
|
};
|
||||||
use language::{Language, LanguageRegistry, Rope};
|
use language::{Language, LanguageRegistry, Rope};
|
||||||
use parser::{parse_links_only, parse_markdown, MarkdownEvent, MarkdownTag, MarkdownTagEnd};
|
use parser::{parse_links_only, parse_markdown, MarkdownEvent, MarkdownTag, MarkdownTagEnd};
|
||||||
|
@ -785,8 +785,52 @@ impl IntoElement for MarkdownElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AnyDiv {
|
||||||
|
Div(Div),
|
||||||
|
Stateful(Stateful<Div>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AnyDiv {
|
||||||
|
fn into_any_element(self) -> AnyElement {
|
||||||
|
match self {
|
||||||
|
Self::Div(div) => div.into_any_element(),
|
||||||
|
Self::Stateful(div) => div.into_any_element(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Div> for AnyDiv {
|
||||||
|
fn from(value: Div) -> Self {
|
||||||
|
Self::Div(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Stateful<Div>> for AnyDiv {
|
||||||
|
fn from(value: Stateful<Div>) -> Self {
|
||||||
|
Self::Stateful(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Styled for AnyDiv {
|
||||||
|
fn style(&mut self) -> &mut StyleRefinement {
|
||||||
|
match self {
|
||||||
|
Self::Div(div) => div.style(),
|
||||||
|
Self::Stateful(div) => div.style(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParentElement for AnyDiv {
|
||||||
|
fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
|
||||||
|
match self {
|
||||||
|
Self::Div(div) => div.extend(elements),
|
||||||
|
Self::Stateful(div) => div.extend(elements),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct MarkdownElementBuilder {
|
struct MarkdownElementBuilder {
|
||||||
div_stack: Vec<Div>,
|
div_stack: Vec<AnyDiv>,
|
||||||
rendered_lines: Vec<RenderedLine>,
|
rendered_lines: Vec<RenderedLine>,
|
||||||
pending_line: PendingLine,
|
pending_line: PendingLine,
|
||||||
rendered_links: Vec<RenderedLink>,
|
rendered_links: Vec<RenderedLink>,
|
||||||
|
@ -812,7 +856,7 @@ struct ListStackEntry {
|
||||||
impl MarkdownElementBuilder {
|
impl MarkdownElementBuilder {
|
||||||
fn new(base_text_style: TextStyle, syntax_theme: Arc<SyntaxTheme>) -> Self {
|
fn new(base_text_style: TextStyle, syntax_theme: Arc<SyntaxTheme>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
div_stack: vec![div().debug_selector(|| "inner".into())],
|
div_stack: vec![div().debug_selector(|| "inner".into()).into()],
|
||||||
rendered_lines: Vec::new(),
|
rendered_lines: Vec::new(),
|
||||||
pending_line: PendingLine::default(),
|
pending_line: PendingLine::default(),
|
||||||
rendered_links: Vec::new(),
|
rendered_links: Vec::new(),
|
||||||
|
@ -841,11 +885,12 @@ impl MarkdownElementBuilder {
|
||||||
self.text_style_stack.pop();
|
self.text_style_stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_div(&mut self, mut div: Div, range: &Range<usize>, markdown_end: usize) {
|
fn push_div(&mut self, div: impl Into<AnyDiv>, range: &Range<usize>, markdown_end: usize) {
|
||||||
|
let mut div = div.into();
|
||||||
self.flush_text();
|
self.flush_text();
|
||||||
|
|
||||||
if range.start == 0 {
|
if range.start == 0 {
|
||||||
//first element, remove top margin
|
// Remove the top margin on the first element.
|
||||||
div.style().refine(&StyleRefinement {
|
div.style().refine(&StyleRefinement {
|
||||||
margin: gpui::EdgesRefinement {
|
margin: gpui::EdgesRefinement {
|
||||||
top: Some(Length::Definite(px(0.).into())),
|
top: Some(Length::Definite(px(0.).into())),
|
||||||
|
@ -856,6 +901,7 @@ impl MarkdownElementBuilder {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if range.end == markdown_end {
|
if range.end == markdown_end {
|
||||||
div.style().refine(&StyleRefinement {
|
div.style().refine(&StyleRefinement {
|
||||||
margin: gpui::EdgesRefinement {
|
margin: gpui::EdgesRefinement {
|
||||||
|
@ -867,12 +913,13 @@ impl MarkdownElementBuilder {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.div_stack.push(div);
|
self.div_stack.push(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_div(&mut self) {
|
fn pop_div(&mut self) {
|
||||||
self.flush_text();
|
self.flush_text();
|
||||||
let div = self.div_stack.pop().unwrap().into_any();
|
let div = self.div_stack.pop().unwrap().into_any_element();
|
||||||
self.div_stack.last_mut().unwrap().extend(iter::once(div));
|
self.div_stack.last_mut().unwrap().extend(iter::once(div));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -973,7 +1020,7 @@ impl MarkdownElementBuilder {
|
||||||
debug_assert_eq!(self.div_stack.len(), 1);
|
debug_assert_eq!(self.div_stack.len(), 1);
|
||||||
self.flush_text();
|
self.flush_text();
|
||||||
RenderedMarkdown {
|
RenderedMarkdown {
|
||||||
element: self.div_stack.pop().unwrap().into_any(),
|
element: self.div_stack.pop().unwrap().into_any_element(),
|
||||||
text: RenderedText {
|
text: RenderedText {
|
||||||
lines: self.rendered_lines.into(),
|
lines: self.rendered_lines.into(),
|
||||||
links: self.rendered_links.into(),
|
links: self.rendered_links.into(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue