Lazygit 终端着色体系详解:gookit/color 的 ANSI 色彩渲染与 16/256/真彩色实现
Lazygit 的界面之所以能在终端中呈现主题化、可配置的彩色输出,底层依赖的是被 vendored 进仓库的命令行着色库 gookit/color。本篇基于该库的 README 文档,系统讲解其 16 色 / 256 色 / 真彩色(RGB)三级色彩模型、HTML 风格标签语法与颜色转换工具集,并结合 Lazygit 源码(pkg/theme/gocui.go、pkg/gui/style/color.go 等)说明这些 API 是如何被 Lazygit 的主题系统与自定义配色配置实际消费的,读完后可独立掌握在 Go TUI/CLI 应用中做终端着色的完整方案。
一、gookit/color 是什么
gookit/color 是一个“命令行列色库”(command-line color library),核心定位(见 vendor/github.com/gookit/color/color.go 顶部包注释):
- 支持富色彩渲染输出、通用 API 方法,并兼容 Windows 系统;
- 零依赖(zero dependencies),使用简单;
- 支持 16 色(4-bit)、256 色(8-bit)、真彩色(24-bit RGB)三级输出:
- 16 色是支持最广泛的级别,在任何 Windows 版本上都能工作;
- 自
v1.2.4起,256 色与真彩色也支持 Windows CMD 和 PowerShell 环境;
- 支持 HEX、HSL 值到 RGB 的转换;
- 提供与
fmt对齐的通用 API:Print、Printf、Println、Sprint、Sprintf; - 支持 HTML 标签式着色(如
<green>message</> <fg=red;bg=blue>text</>),且自定义标签属性可同时使用 16 色名、256 色值、RGB 值和 HEX 值; - 通过环境变量
NO_COLOR禁用颜色,或用FORCE_COLOR强制开启颜色渲染; - 支持 RGB、256、16 三级颜色之间的相互转换。
安装方式(本仓库中已通过 go mod vendor 固定在 vendor/github.com/gookit/color/ 下,查看即可):
go get github.com/gookit/color
二、快速上手:通用 API 与快捷函数
README 给出的 Quick start 示例完整展示了该库的三层用法:包级快捷函数、fmt.Print* 风格方法、函数式引用:
package main
import (
"fmt"
"github.com/gookit/color"
)
func main() {
// 包级快捷函数
color.Redp("Simple to use color")
color.Redln("Simple to use color")
color.Greenp("Simple to use color\n")
color.Cyanln("Simple to use color")
color.Yellowln("Simple to use color")
// 像 fmt.Print* 一样使用
color.Red.Println("Simple to use color")
color.Green.Print("Simple to use color\n")
color.Cyan.Printf("Simple to use %s\n", "color")
color.Yellow.Printf("Simple to use %s\n", "color")
// 像函数一样使用
red := color.FgRed.Render
green := color.FgGreen.Render
fmt.Printf("%s line %s library\n", red("Command"), green("color"))
// 自定义颜色
color.New(color.FgWhite, color.BgBlack).Println("custom color style")
// 也可以:
color.Style{color.FgCyan, color.OpBold}.Println("custom color style")
// 内置主题/风格
color.Info.Tips("message")
color.Info.Prompt("message")
color.Info.Println("message")
color.Warn.Println("message")
color.Error.Println("message")
// 使用 style tag
color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>\n")
// 自定义标签属性:支持 16 色名、256 色值、RGB 值与 HEX 值
color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>")
// 应用一个 style tag
color.Tag("info").Println("info style text")
// prompt 消息
color.Info.Prompt("prompt style message")
color.Warn.Prompt("prompt style message")
// tips 消息
color.Info.Tips("tips style message")
color.Warn.Tips("tips style message")
}
官方示例的运行方式:go run ./_examples/demo.go(示例源码位于上游仓库的 _examples/ 目录,vendor 目录中仅包含库本体)。
三、Basic / 16 色:兼容性最好的一级
16 色在任意 Windows 版本上可用,是所有终端的“最大公约数”。基础色 API 同样提供 Print、Printf、Println、Sprint、Sprintf:
color.Bold.Println("bold message")
color.Cyan.Println("yellow message")
color.Yellow.Println("yellow message")
color.Magenta.Println("yellow message")
// 仅使用前景色
color.FgCyan.Printf("Simple to use %s\n", "color")
// 仅使用背景色
color.BgRed.Printf("Simple to use %s\n", "color")
运行演示:go run ./_examples/color_16.go。
3.1 自定义组合颜色与样式
完全自定义前景、背景与修饰(option):
myStyle := color.New(color.FgWhite, color.BgBlack, color.OpBold)
myStyle.Println("custom color style")
// 也可以:
color.Style{color.FgCyan, color.OpBold}.Println("custom color style")
还可以直接设置/重置控制台自身的颜色状态(影响后续所有输出):
color.Set(color.FgCyan) // 设置控制台颜色
fmt.Print("message") // 打印消息
color.Reset() // 重置控制台设置
从源码 vendor/github.com/gookit/color/color.go 可以看到,Set 内部调用 Colors2code(colors...) 生成形如 "32;45" 的 SGR 参数串,再通过 SetTerminal(code) 写入终端;Reset 则对应 ResetTerminal()。
3.2 附加风格(Additional styles)
除基础色外,库内置了一组语义化风格:Info、Note、Light、Error、Danger、Notice、Success、Comment、Primary、Warning、Question、Secondary,全部提供通用 Print* 方法:
color.Info.Println("Info message")
color.Notice.Println("Notice message")
color.Error.Println("Error message")
// ...
此外还有三种带版式语义的风格:
Tips 风格:
color.Info.Tips("Info tips message")
color.Notice.Tips("Notice tips message")
color.Error.Tips("Error tips message")
color.Secondary.Tips("Secondary tips message")
Prompt 风格:
color.Info.Prompt("Info prompt message")
color.Notice.Prompt("Notice prompt message")
color.Error.Prompt("Error prompt message")
// ...
Block 风格:
color.Danger.Block("Danger block message")
color.Warn.Block("Warn block message")
// ...
对应的演示分别为 go run ./_examples/theme_basic.go、theme_tips.go、theme_prompt.go、theme_block.go。
四、256 色用法
256 色在
v1.2.4起支持 Windows CMD、PowerShell 环境。
4.1 单独设置前景或背景
核心构造函数:color.C256(val uint8, isBg ...bool) Color256,第二个可选布尔参数决定是否作为背景色:
c := color.C256(132) // 前景色
c.Println("message")
c.Printf("format %s", "message")
c := color.C256(132, true) // 背景色
c.Println("message")
c.Printf("format %s", "message")
4.2 256 色样式
构造函数 S256(fgAndBg ...uint8) *Style256 可同时设置前景与背景:
s := color.S256(32, 203)
s.Println("message")
s.Printf("format %s", "message")
配合 options:
s := color.S256(32, 203)
s.SetOpts(color.Opts{color.OpBold})
s.Println("style with options")
s.Printf("style with %s\n", "options")
运行演示:go run ./_examples/color_256.go。
五、RGB / 真彩色
RGB 颜色在
v1.2.4起支持 WindowsCMD、PowerShell环境。
5.1 设置前景或背景
color.RGB(r, g, b uint8, isBg ...bool) RGBColor
color.RGB(30, 144, 255).Println("message. use RGB number")
c := color.RGB(30, 144, 255) // 前景色
c.Println("message")
c = color.RGB(30, 144, 255, true) // 背景色
c.Println("message")
color.HEX(hex string, isBg ...bool) RGBColor,HEX 值支持"ccc"、"cccccc"、"#cccccc"三种写法:
color.HEX("#1976D2").Println("blue-darken")
color.HEX("#D50000", true).Println("red-accent. use HEX style")
c := color.HEX("ccc")
c.Println("message")
c = color.HEX("aabbcc", true) // 作为背景色
c.Println("message")
5.2 RGB 样式
color.NewRGBStyle(fg RGBColor, bg ...RGBColor) *RGBStyle:
s := color.NewRGBStyle(RGB(20, 144, 234), RGB(234, 78, 23))
s.Println("message")
s.Printf("format %s", "message")
color.HEXStyle(fg string, bg ...string) *RGBStyle:
s := color.HEXStyle("11aa23", "eee")
s.Println("message")
s.Printf("format %s", "message")
配合 options:
s := color.HEXStyle("11aa23", "eee")
s.SetOpts(color.Opts{color.OpBold})
s.Println("style with options")
s.Printf("style with %s\n", "options")
运行演示:go run ./_examples/color_rgb.go。
六、HTML 风格标签(Tag)渲染
Print、Printf、Println 等函数支持自动解析并渲染颜色标签,这是该库区别于普通 ANSI 封装的一个亮点。一个综合示例:
text := `
<mga1>gookit/color:</>
A <green>command-line</>
<cyan>color library</> with <fg=167;bg=232>256-color</>
and <fg=11aa23;op=bold>True-color</> support,
<fg=mga;op=i>universal API</> methods
and <cyan>Windows</> support.
`
color.Print(text)
标签格式分两类:
- 内置标签:
<TAG_NAME>CONTENT</>,例如<info>message</>; - 自定义属性标签:
<fg=VALUE;bg=VALUE;op=VALUES>CONTENT</>,例如<fg=167;bg=232>wel</>。
更多示例:
// 使用 style tag
color.Print("<suc>he</><comment>llo</>, <cyan>wel</><red>come</>")
color.Println("<suc>hello</>")
color.Println("<error>hello</>")
color.Println("<warning>hello</>")
// 自定义颜色属性
color.Print("<fg=yellow;bg=black;op=underscore;>hello, welcome</>\n")
// 自定义标签属性:支持 16 色名、256 色值、RGB 值与 HEX 值
color.Println("<fg=11aa23>he</><bg=120,35,156>llo</>, <fg=167;bg=232>wel</><fg=red>come</>")
6.1 标签属性格式
属性串的统一格式为 "fg=VALUE;bg=VALUE;op=VALUE"(VALUE 取值见源码变量 FgColors、BgColors、AllOptions),三类颜色级别各有语法:
16 色:
"fg=yellow"
"bg=red"
"op=bold,underscore" // option 允许多值
"fg=white;bg=blue;op=bold"
"fg=white;op=bold,underscore"
256 色:
"fg=167"
"fg=167;bg=23"
"fg=167;bg=23;op=bold"
真彩色:
// hex
"fg=fc1cac"
"fg=fc1cac;bg=c2c3c4"
// r,g,b
"fg=23,45,214"
"fg=23,45,214;bg=109,99,88"
属性解析入口是 func ParseCodeFromAttr()(位于 vendor/github.com/gookit/color/color_tag.go)。内置标签名清单可参考该文件中的 colorTags 变量。
除了内联标签,还可以用 color.Tag 按标签名构造消息:
color.Tag("info").Print("info style text")
color.Tag("info").Printf("%s style text", "info")
color.Tag("info").Println("info style text")
标签渲染在 Windows cmd.exe 与 PowerShell 下同样受支持;渲染开关是包级变量 RenderTag(默认为 true,可用 NotRenderTag() 关闭),定义在 vendor/github.com/gookit/color/color.go。
七、颜色转换:RGB ⇄ 256 ⇄ 16
库支持三级颜色互转(Rgb <=> 256 <=> 16),每个颜色类型都提供了转换方法:
basic := color.Red
basic.Println("basic color")
c256 := color.Red.C256()
c256.Println("256 color")
c256.C16().Println("basic color")
rgb := color.Red.RGB()
rgb.Println("rgb color")
rgb.C256().Println("256 color")
README 还列出了一组内置转换工具函数(实现在 vendor/github.com/gookit/color/convert.go):
func Basic2hex(val uint8) string
func Bg2Fg(val uint8) uint8
func Fg2Bg(val uint8) uint8
func C256ToRgb(val uint8) (rgb []uint8)
func C256ToRgbV1(val uint8) (rgb []uint8)
func Hex2basic(hex string, asBg ...bool) uint8
func Hex2rgb(hex string) []int
func HexToRGB(hex string) []int
func HexToRgb(hex string) (rgb []int)
func HslIntToRgb(h, s, l int) (rgb []uint8)
func HslToRgb(h, s, l float64) (rgb []uint8)
func HsvToRgb(h, s, v int) (rgb []uint8)
func Rgb2ansi(r, g, b uint8, isBg bool) uint8
func Rgb2basic(r, g, b uint8, isBg bool) uint8
func Rgb2hex(rgb []int) string
func Rgb2short(r, g, b uint8) uint8
func RgbTo256(r, g, b uint8) uint8
func RgbTo256Table() map[string]uint8
func RgbToAnsi(r, g, b uint8, isBg bool) uint8
func RgbToHex(rgb []int) string
func RgbToHsl(r, g, b uint8) []float64
func RgbToHslInt(r, g, b uint8) []int
转换为 RGBColor 的构造函数(统一入口,isBg 可选参数决定是否作为背景色):
func RGBFromSlice(rgb []uint8, isBg ...bool) RGBColorfunc RGBFromString(rgb string, isBg ...bool) RGBColorfunc HEX(hex string, isBg ...bool) RGBColorfunc HSL(h, s, l float64, isBg ...bool) RGBColorfunc HSLInt(h, s, l int, isBg ...bool) RGBColor
八、实用函数与颜色级别探测
README 列出的实用函数与 vendor/github.com/gookit/color/color.go 中的实现一一对应:
| 函数 | 作用 |
|---|---|
Disable() |
禁用颜色渲染(返回旧状态) |
SetOutput(io.Writer) |
自定义着色文本的输出 Writer |
ForceOpenColor() |
强制开启颜色渲染(实现上将级别直接置为 LevelRgb) |
Colors2code(colors ...Color) string |
将颜色转换为 SGR 参数串,如 "32;45;3" |
ClearCode(str string) string |
清除文本中的颜色码 |
ClearTag(s string) string |
清除字符串中所有颜色 HTML 标签 |
IsConsole(w io.Writer) |
判断 w 是否为 stdout/stderr/stdin |
8.1 终端颜色级别自动探测
color 会自动检查当前终端支持的颜色级别(探测逻辑在 vendor/github.com/gookit/color/detect_env.go 及平台文件 detect_nonwin.go、detect_windows.go 中):
// Level is the color level supported by a terminal.
type Level = terminfo.ColorLevel
const (
LevelNo = terminfo.ColorLevelNone // 不支持颜色
Level16 = terminfo.ColorLevelBasic // 基础 3/4-bit 色
Level256 = terminfo.ColorLevelHundreds // 8-bit 色
LevelRgb = terminfo.ColorLevelMillions // 24-bit 真彩色
)
对应查询函数:
func SupportColor() bool— 当前环境是否支持颜色输出;func Support256Color() bool— 是否支持 256 色;func SupportTrueColor() bool— 是否支持真彩色;func TermColorLevel() Level— 获取当前支持的颜色级别。
从源码结构看,color.go 中这些函数只是对包级变量 colorLevel 的比较(colorLevel > LevelNo、> Level16、> Level256),而 colorLevel 在包初始化阶段由 detectTermColorLevel() 确定——Windows 下还会同时得出 needVTP(是否需要启用虚拟终端处理)标记。
8.2 环境变量开关
NO_COLOR:只要非空即禁用颜色渲染。包级变量Enable的初始值就是os.Getenv("NO_COLOR") == ""(vendor/github.com/gookit/color/color.go 第 47 行附近);FORCE_COLOR:配合ForceOpenColor()强制把级别拉到LevelRgb;- 另有开发调试用的
COLOR_DEBUG_MODE=on环境变量,可打开包的 debug 模式记录探测过程中的内部错误(通过InnerErrs()查看)。
九、底层原理:ANSI 转义序列的生成与清理
从 vendor/github.com/gookit/color/color.go 的源码可以看清该库的渲染管道,它对所有 API 形式最终都归约到 SGR(Select Graphic Rendition)转义序列的拼装:
const (
StartSet = "\x1b[" // ESC [
ResetSet = "\x1b[0m" // 复位所有属性
SettingTpl = "\x1b[%sm" // 设置模板
FullColorTpl = "\x1b[%sm%s\x1b[0m" // 完整模板:开色 + 内容 + 复位
CodeSuffix = "[0m"
)
const CodeExpr = `\033\[[\d;?]+m` // 匹配颜色码的正则
核心渲染函数 RenderCode(code string, args ...any) 的逻辑:
- 先把可变参数拼接成消息(针对 1 个、2 个参数的常见路径做了快路径优化,避免
fmt.Sprint开销); - 若
code为空,直接返回原文; - 若
Enable == false(如设置了NO_COLOR)或终端不支持颜色,则调用ClearCode(message)返回纯文本; - 否则返回
StartSet + code + "m" + message + ResetSet,即标准\x1b[<code>m<msg>\x1b[0m结构。
RenderString 还有一个值得注意的细节:如果消息本身包含 ResetSet(例如嵌套了其他着色文本),它会在每处复位序列之后重新追加一次开色序列,保证外层颜色不被内层复位破坏——这对 TUI 中嵌套拼接多个着色片段非常关键。
ClearCode 则是用正则 CodeExpr(编译后的 codeRegex)把 \033[...m 序列整体删除,实现“去色化”。ClearTag 则负责移除 HTML 风格标签本身。
十、Lazygit 如何使用 gookit/color
gookit/color 在 Lazygit 中并非直接面向用户 API,而是作为“主题 → 终端属性”转换链的一环。结合源码可以看到三处典型用法:
10.1 HEX 颜色字符串到 gocui 属性的转换
Lazygit 的主题系统允许用户在配置中写 #RRGGBB 十六进制颜色。pkg/theme/gocui.go 中的 GetGocuiAttribute 就是把字符串键解析为 gocui 渲染属性的入口:
func GetGocuiAttribute(key string) gocui.Attribute {
if utils.IsValidHexValue(key) {
values := color.HEX(key).Values()
return gocui.NewRGBColor(int32(values[0]), int32(values[1]), int32(values[2]))
}
value, present := gocuiColorMap[key]
if present {
return value
}
return gocui.ColorWhite
}
这里正是本文第五节 color.HEX(hex) 接口的真实消费场景:先用 pkg/utils/color.go 中的 IsValidHexValue(仅接受 #RGB 或 #RRGGBB 两种长度)校验,再通过 color.HEX(key).Values() 拿到 [r,g,b] 三值,构造 gocui 的 RGB 颜色;非 HEX 的键(如 "red"、"bold"、"underline")则回落到 gocuiColorMap 中的 16 色与修饰属性。GetGocuiStyle 再把多个属性按位或组合,最终驱动终端渲染。
10.2 主题文本样式与背景色转换
pkg/theme/style.go 的 GetTextStyle 处理 bold、reverse、underline、strikethrough 等修饰键,其余键查 style.ColorMap;查不到时若为合法 HEX 值,则调用 style.NewRGBColor(color.HEX(key, background)) —— 注意第二个参数直接透传给 HEX 的 isBg 变参,即 Lazygit 用 color.HEX 的 isBg ...bool 语义同时生成前景/背景 RGB 颜色。
而 pkg/gui/style/color.go 中的 Color.ToRGB 展示了 16 色到 RGB 的转换路径(对应本文第七节的 basic.RGB() 方法),其中有一段耐人寻味的注释:
if isBg {
// We need to convert bg color to fg color
// This is a gookit/color bug,
// https://github.com/gookit/color/issues/39
return NewRGBColor((*c.basic - 10).RGB())
}
从源码结构看,Lazygit 通过把 16 色基本值减去 10(前景 30–37 区间换算为背景 40–47 区间的对应值)再做 RGB() 转换,规避了 gookit/color 在背景色转换上的一个已知问题——这是第三方库与宿主项目之间典型的“补丁式协作”,也说明 C16/C256/RGB 转换方法在真实项目中被反复依赖。
10.3 用户自定义颜色(customColors)
Lazygit 配置中的 customColors 映射由 pkg/utils/color.go 的 SetCustomColors 处理:
func SetCustomColors(customColors map[string]string) map[string]*style.TextStyle {
return lo.MapValues(customColors, func(c string, key string) *style.TextStyle {
if s, ok := style.ColorMap[c]; ok {
return &s.Foreground
}
value := style.New().SetFg(style.NewRGBColor(color.HEX(c, false)))
return &value
})
}
即:配置值先尝试匹配内置 ColorMap 中的颜色名,匹配不上时按 HEX 值走 color.HEX(c, false) 生成前景 RGB 颜色。这与本文第五节 HEX 构造函数、以及 docs/Config.md 中主题配置部分的能力正好衔接:Lazygit 的彩色主题(提交哈希着色、分支名着色、diff 高亮等)本质上都是把用户配置的颜色字符串经由 gookit/color 的 HEX/RGB API 翻译成终端可渲染的属性。
10.4 去色化:Decolorise 与 ClearCode 的对照
.pkg/utils/color.go 中的 Decolorise(实际路径 pkg/utils/color.go)实现了带缓存的 ANSI 序列剥离:
re := regexp.MustCompile(`\x1B\[([0-9]{1,3}(;[0-9]{1,3})*)?[mGK]`)
linkRe := regexp.MustCompile(`\x1B]8;[^;]*;(.*?)(\x1B.|\x07)`)
它比 gookit/color 的 ClearCode 多覆盖了两类序列:光标/擦除类 SGR([mGK] 后缀)以及 OSC 8 超链接序列(Lazygit 支持终端超链接,见 pkg/gui/style/hyperlink.go 相关渲染)。从源码结构看,ClearCode 正则只匹配 [...m 形式,因此 Lazygit 在需要“纯文本长度”(如计算行宽、存储到历史)的场景选择自己实现一个更宽的去色函数,并用 sync.RWMutex 加 map 做结果缓存以避免重复正则匹配。
十一、小结
- gookit/color 提供“16 色 → 256 色 → 真彩色”三级模型,API 上通过
Color/Color256/RGBColor三个类型与C256、S256、RGB、HEX、HEXStyle等构造函数对齐,且都支持isBg可选参数区分前景/背景; - 其通用 API(
Print*/Sprint*)、语义风格(Info/Warn/Error等)与 HTML 标签渲染,覆盖了从简单 CLI 提示到复杂 TUI 的着色需求,标签属性语法(fg=/bg=/op=)同时兼容 16 色名、256 色值与 RGB/HEX 值; - 渲染管道最终归约为
\x1b[<code>m<msg>\x1b[0m的 SGR 序列拼装,受NO_COLOR/Enable与终端级别探测(TermColorLevel)双重门控; - 在 Lazygit 中,该库主要承担“配置字符串 → 终端属性”的转换职责:
color.HEX解析主题中的 HEX 色值,basic.RGB()完成 16 色到 RGB 的升级,IsValidHexValue把关输入格式,再配合自研的Decolorise处理带超链接序列的去色化——这正是理解 Lazygit 主题系统(pkg/theme)与 gocui 渲染层之间桥梁的关键。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00