WezTerm Lua API 深度解析:wezterm.color.gradient颜色渐变采样实战
【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm
wezterm.color.gradient是 WezTerm 内置 Lua API 中的颜色工具函数,用于根据一份渐变规格(gradient spec)与目标颜色数量,返回在渐变范围内均匀采样的一组颜色。该函数常被用来为 Tab 标题、状态栏或按时间动态插值的场景生成配色,是与window_background_gradient共享同一套渐变语法、却又独立面向"程序化取色"的核心工具。读完本文,你将掌握该函数的完整参数模型、返回值类型,以及将其落地到 Tab 配色与时间驱动配色等真实配置中的完整方案。
函数签名与核心用途
wezterm.color.gradient自 WezTerm 版本20220807-113146-c2fee766起提供,定义于 gradient.md:
wezterm.color.gradient(gradient, num_colors)gradient:一个渐变规格(Lua 表),其合法取值与window_background_gradient配置项完全一致,详见 window_background_gradient.md;num_colors:期望返回的颜色数量;- 返回值:一个包含
num_colors个元素的 Lua 数组,各元素均匀分布在渐变范围内,且每个元素都是一个 Color 对象,而非纯字符串。
文档给出了一个直观示例,即打开调试覆盖层 REPL 后直接执行:
> wezterm.color.gradient({preset="Rainbow"}, 4) ["#6e40aa", "#ff8c38", "#5dea8d", "#6e40aa"]可见传入Rainbow预设并请求 4 个颜色时,得到的是首尾相接的 4 个十六进制色值(Rainbow为循环渐变,故起点与终点同色)。该函数官方用途说明是:例如为 Tab 生成一组颜色,或实现"按一天中的时间在渐变上插值"这类有趣的效果。
参数详解:一份完整的渐变规格
gradient参数支持两种描述方式:使用预置预设(preset)或显式给出颜色列表(colors),二者选其一,再配合若干可选的插值参数。
方式一:colors 颜色列表
直接给出将被插值的一组颜色,接受 CSS 风格的颜色写法(命名颜色、rgb字符串等):
local colors = wezterm.color.gradient({ colors = { '#0f0c29', '#302b63', '#24243e', }, }, 5)方式二:preset 预设
若给出preset字段,则忽略colors。WezTerm 通过colorgradcrate 提供了 39 种内置预设,全部可枚举于 config/src/background.rs 中的 GradientPreset 枚举:
Blues、BrBg、BuGn、BuPu、Cividis、Cool、CubeHelixDefault、GnBu、Greens、Greys、Inferno、Magma、OrRd、Oranges、PiYg、Plasma、PrGn、PuBu、PuBuGn、PuOr、PuRd、Purples、Rainbow、RdBu、RdGy、RdPu、RdYlBu、RdYlGn、Reds、Sinebow、Spectral、Turbo、Viridis、Warm、YlGn、YlGnBu、YlOrBr、YlOrRd
这些名称大小写敏感,均以 PascalCase 拼写,例如preset = "Viridis"。
可选插值参数
以下参数与window_background_gradient完全同源,官方参数说明同样适用于本函数:
| 参数 | 取值 | 默认值 | 说明 |
|---|---|---|---|
interpolation | "Linear"、"Basis"、"CatmullRom" | "Linear" | 插值方式,Basis与CatmullRom会带来更平滑的曲线过渡 |
blend | "Rgb"、"LinearRgb"、"Hsv"、"Oklab" | "Rgb" | 颜色混合的色彩空间,Oklab能提供更符合人眼感知的过渡 |
segment_size | 整数 | 无 | 将渐变划分为若干"段",用于制造阶梯式色带效果 |
segment_smoothness | 浮点数 | 无 | 段边缘硬度,0.0为硬边,1.0为柔和边缘 |
需要特别指出的是:segment_size与segment_smoothness必须同时指定或同时省略,这与底层 Gradient::build() 中的校验逻辑一致——只给其一会在运行时直接报错 "Gradient must either specify both segment_size and segment_smoothness, or neither"。
一个带分段效果的完整示例:
local colors = wezterm.color.gradient({ colors = { '#EEBD89', '#D13ABD' }, interpolation = 'CatmullRom', blend = 'Oklab', segment_size = 11, segment_smoothness = 0.0, }, 8)关于 orientation 与 noise 的说明
window_background_gradient中还存在orientation(水平/垂直/线性角度/径向)与noise(抗色带抖动)两个参数。但从源码看,Gradient::build() 在构建colorgrad渐变时只读取了 preset、colors、blend、interpolation 与分段参数;orientation与noise是渲染窗口背景时才会消费的字段。因此对wezterm.color.gradient而言,它们不会影响采样结果——这点可以放心,采样输出只取决于颜色序列与插值/混合/分段参数。
返回值:Color 对象数组
函数的每个返回值都是 WezTerm 的 Color 对象(内部以 SRGBA 存储),这意味着可以直接调用 Color 对象的方法做二次加工。其底层类型为lua-api-crates/color-funcs中的ColorWrap,可用的常用方法包括(见 lib.rs):
:lighten(factor)/:darken(factor):按比例调整亮度,factor为正浮点数;:saturate(factor)/:desaturate(factor):调整饱和度;:adjust_hue_fixed(amount):按给定量调整色相;:hsla():返回(h, s, l, a)元组;:srgba_u8()、:linear_rgba()、:laba():返回各色彩空间的通道值;- 直接
tostring(color)(或在表中直接展示)会得到形如#6e40aa的十六进制字符串,这正是 REPL 中看到的结果。
例如取渐变采样后再统一提亮:
local base = wezterm.color.gradient({ preset = 'Inferno' }, 5) local bright = {} for i, c in ipairs(base) do bright[i] = c:lighten(0.1) end在调试覆盖层 REPL 中快速试验
调试覆盖层是 WezTerm 内建的一个"日志 + Lua REPL"混合面板,是试验wezterm.color.gradient最快捷的途径。默认绑定为CTRL-SHIFT-l(可通过ShowDebugOverlay动作重新绑定):
config.keys = { { key = 'L', mods = 'CTRL', action = wezterm.action.ShowDebugOverlay }, }打开后 REPL 已预导入wezterm模块,可以直接输入:
> wezterm.color.gradient({colors={'red', 'blue'}}, 3) ["#ff0000", "#7f007f", "#0000ff"]REPL 环境与配置的全局状态相互独立,适合先验证参数组合与采样效果,再把验证通过的代码搬回wezterm.lua。
实战一:为 Tab 生成一组配色
官方文档明确指出该函数的典型场景之一是"为 tabs 生成颜色"。结合 Tab 标题格式化(format-tab-title),可以实现每个 Tab 按索引依次取色:
local colors = wezterm.color.gradient({ preset = 'Turbo' }, 8) wezterm.on('format-tab-title', function(tab, tabs, panes, config, hover, max_width) local index = tab.tab_index or 0 local color = colors[(index % #colors) + 1] return { { Background = { Color = color } }, { Text = ' ' .. tab.active_pane.title .. ' ' }, } end)这里用% #colors做循环取色,使 Tab 数量超过采样数时也能平滑回绕。
实战二:按一天中的时间动态插值
官方文档设想的"根据一天中的时间在渐变上插值"效果,可以借助os.date把当前时刻映射到[0, 1],再换算为采样下标。由于wezterm.color.gradient的采样点均匀分布,时间比例乘以上限即可命中对应颜色:
local function color_for_now() local hour = tonumber(os.date('%H')) or 12 local minute = tonumber(os.date('%M')) or 0 local t = (hour + minute / 60) / 24 -- 0.0 ~ 1.0 映射到一天 -- 采样一个足够大的数量,近似连续渐变 local samples = wezterm.color.gradient({ preset = 'Sinebow' }, 24) local idx = math.max(1, math.min(24, math.floor(t * 24) + 1)) return samples[idx] end若希望输出更平滑,也可以取两个相邻采样点之间再做一次线性插值(配合 Color 对象的通道访问方法),这里不再展开。
底层实现:从 Lua 到 colorgrad 的调用链
从源码可以完整还原该函数在 Rust 侧的实现路径:
- Lua 绑定注册:在 lua-api-crates/color-funcs/src/lib.rs#L169-L171 中,
gradient_colors函数被同时注册为两个入口——模块级别名wezterm.gradient_colors与命名空间wezterm.color.gradient; - 参数接收:实现函数接收
(Gradient, usize)二元组(lib.rs#L191-L194),其中Gradient正是 config/src/background.rs#L432-L457 中与窗口背景共享的结构体; - 构建渐变:调用
gradient.build(),其内部逻辑为——若有preset则直接映射到colorgrad预设函数;否则用CustomGradient::new()装配colors、blend与interpolation(background.rs#L461-L481); - 均匀采样:调用
g.colors(num_colors)获得等间距采样点,再逐一转为ColorWrap(即 Lua 侧看到的 Color 对象)后作为数组返回。
这意味着wezterm.color.gradient与window_background_gradient底层使用完全相同的渐变引擎,只是前者把采样结果以颜色数组的形式交还给 Lua 脚本,后者则将渐变渲染为窗口背景位图。
旧 API 演进:从wezterm.gradient_colors到wezterm.color.gradient
自20220807-113146-c2fee766起,原函数wezterm.gradient_colors(自20210814-124438-54e29167引入)已迁移至wezterm.color.gradient,官方明确建议使用新名称,见 gradient_colors.md。迁移带来两点变化:
- 函数入口从
wezterm.gradient_colors改为wezterm.color.gradient; - 返回值从纯字符串升级为 Color 对象,因而可以直接调用
:lighten、:saturate等方法。
旧名称目前仍可用(Rust 侧保留了wezterm.gradient_colors的注册),但新配置应统一使用wezterm.color.gradient,以便获得对象化的返回值与后续演进支持。
小结
wezterm.color.gradient是 WezTerm Lua 配置体系中"以编程方式生成调色板"的入口:它复用window_background_gradient的完整渐变规格(colors/preset、interpolation、blend、segment),返回均匀采样且对象化的 Color 数组。结合调试覆盖层 REPL 可以快速验证参数效果,再落地到 Tab 标题、时间驱动配色等自定义场景中。若要进一步了解其姊妹能力,可继续阅读 window_background_gradient.md 中关于线性/径向方向与noise的渲染细节,以及 wezterm.color 模块 下的parse、from_hsla、get_default_colors等配套 API。
【免费下载链接】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),仅供参考