markdown: Fix indented codeblocks having incorrect content ranges (#38225)

Lukas Wirth created

Closes https://github.com/zed-industries/zed/issues/37743

Release Notes:

- Fixed agent panel panicking when streaming indented codeblocks from
agent output

Change summary

crates/markdown/src/markdown.rs |  4 ++--
crates/markdown/src/parser.rs   | 25 +++++++++++++++++++++++--
2 files changed, 25 insertions(+), 4 deletions(-)

Detailed changes

crates/markdown/src/markdown.rs 🔗

@@ -1079,7 +1079,7 @@ impl Element for MarkdownElement {
                         {
                             builder.modify_current_div(|el| {
                                 let content_range = parser::extract_code_block_content_range(
-                                    parsed_markdown.source()[range.clone()].trim(),
+                                    &parsed_markdown.source()[range.clone()],
                                 );
                                 let content_range = content_range.start + range.start
                                     ..content_range.end + range.start;
@@ -1110,7 +1110,7 @@ impl Element for MarkdownElement {
                         {
                             builder.modify_current_div(|el| {
                                 let content_range = parser::extract_code_block_content_range(
-                                    parsed_markdown.source()[range.clone()].trim(),
+                                    &parsed_markdown.source()[range.clone()],
                                 );
                                 let content_range = content_range.start + range.start
                                     ..content_range.end + range.start;

crates/markdown/src/parser.rs 🔗

@@ -67,7 +67,7 @@ pub fn parse_markdown(
                         MarkdownTag::CodeBlock {
                             kind: CodeBlockKind::Indented,
                             metadata: CodeBlockMetadata {
-                                content_range: range.start + 1..range.end + 1,
+                                content_range: range.clone(),
                                 line_count: 1,
                             },
                         }
@@ -698,7 +698,28 @@ mod tests {
                 HashSet::from(["rust".into()]),
                 HashSet::new()
             )
-        )
+        );
+        assert_eq!(
+            parse_markdown("    fn main() {}"),
+            (
+                vec![
+                    (
+                        4..16,
+                        Start(CodeBlock {
+                            kind: CodeBlockKind::Indented,
+                            metadata: CodeBlockMetadata {
+                                content_range: 4..16,
+                                line_count: 1
+                            }
+                        })
+                    ),
+                    (4..16, Text),
+                    (4..16, End(MarkdownTagEnd::CodeBlock))
+                ],
+                HashSet::new(),
+                HashSet::new()
+            )
+        );
     }
 
     #[test]