WezTerm 配置指南:用 wezterm.format 构建带颜色与属性的终端格式化文本

WezTerm 配置指南:用 wezterm.format 构建带颜色与属性的终端格式化文本 WezTerm 配置指南用 wezterm.format 构建带颜色与属性的终端格式化文本【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/weztermwezterm.format是 WezTermRust 编写的 GPU 加速跨平台终端模拟器内置的 Lua 工具函数用于把“文本 终端图形属性粗体、斜体、下划线、颜色”描述为结构化的FormatItem数组并自动渲染为内嵌 WezTerm 兼容转义序列的字符串。它是定制标签页标题、左右状态栏status bar等 UI 文本的基石 API。读完本文你将掌握wezterm.format的全部FormatItem取值、其背后的转义序列生成原理以及如何与set_right_status、format-tab-title、wezterm.nerdfonts配合实现可落地的状态栏与 Powerline 风格界面。一、wezterm.format是什么wezterm.format自版本20210314-114017-04b7cedd起提供用于生成一段带终端图形属性的格式化字符串。它的输入是一个数组数组的每个元素是一个FormatItem输出是一个字符串其中嵌入了 WezTerm 兼容的 ANSI 转义序列。由于返回的是一段包含转义序列的普通字符串因此它可以被用在任何接受带样式字符串的 API 中例如window:set_right_status —— 标签栏右侧状态区window:set_left_status—— 标签栏左侧状态区format-tab-title 事件 —— 自定义标签页标题该事件支持返回FormatItem表format-window-title事件、wezterm.log_info日志输出等。最简单的示例下面的脚本把Hello以及当前日期时间输出为“紫色文字、蓝色背景、单下划线”并打印到 wezterm 进程的 stderrlocal wezterm require wezterm local success, date, stderr wezterm.run_child_process { date } wezterm.log_info(wezterm.format { { Attribute { Underline Single } }, { Foreground { AnsiColor Fuchsia } }, { Background { Color blue } }, { Text Hello .. date .. }, ResetAttributes, { Text this text has default attributes }, })要点wezterm.format本身只负责把属性与文本转换成转义序列它不会关心属性作用范围之外的文本因此在需要恢复默认样式时应显式加入ResetAttributes。二、FormatItem 全量取值参考FormatItem支持以下元素类型来自 lua-api-crates/termwiz-funcs/src/lib.rs 中FormatItem枚举的实现元素说明{TextHello}输出文本。字符串可以是任意字符串表达式包括wezterm.format本身不直接支持的任意转义序列见下文“直接内嵌转义序列”一节{Attribute{UnderlineNone}}关闭下划线{Attribute{UnderlineSingle}}单下划线{Attribute{UnderlineDouble}}双下划线{Attribute{UnderlineCurly}}波浪形下划线{Attribute{UnderlineDotted}}点状下划线{Attribute{UnderlineDashed}}虚线式下划线{Attribute{IntensityNormal}}常规字重{Attribute{IntensityBold}}粗体字重{Attribute{IntensityHalf}}半亮/半透明字重{Attribute{Italictrue}}开启斜体{Attribute{Italicfalse}}关闭斜体{Foreground{AnsiColorBlack}}前景色设为 ANSI 调色板颜色索引 0–15名称可为Black、Maroon、Green、Olive、Navy、Purple、Teal、Silver、Grey、Red、Lime、Yellow、Blue、Fuchsia、Aqua、White{Foreground{Coloryellow}}前景色设为具名颜色或 RGB 值如#ffffff{Background{AnsiColorBlack}}背景色设为 ANSI 颜色取值同Foreground{Background{Colorblue}}背景色设为具名颜色或 RGB 值取值同ForegroundResetAttributes将所有属性重置为默认值自版本20220807-113146-c2fee766起支持关于 ANSI 颜色与 RGB 颜色从源码FormatColor枚举可见颜色有两种来源AnsiColor直接映射到 termwiz 的AnsiColor枚举生成标准 ANSI SGR 颜色序列Color(String)字符串通过SrgbaTuple::from_str解析。解析失败时源码中的兜底行为是回退为白色(0xff, 0xff, 0xff)见 lua-api-crates/termwiz-funcs/src/lib.rs。因此传入非法颜色名不会导致报错但会产生白色实际配置时建议使用合法的 CSS 颜色名或#rrggbb格式。三、源码级原理FormatItem 如何变成转义序列wezterm.format并不是简单的字符串拼接。查看 lua-api-crates/termwiz-funcs/src/lib.rs 可以还原它的完整调用链每个FormatItem通过FromFormatItem for Change被转换为 termwiz 的Change指令AttributeChange::Foreground、AttributeChange::Background、Change::Text、Change::AllAttributes(...)等见 lib.rsformat_as_escapes会在所有输入元素的末尾自动追加一个Change::AllAttributes(CellAttributes::default())即在字符串结束处隐式恢复默认属性见 lib.rs。这解释了为什么文档示例中即使不加ResetAttributes输出也不会“污染”后续内容随后使用TerminfoRenderer把Change列表渲染到内存缓冲区渲染目标实现了std::io::Write与RenderTty终端尺寸固定为 80×24见 lib.rs渲染所用的能力Capabilities来自仓库内内置的termwiz/data/xterm-256colorterminfo 数据库并强制声明ColorLevel::TrueColor见 lib.rs。也就是说无论终端环境变量如何wezterm.format始终以 xterm-256color TrueColor 的能力输出转义序列从而保证 WezTerm 自身渲染时颜色一致。这意味着你完全可以信任它的输出格式是 WezTerm 自身可识别的且生成过程不依赖外部infocmp等工具。四、直接内嵌任意转义序列{Text...}接受任意字符串因此可以把wezterm.format不原生支持的属性直接以转义序列形式写入。文档给出的典型场景是自定义下划线颜色local wezterm require wezterm wezterm.log_info(wezterm.format { -- turn on underlines { Attribute { Underline Single } }, -- make the underline red { Text \x1b[58:2::255:0:0m }, -- and say hello { Text hello }, })这里的\x1b[58:2::255:0:0m是 SGR 的“下划线颜色”扩展序列子参数语法58:2::R:G:B用于把下划线渲染为纯红色。这类序列会被原样透传进结果字符串从而让wezterm.format在语法上保持可扩展性。五、实战在标签栏状态区显示日期与斜体文本wezterm.format最典型的用途是配合update-right-status事件刷新右侧状态区。在wezterm.lua配置中加入local wezterm require wezterm wezterm.on(update-right-status, function(window, pane) local date wezterm.strftime %Y-%m-%d %H:%M:%S -- Make it italic and underlined window:set_right_status(wezterm.format { { Attribute { Underline Single } }, { Attribute { Italic true } }, { Text Hello .. date }, }) end) return {}效果示意见 docs/screenshots/wezterm-status-date.png。注意set_right_status渲染在标签栏右侧超出宽度时会从左侧裁剪见 window/set_right_status.md。六、实战Powerline 风格的渐变色状态栏将多个FormatItem组合可以构造经典的 Powerline 箭头渐变效果。下面的配置提取当前 pane 的工作目录、主机名、日期与电量并为每个“单元格”交替设置前景/背景色单元格之间用 Powerline 左箭头\u{e0b2}连接wezterm.on(update-right-status, function(window, pane) local cells {} -- 取当前 pane 的 cwd 与主机名远端若开启 OSC 7 也能识别 local cwd_uri pane:get_current_working_dir() if cwd_uri then local cwd local hostname if type(cwd_uri) userdata then cwd cwd_uri.file_path hostname cwd_uri.host or wezterm.hostname() else cwd_uri cwd_uri:sub(8) local slash cwd_uri:find / if slash then hostname cwd_uri:sub(1, slash - 1) cwd cwd_uri:sub(slash):gsub(%%(%x%x), function(ch) return string.char(tonumber(ch, 16)) end) end end local dot hostname:find [.] if dot then hostname hostname:sub(1, dot - 1) end if hostname then hostname wezterm.hostname() end table.insert(cells, cwd) table.insert(cells, hostname) end local date wezterm.strftime %a %b %-d %H:%M table.insert(cells, date) for _, b in ipairs(wezterm.battery_info()) do table.insert(cells, string.format(%.0f%%, b.state_of_charge * 100)) end -- Powerline 符号与其填充变体 local SOLID_LEFT_ARROW utf8.char(0xe0b2) local colors { #3c1361, #52307c, #663a82, #7c5295, #b491c8, } local text_fg #c0c0c0 local elements {} local num_cells 0 local function push(text, is_last) local cell_no num_cells 1 table.insert(elements, { Foreground { Color text_fg } }) table.insert(elements, { Background { Color colors[cell_no] } }) table.insert(elements, { Text .. text .. }) if not is_last then table.insert(elements, { Foreground { Color colors[cell_no 1] } }) table.insert(elements, { Text SOLID_LEFT_ARROW }) end num_cells num_cells 1 end while #cells 0 do local cell table.remove(cells, 1) push(cell, #cells 0) end window:set_right_status(wezterm.format(elements)) end)渲染效果见 docs/screenshots/wezterm-status-powerline.png。核心技巧在于每个单元格的“箭头”前景色使用下一个单元格的背景色从而形成平滑的颜色过渡wezterm.format严格按数组顺序输出转义序列因此前景/背景的先后顺序直接决定视觉结果。七、实战结合 Nerd Fonts 图标WezTerm 内置Nerd Font Symbols Font作为默认字体回退无需打补丁字体即可使用 Nerd Fonts 符号。wezterm.nerdfonts用户数据对象可按符号名解析出具体字形如fa_clock_o代表 Font Awesome 的时钟图标然后交给wezterm.format组合进状态栏local wezterm require wezterm wezterm.on(update-right-status, function(window, pane) -- Wed Mar 3 08:14 local date wezterm.strftime %a %b %-d %H:%M window:set_right_status(wezterm.format { { Text wezterm.nerdfonts.fa_clock_o .. .. date }, }) end)可用的符号名与 Nerd Fonts 版本相关自20230712-072601-f4abf8fd起内置 Nerd Fonts 升级到 3.0Material Design 图标前缀由mdi_改为md_若干符号映射也有调整详见 wezterm/nerdfonts.md 中的完整符号表。在源码层面wezterm.nerdfonts的查找由NerdFonts结构体实现通过termwiz::nerdfonts::NERD_FONTS常量表完成符号名到字形的映射见 lua-api-crates/termwiz-funcs/src/lib.rs。八、实战自定义标签页标题format-tab-title事件返回一个字符串或一个FormatItem表用于定制标签栏中的每个标签。wezterm.format的FormatItem结构与该事件返回值完全一致因此可以复用同一套写法。例如让活动标签显示蓝色背景上一次激活的标签显示绿色背景并追加*function tab_title(tab_info) local title tab_info.tab_title -- 优先使用显式设置的标题否则回退到活动 pane 的标题 if title and #title 0 then return title end return tab_info.active_pane.title end wezterm.on( format-tab-title, function(tab, tabs, panes, config, hover, max_width) local title tab_title(tab) if tab.is_active then return { { Background { Color blue } }, { Text .. title .. }, } end if tab.is_last_active then return { { Background { Color green } }, { Text .. title .. * }, } end return title end )需要注意format-tab-title事件是同步执行的必须尽快返回否则会阻塞 GUI 线程因此不能在事件回调里调用wezterm.run_child_process这类异步函数会报format-tab-title: runtime error: attempt to yield from outside a coroutine。如需完整的复杂示例含max_width截断与 Powerline 箭头边缘样式参考 window-events/format-tab-title.md。九、使用建议与常见误区记得重置属性虽然format_as_escapes会在字符串末尾自动恢复默认属性但如果你在字符串中途需要切回默认样式例如一段彩色文本后面紧跟普通文本应显式使用ResetAttributes或重新声明颜色/字重。颜色字符串要合法Color接受 CSS 具名颜色或#rrggbb非法字符串会被源码兜底解析为白色调试时如果发现颜色“失效”先检查拼写。状态栏有宽度限制set_right_status内容右对齐且从左侧裁剪信息较多时应结合wezterm.truncate_right等工具截断同仓库termwiz-funcs提供了pad_left、pad_right、truncate_left、truncate_right等辅助函数见 lua-api-crates/termwiz-funcs/src/lib.rs。转义序列可自由透传任何wezterm.format不支持的属性都可以通过{Text\x1b[...m}直接嵌入扩展能力不受限制。总结wezterm.format是 WezTerm 配置生态中“结构化成带样式文本”的统一入口它把FormatItem数组通过 termwiz 的Change指令与 xterm-256color/TrueColor 渲染器转换为可靠的转义序列字符串再被状态栏、标签标题、日志输出等消费。掌握Attribute、Foreground、Background、Text、ResetAttributes五种元素配合 Nerd Fonts 与 Powerline 字形即可构建出专业级的终端 UI。【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考