eza 颜色与主题定制完全指南:EZA_COLORS 环境变量与 theme.yml 详解
【免费下载链接】ezaA modern alternative to ls项目地址: https://gitcode.com/gh_mirrors/ez/eza
eza(现代版ls)在终端输出中对文件名、权限位、大小、日期、Git 状态等几乎每个元素都提供了细粒度的配色能力。本文以官方 man 手册 man/eza_colors-explanation.5.md 为骨架,结合仓库源码(src/theme/、src/options/config.rs、src/info/filetype.rs)深入讲解两层定制体系:通过EZA_COLORS/LS_COLORS环境变量快速覆盖颜色,以及通过theme.yml配置文件声明式定义完整主题。读完本文,你将掌握颜色代码的语法、内置扩展映射的覆盖机制,以及如何写出可复现、可分享的个性化主题文件。
一、定制颜色的两种入口
eza 的配色定制分为两个层次:
- 环境变量层(
EZA_COLORS/LS_COLORS/ 旧名EXA_COLORS):适合临时覆盖、单点微调,例如“把 zip 文件变绿”“把日期列变绿”; - 配置文件层(
theme.yml):适合系统性的主题声明,通过EZA_CONFIG_DIR或$XDG_CONFIG_HOME/eza/theme.yml加载,支持图标、前景/背景色、加粗、斜体等完整样式属性。
两者可以叠加使用:配置文件(ThemeConfig)解析得到基础UiStyles后,环境变量中的映射会继续覆盖其上。这一点在 src/theme/mod.rs 的to_theme()中体现:先加载theme_config得到 UI 样式,再调用parse_color_vars解析环境变量对样式进行二次修改,最后把 glob 映射与内置FileTypes组合成FileStyle链。
二、环境变量语法:键值对、分隔符与 glob
EZA_COLORS的语法结构(详见 man/eza_colors.5.md):
- 键值对之间用
=连接,例如*.txt=32; - 同一键的多个 ANSI 格式码用
;连接,例如*.txt=32;1;4(绿色加粗加下划线); - 多组键值对之间用
:分隔,例如*.txt=32:*.mp3=1;35。
键可以是两位字母代码(如da表示日期、uu表示当前用户),也可以是文件 glob(如*.zip、Vagrantfile)。任何不是合法两位代码的键都会被当作 glob 处理——即使它恰好也是两位字母。从源码 src/theme/lsc.rs 可以看到,LSColors::each_pair按:切分、再按=切分(最多取三段),只有“键和值都非空”的项才被接受;随后 src/theme/mod.rs 的parse_color_vars先尝试用set_ls/set_exa匹配两位代码,匹配失败才交给glob::Pattern作为文件映射。
需要注意的是:
EXA_COLORS向后兼容:当EZA_COLORS未设置时,eza 会回退检查EXA_COLORS(man/eza_colors.5.md);EXA_COLORS覆盖LS_COLORS:EZA_COLORS中给出的值会覆盖LS_COLORS中的同名项,因此无需重写整套LS_COLORS就能扩展它;- 样式值必须合法:与某些
ls实现不同,eza 会严格校验 ANSI 码,不会原样输出任意字符。lsc.rs的to_style()只识别1(bold)、2(dimmed)、3(italic)、4(underline)、5(blink)、7(reverse)、8(hidden)、9(strikethrough)、标准 16 色(30–37、90–97)、256 色38;5;nnn、真彩 RGB38;2;r;g;b,以及对应的背景色40–47、100–107、48;5;nnn、48;2;r;g;b,其余一律忽略。
三、经典用法示例
以下示例均来自官方 man 文档,可直接复制使用:
| 目标 | 命令 |
|---|---|
| 关闭“当前用户”高亮 | EZA_COLORS="uu=0:gu=0" |
| 日期列变绿 | EZA_COLORS="da=32" |
| 高亮 Vagrantfile | EZA_COLORS="Vagrantfile=1;4;33" |
| 覆盖 zip 默认颜色(256 色) | EZA_COLORS="*.zip=38;5;125" |
| Markdown 偏绿、日志偏灰 | EZA_COLORS="*.md=38;5;121:*.log=38;5;248" |
覆盖与重置内置扩展映射
eza 内置了一套覆盖常见扩展名的颜色映射(文档、压缩包、媒体、临时文件等)。环境变量中的任何映射都会覆盖内置默认值:例如LS_COLORS="*.zip=32"只会把 zip 文件变绿,其他压缩文件的颜色保持不变。
若想彻底禁用内置映射,可在EZA_COLORS开头放一个reset条目:
EZA_COLORS="reset:*.txt=31":只高亮文本文件;EZA_COLORS="reset":什么都不高亮。
源码实现上,parse_color_vars检测到exa值为"reset"或以"reset:"开头时,会将use_default_filetypes置为false(src/theme/mod.rs);随后to_theme()依据“自定义映射是否为空 + 是否使用内置映射”两个布尔量,组合出四种FileStyle:仅内置、仅自定义、两者叠加(自定义优先)、全部关闭(src/theme/mod.rs)。
glob 映射的匹配顺序
自定义 glob 从后往前匹配,即后定义的条目优先级更高(src/theme/mod.rs)。同时,简单的*.ext形式会进入哈希表以提升复杂LS_COLORS场景下的匹配性能,复杂模式(含? * [ ] .等)则走 glob 匹配,二者行为保持一致。这一点也被 src/theme/mod.rs 的单元测试覆盖,例如"pi=31:pi=32:pi=33"最终生效的是黄色33。
四、内置扩展类型与默认配色
eza 将常见文件归为若干语义类型,每种类型有独立的默认样式。官方说明如下(对应 src/info/filetype.rs 与 src/theme/default_theme.rs 的实现):
| 类型 | 示例扩展/文件名 | 默认样式 |
|---|---|---|
| Build(构建文件) | Makefile、Cargo.toml、package.json | 黄色加粗加下划线 |
| Image(图片) | png、jpeg、gif | 紫色 |
| Video(视频) | mp4、ogv、m2ts | 更深的紫色(加粗) |
| Music(有损音乐) | mp3、m4a、ogg | 淡蓝色 |
| Lossless(无损音乐) | flac、alac、wav | 稍亮的蓝色(加粗) |
| Crypto(加密相关) | asc、enc、p12 | 亮绿色(加粗) |
| Document(文档) | pdf、doc、dvi | 更淡的绿色 |
| Compressed(压缩文件) | zip、tgz、Z | 红色 |
| Temp(临时文件) | tmp、swp、~ | 默认前景色变暗(dimmed) |
| Compiled(编译产物) | class、o、pyc | 黄色 |
| Source(源码) | cpp、js、java | 亮黄色(加粗) |
Compiled 的智能判定:除了“常见扩展名”外,eza 还会把一个文件判为编译产物——如果它使用常见扩展名、且与其某个源文件位于同一目录。例如styles.css旁边存在styles.less/styles.sass时,或scripts.js旁边存在scripts.ts/scripts.coffee时。对应逻辑见 src/info/filetype.rs:文件以~结尾或#...#包裹判为 Temp,再依次查文件名表、扩展名表,最后检查是否与源文件同目录。
值得一提的是,eza 支持亮色系(bright colours):在EZA_COLORS中可直接使用90–97的亮色代码(90深灰、91亮红、92亮绿、93亮黄、94亮蓝、95亮紫、96亮青、97亮白),大多数现代 256 色终端都支持。
五、两位代码速查表
LS_COLORS 兼容的十个代码
di目录、ex可执行文件、fi普通文件、pi命名管道、so套接字、bd块设备、cd字符设备、ln符号链接、or无目标的符号链接。这些由set_ls处理(src/theme/ui_styles.rs)。
EZA_COLORS 扩展代码
权限位:oc(八进制权限)、ur/uw/ux/ue、gr/gw/gx、tr/tw/tx、su/sf、xa(扩展属性指示符)。
大小:sn(一次设置nb nk nm ng nt五个数字样式)、sb(一次设置ub uk um ug ut五个单位样式)、nb/nk/nm/ng/nt按 B/KB/MB/GB/TB 分级的数字颜色、ub/uk/um/ug/ut对应的单位颜色、df/ds设备主/次 ID。
用户与组:uu(你自己)、uR(root)、un(其他人)、gu(你所在的组)、gR(与 root 相关的组)、gn(你不在的组)。
链接:lc(硬链接数)、lm(至少两个硬链接的普通文件的链接数)。
Git:ga(新增)、gm(修改)、gd(删除)、gv(重命名)、gt(元数据变更)、gi(忽略)、gc(冲突)。
Git 仓库状态:Gm(主分支)、Go(其他分支)、Gc(干净)、Gd(脏)。
UI 元素:xx(标点/背景 UI)、da(日期)、in(inode)、bl(块数)、hd(表头)、lp(符号链接路径)、cc(文件名中的转义字符)、bO(损坏符号链接路径的覆盖样式)、sp(特殊文件)、mp(挂载点)、oc(八进制)。
文件类型:im(图片)、vi(视频)、mu(有损音乐)、lo(无损音乐)、cr(加密)、do(文档)、co(压缩)、tm(临时)、cm(编译产物)、bu(构建文件)、sc(源码)、ic(图标,未设置时与文件名同色)。
SELinux 安全上下文:Sn(无上下文)、Su(SELinux user)、Sr(role)、St(type)、Sl(level)。
BSD 文件标志:ff。
以上完整对应关系可在 src/theme/ui_styles.rs 的set_exa中逐一查到,并且每一条都有对应单元测试验证(src/theme/mod.rs),例如exa_uu: ls "", exa "uu=38;5;117"断言user_you被设置为Fixed(117)。
六、theme.yml:声明式主题配置文件
从 man/eza_colors-explanation.5.md 可知,eza 支持通过theme.yml文件一次性声明上述所有样式及更多属性。
配置文件查找路径
- 设置
EZA_CONFIG_DIR指定 eza 查找theme.yml的目录; - 否则查找
$XDG_CONFIG_HOME/eza/theme.yml; - 文件名必须为
theme.yml,无论你指定哪个目录。
源码层面,默认路径由dirs::config_dir()拼接eza/theme.yml生成(src/options/config.rs),加载解析在ThemeConfig::to_theme()中完成:打开文件并用serde_norway(YAML)反序列化为UiStylesOverride,再与默认UiStyles做“覆盖式”合并——未声明的字段保留默认值,声明的字段替换默认值(src/options/config.rs、src/options/config.rs)。
可用字段总览
filekinds: normal directory symlink pipe block_device char_device socket special executable mount_point perms: user_read user_write user_execute_file user_execute_other group_read group_write group_execute other_read other_write other_execute special_user_file special_other attribute size: major minor number_byte number_kilo number_mega number_giga number_huge unit_byte unit_kilo unit_mega unit_giga unit_huge users: user_you user_root user_other group_yours group_other group_root links: normal multi_link_file git: new modified deleted renamed ignored conflicted git_repo: branch_main branch_other git_clean git_dirty security_context: none: selinux: colon user role typ range file_type: image video music crypto document compressed temp compiled build source punctuation: date: inode: blocks: header: octal: flags: control_char: broken_symlink: broken_path_overlay:每个字段可用的样式属性
每个字段/子字段下都可以定义以下样式属性:
foreground: Blue background: null is_bold: false is_dimmed: false is_italic: false is_underline: false is_blink: false is_reverse: false is_hidden: false is_strikethrough: true prefix_with_reset: false颜色取值:除Blue、Red、Green等命名色外,还支持#rrggbb十六进制(如#ff00ff)、#rgb缩写、0–255 的 256 色编号(如125)、以及default/none。解析函数color_from_str(src/options/config.rs)对十六进制支持#ff00ff与#f0f两种形式,数字字符串直接映射为Fixed(n),并有对应的单元测试(src/options/config.rs)。
布尔属性别名:fg/bg可分别作为foreground/background的别名,bold/dimmed/italic/underline/blink/reverse/hidden/strikethrough/prefix_reset分别是各is_*字段的别名(src/options/config.rs)。
完整示例
file_type: image: foreground: Blue is_italic: true date: foreground: White security_context: selinux: role: is_hidden: true自定义图标
filenames和extensions字段还可以定制图标(icon glyph)及其颜色:
filenames: # 只改图标字形 Cargo.toml: {icon: {glyph: 🦀}} Cargo.lock: {icon: {glyph: 🦀}} extensions: rs: { filename: {foreground: Red}, icon: {glyph: 🦀}}仓库自带的示例配置 docs/theme.yml 展示了更完整的用法:不仅改了Cargo.toml/Cargo.lock的图标为 🦀,还把rs扩展名的文件名改为红色并配 🦀 图标,同时为nix扩展名配置了 ❄ 图标和白色样式。
实现层面,图标与文件名样式由FileNameStyle { icon: Option<IconStyle>, filename: Option<Style> }描述(src/theme/ui_styles.rs),IconStyle包含glyph: Option<char>与style: Option<Style>;在style_override中按“文件名精确匹配 → 扩展名匹配”的顺序查找覆盖(src/theme/mod.rs)。
使用 theme.yml 的注意事项
- 并非所有字形都支持改颜色:某些 Unicode 图标无法着色,此时颜色属性不生效;
- 语法错误影响面大:如果主题没有生效,请先仔细检查 YAML 语法——一个语法问题可能导致多个属性同时失效;
- 文件名必须固定为
theme.yml,与所选目录无关。
七、颜色输出的启用条件
最后需要说明颜色在什么情况下会真正输出。UseColours有三种模式(src/theme/mod.rs):
Always:即使输出不指向终端也显示颜色;Automatic(默认):仅当 stdout 是终端时显示,输出到管道时关闭(避免干扰grep、more等程序);Never:即使输出到终端也不显示。
to_theme()会在Never或Automatic且非 TTY 时退化为纯色输出(UiStyles::plain()+NoFileStyle),Windows 旧版控制台无法启用 ANSI 时也会自动降级(src/theme/mod.rs)。因此在管道、脚本或 CI 环境中,颜色定制不会污染文本输出。
八、进一步阅读
- man/eza_colors.5.md:
EZA_COLORS两位代码、ANSI 样式码的完整权威清单; - src/theme/default_theme.rs:内置默认主题的完整颜色定义;
- src/theme/ui_styles.rs:
UiStyles数据结构与set_ls/set_exa全部代码映射; - src/theme/lsc.rs:LS_COLORS 字符串解析与 ANSI 码→样式转换;
- src/options/config.rs:
theme.yml反序列化与覆盖合并逻辑; - src/info/filetype.rs:Build/Source/Compiled/Temp 等文件类型判定表;
- docs/theme.yml:官方示例主题文件。
【免费下载链接】ezaA modern alternative to ls项目地址: https://gitcode.com/gh_mirrors/ez/eza
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考