markdown preview: Handle line breaks in between task list items correctly (#9795)

Closes #9783 

Release Notes:

- Fixed task list rendering when there was a line break between two list
items ([#9783](https://github.com/zed-industries/zed/issues/9783))
This commit is contained in:
Bennet Bo Fenner 2024-03-26 11:12:57 +01:00 committed by GitHub
parent 157fb98a8b
commit db9221aa57
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -73,6 +73,10 @@ impl<'a> MarkdownParser<'a> {
return self.peek(0); return self.peek(0);
} }
fn current_event(&self) -> Option<&Event> {
return self.current().map(|(event, _)| event);
}
fn is_text_like(event: &Event) -> bool { fn is_text_like(event: &Event) -> bool {
match event { match event {
Event::Text(_) Event::Text(_)
@ -448,20 +452,22 @@ impl<'a> MarkdownParser<'a> {
inside_list_item = true; inside_list_item = true;
// Check for task list marker (`- [ ]` or `- [x]`) // Check for task list marker (`- [ ]` or `- [x]`)
if let Some(next) = self.current() { if let Some(event) = self.current_event() {
match next.0 { // If there is a linebreak in between two list items the task list marker will actually be the first element of the paragraph
Event::TaskListMarker(checked) => { if event == &Event::Start(Tag::Paragraph) {
task_item = Some(checked); self.cursor += 1;
self.cursor += 1; }
}
_ => {} if let Some(Event::TaskListMarker(checked)) = self.current_event() {
task_item = Some(*checked);
self.cursor += 1;
} }
} }
if let Some(next) = self.current() { if let Some(event) = self.current_event() {
// This is a plain list item. // This is a plain list item.
// For example `- some text` or `1. [Docs](./docs.md)` // For example `- some text` or `1. [Docs](./docs.md)`
if MarkdownParser::is_text_like(&next.0) { if MarkdownParser::is_text_like(event) {
let text = self.parse_text(false); let text = self.parse_text(false);
let block = ParsedMarkdownElement::Paragraph(text); let block = ParsedMarkdownElement::Paragraph(text);
current_list_items.push(Box::new(block)); current_list_items.push(Box::new(block));
@ -472,6 +478,11 @@ impl<'a> MarkdownParser<'a> {
} }
} }
} }
// If there is a linebreak in between two list items the task list marker will actually be the first element of the paragraph
if self.current_event() == Some(&Event::End(TagEnd::Paragraph)) {
self.cursor += 1;
}
} }
Event::End(TagEnd::Item) => { Event::End(TagEnd::Item) => {
self.cursor += 1; self.cursor += 1;
@ -823,6 +834,29 @@ Some other content
); );
} }
#[gpui::test]
async fn test_list_with_linebreak_is_handled_correctly() {
let parsed = parse(
"\
- [ ] Task 1
- [x] Task 2
",
)
.await;
assert_eq!(
parsed.children,
vec![list(
vec![
list_item(1, Task(false), vec![p("Task 1", 2..5)]),
list_item(1, Task(true), vec![p("Task 2", 16..19)]),
],
0..27
),]
);
}
#[gpui::test] #[gpui::test]
async fn test_list_nested() { async fn test_list_nested() {
let parsed = parse( let parsed = parse(