From 5d741f39eb679fd518116d62c26622d718e0c415 Mon Sep 17 00:00:00 2001 From: Kenneth Date: Mon, 11 May 2026 01:22:19 +0800 Subject: [PATCH] feat: impl md code fence rendering --- src/component/markdown.rs | 60 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/component/markdown.rs b/src/component/markdown.rs index b3e74d7..bbd632e 100644 --- a/src/component/markdown.rs +++ b/src/component/markdown.rs @@ -2,7 +2,7 @@ use std::ops::Range; -use gpui::{AppContext, ParentElement, Refineable, RenderOnce, Styled, div, px, rems}; +use gpui::{AppContext, ParentElement, Refineable, RenderOnce, Styled, div, px, relative, rems}; use tree_sitter::Node; use crate::{app, theme}; @@ -422,6 +422,64 @@ impl MarkdownText { } } + | MARKDOWN_KIND_ID_FENCED_CODE_BLOCK => { + // expected tree shape: + // fenced_code_block + // ├── info_string? (present if there is a language annotation) + // └── code_fence_content? (present if there is some content between the backticks) + + if !cursor.goto_first_child() { + render_fallback_content(&cursor, &self.content, &mut self.blocks); + continue; + } + + let content = if cursor.node().kind_id() == MARKDOWN_KIND_ID_INFO_STRING { + // skipping info string (which annotates the code block) + if cursor.goto_next_sibling() { + // this is code_fence_content node + gpui::SharedString::new( + cursor + .node() + .utf8_text(self.content.as_bytes()) + .unwrap_or_default(), + ) + } else { + gpui::SharedString::default() + } + } else { + // assuming the current node is already code_fence_content + gpui::SharedString::new( + cursor + .node() + .utf8_text(self.content.as_bytes()) + .unwrap_or_default(), + ) + }; + + cursor.goto_parent(); + + let block = ContentBlock::Text { + decoration: None, + text: content, + highlights: Vec::new(), + links: Vec::new(), + style: gpui::StyleRefinement::default(), + } + .text_sm() + .text_color(theme.colors.text) + .line_height(relative(1.2)) + .font_family("Menlo") + .px_3() + .py_2() + .rounded_sm() + .bg(theme.colors.surface) + .border_1() + .my_4() + .border_color(theme.colors.border); + + self.blocks.push(block); + } + | _ => { println!( "[WARN] formatting not implemenetd for node type {:?}",