TextView
TextView 用于在 GPUI 中渲染格式化文本。它支持 Markdown、简单 HTML、文本选择、代码块操作,以及通过 Markdown 插件解析和渲染项目自定义语法。
标准实现现在位于 gpui-base;本模块保留兼容重导出和组件主题适配。仅使用 Base 时的设置、完整默认样式及可选语法高亮请参阅 GPUI Base TextView。
TextView::selectable(true) 使用 gpui-base 提供的窗口级文本选择引擎。如果要让普通文本或自定义 renderer 参与同一选择,请参阅 GPUI Base Text Selection(英文)。
导入
rust
use gpui_component::text::{markdown, TextView};用法
Markdown
只需要渲染 Markdown 时,可以使用 markdown helper:
rust
use gpui_component::text::markdown;
markdown("# Hello\n\nThis is **Markdown**.")
.selectable(true)
.scrollable(true)如果需要稳定 id,也可以直接构造 TextView:
rust
use gpui_component::text::TextView;
TextView::markdown("preview", markdown_source)
.selectable(true)HTML
rust
TextView::html("html-preview", "<strong>Hello</strong>")Markdown 插件
使用 .plugin(...) 支持自定义 Markdown 格式。插件同时拥有解析和渲染逻辑,调用方只需要把它挂到 TextView 上:
rust
markdown(source)
.plugin(TickerPlugin::new())Markdown 插件实现 MarkdownPlugin:
rust
use gpui::{App, IntoElement, ParentElement as _, Window};
use gpui_component::text::{
markdown_ast, MarkdownNode, MarkdownParseContext, MarkdownPlugin,
};
struct TickerNode {
symbol: String,
}
struct TickerPlugin;
impl TickerPlugin {
fn new() -> Self {
Self
}
}
impl MarkdownPlugin for TickerPlugin {
fn is_block(&self) -> bool {
true
}
fn name(&self) -> &str {
"ticker"
}
fn parse(
&self,
node: &markdown_ast::Node,
cx: &MarkdownParseContext<'_>,
) -> Option<MarkdownNode> {
let markdown_ast::Node::Paragraph(paragraph) = node else {
return None;
};
let [markdown_ast::Node::Text(text)] = paragraph.children.as_slice() else {
return None;
};
let symbol = text.value.strip_prefix('$')?;
Some(
MarkdownNode::new(
"ticker",
TickerNode {
symbol: symbol.to_string(),
},
)
.text(format!("${symbol}"))
.markdown(cx.node_source(node).unwrap_or(text.value.as_str())),
)
}
fn render(
&self,
node: &MarkdownNode,
_window: &mut Window,
_cx: &mut App,
) -> impl IntoElement {
let ticker = node.data::<TickerNode>().expect("ticker node data");
gpui::div().child(format!("${}", ticker.symbol))
}
}然后挂到 Markdown TextView:
rust
markdown("$AAPL.US")
.plugin(TickerPlugin::new())MarkdownNode
MarkdownNode 是 parse 和 render 之间传递的中性数据结构。
rust
MarkdownNode::new("ticker", TickerNode { symbol })
.text("$AAPL.US")
.markdown("$AAPL.US")name是稳定的节点名称,用于匹配 renderer。data是 parser 产生的类型化数据,通过node.data::<T>()读取。text是纯文本表示,用于选择和未注册 renderer 时的回退渲染。markdown是 Markdown 表示,用于将文档重新序列化为 Markdown。
Block 插件
当前自定义 Markdown 渲染支持 block 插件。现在可注册的插件需要在 is_block() 中返回 true:
rust
fn is_block(&self) -> bool {
true
}Inline 插件保留给未来的 TextView 支持。
代码块操作
可以为 Markdown 代码块渲染操作控件:
rust
markdown(source)
.code_block_actions(|code_block, _window, _cx| {
gpui::div().child(format!("Run {}", code_block.lang().unwrap_or_default()))
})