Tree-sitter
OpenTUI 集成了 Tree-sitter,提供快速、精确的语法高亮功能。你可以全局注册解析器,也可以按客户端注册。
全局添加解析器
在创建客户端之前使用 addDefaultParsers():
import { addDefaultParsers, getTreeSitterClient } from "@opentui/core"
addDefaultParsers([
{
filetype: "python",
wasm: "https://github.com/tree-sitter/tree-sitter-python/releases/download/v0.23.6/tree-sitter-python.wasm",
queries: {
highlights: ["https://raw.githubusercontent.com/tree-sitter/tree-sitter-python/master/queries/highlights.scm"],
},
},
])
const client = getTreeSitterClient()
await client.initialize()
按客户端添加解析器
import { TreeSitterClient } from "@opentui/core"
const client = new TreeSitterClient({ dataPath: "./cache" })
await client.initialize()
client.addFiletypeParser({
filetype: "rust",
wasm: "https://github.com/tree-sitter/tree-sitter-rust/releases/download/v0.23.2/tree-sitter-rust.wasm",
queries: {
highlights: ["https://raw.githubusercontent.com/tree-sitter/tree-sitter-rust/master/queries/highlights.scm"],
},
})
解析器配置
interface FiletypeParserOptions {
filetype: string
aliases?: string[]
wasm: string
queries: {
highlights: string[]
injections?: string[]
}
injectionMapping?: {
nodeTypes?: Record<string, string>
infoStringMap?: Record<string, string>
}
}
aliases 将额外的文件类型 ID 映射到同一组解析器资源。
语言注入
使用 queries.injections 来高亮嵌入的语言。
injectionMapping.nodeTypes将注入的节点类型映射到文件类型 ID。injectionMapping.infoStringMap将代码围栏语言标签映射到文件类型 ID。
client.addFiletypeParser({
filetype: "markdown",
wasm: "https://github.com/tree-sitter-grammars/tree-sitter-markdown/releases/download/v0.5.1/tree-sitter-markdown.wasm",
queries: {
highlights: ["./assets/markdown/highlights.scm"],
injections: [
"https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/markdown/injections.scm",
],
},
injectionMapping: {
nodeTypes: {
inline: "markdown_inline",
pipe_table_cell: "markdown_inline",
},
infoStringMap: {
js: "javascript",
jsx: "javascriptreact",
ts: "typescript",
tsx: "typescriptreact",
},
},
})
如果 infoStringMap 没有匹配项,则使用代码围栏语言标签作为文件类型 ID。
使用本地文件
import pythonWasm from "./parsers/tree-sitter-python.wasm" with { type: "file" }
import pythonHighlights from "./queries/python/highlights.scm" with { type: "file" }
addDefaultParsers([
{
filetype: "python",
wasm: pythonWasm,
queries: {
highlights: [pythonHighlights],
},
},
])
自动化资源管理
使用 updateAssets 工具来下载解析器并生成导入语句。
CLI 用法
{
"scripts": {
"prebuild": "bun node_modules/@opentui/core/lib/tree-sitter/update-assets.js --config ./parsers-config.json --assets ./src/parsers --output ./src/parsers.ts"
}
}
编程用法
import { updateAssets } from "@opentui/core/tree-sitter/update-assets"
await updateAssets({
configPath: "./parsers-config.json",
assetsDir: "./src/parsers",
outputPath: "./src/parsers.ts",
})
与 CodeRenderable 配合使用
import { CodeRenderable, RGBA, SyntaxStyle, getTreeSitterClient } from "@opentui/core"
const client = getTreeSitterClient()
await client.initialize()
const syntaxStyle = SyntaxStyle.fromStyles({
default: { fg: RGBA.fromHex("#E6EDF3") },
})
const code = new CodeRenderable(renderer, {
id: "code",
content: "const x = 1",
filetype: "typescript",
syntaxStyle,
treeSitterClient: client,
})
缓存
解析器和查询文件会缓存在客户端的 dataPath 中。设置自定义缓存目录:
const client = new TreeSitterClient({
dataPath: "./my-cache",
})
文件类型解析
import { pathToFiletype, extToFiletype, infoStringToFiletype } from "@opentui/core"
const ft1 = pathToFiletype("src/main.rs")
const ft2 = extToFiletype("ts")
const ft3 = infoStringToFiletype("TSX title=Button.tsx")
infoStringToFiletype() 用于 Markdown 围栏代码块。
你可以在运行时扩展或覆盖映射:
import { extensionToFiletype, basenameToFiletype } from "@opentui/core"
extensionToFiletype.set("templ", "html")
basenameToFiletype.set("mytoolrc", "yaml")