修复 Gnome terminal 里 Solarized Dark 配色看不到临时文件的问题
在 gnome terminal 里用 solarized dark 配色,一直有个问题,就是 ls 列出 .tmp 结尾的临时文件时,文字颜色和背景色是一样的,根本看不到。最近花了点时间排查,终于通过手动改调色板解决了这个问题。

在 gnome terminal 里用 solarized dark 配色,一直有个问题,就是 ls 列出 .tmp 结尾的临时文件时,文字颜色和背景色是一样的,根本看不到。由于从 ls 输出到终端显示出颜色这个路径里有太多组件和配置要排查,这个问题又影响不大,我就一直放着没管。最近终于决定要解决这个问题了。

终端控制色彩显示的原理

CLI 应用通过 ANSI escape code1 来控制终端的行为。这个可以理解为类似 HTML 中的各种 <foo>bar</foo> 标记。其中,大部分复杂的功能都是通过 CSI2 来使用的。 CSI 里面,Select Graphic Rendition (SGR) 序列,用来控制显示格式。

CSI 就是 ESC 字符后面接 [ 字符,后面再接各种命令和参数。用转义写法就是 \033[<cmd_and_args>. SGR 是 <CSI><args>m, 写成转义序列就是 \033[<args>m. 控制终端输出的字符格式,就通过在这里指定不同的 <args> 来实现。可以控制的功能包括加粗、闪烁、下划线,以及字符颜色,背景颜色等。

其中, <CSI>0m, 即 \033[0m 是恢复基本格式。所以在终端应用里常见的用法,就是 \033[<args>m\033[0m 包住一段需要改变格式的问题,就像一对 HTML 标记一样。

问题排查

那现在可以开始来排查是谁把临时文件的颜色设置成和背景色一样了。首先我怀疑的是 oh-my-zsh 的主题。根据 man ls 的说明, ls 是根据环境变量 ‵LS_COLORS来确定各种类型文件的显示颜色的,那就在.oh-my-zsh目录里 grep 各种LS_COLORS, tmp 之类的关键字,没有发现。man ls里又说LS_COLORS一般用dircolors` 命令来生成,但这个也没 grep 到。那就要怀疑是不是默认的配置就有问题了。

执行一下 dircolors -b 命令,可以看到输出和我的 env 里的内容一致,都有 *.tmp=00;90 这一段。那就 ls 这边都是默认的配置,没有问题。出问题的地方是在终端模拟器那边了。自己用命令 printf 'Normal text. \033[90mInvisible text\033[0m.\n' 试一下,也能复现同样的问题。

维基百科上的色表, 90 对应的是 16 色(也就是 4 bit 颜色)里面的第 9 个颜色,亮灰色。看来这个颜色被设置成和背景色一样了。看一下 gnome terminal 的 solarized 调色板,这第 9 个颜色正好就是和背景色一样啊。

gnome-terminal-solarized-palette

试着改了一下这个颜色,之前 print 出来的 Invisible text 就可以看到了。

那看来这个锅要 gnome terminal 背了?

找了一下 gnome terminal 的数据文件和 gconf 配置,都没有找到相关配置,看来这些内置调色板是写在源码里了。找了一下源码,发现在这里: https://github.com/GNOME/gnome-terminal/blob/d092dc2af7fb29b38a2962ece8cb377a0cd50f07/src/terminal-profile-editor.cc#L298.

调色板里的这个颜色和背景色都被设置成了 solarized 里的 base03. 继续去看 solarized3定义,发现它只定义了 8 种不同深浅的灰色,和 8 种 accent colors. 看来 gnome terminal 的 16 色调色板是自己扩展的?

继续去找 gnome termianl 的 bug reports, 发现这个 9 年前的 report. 里面说问题是 solarized 上游 的。最后发现 solarized 上游在给 xterm 定义调色板的时候就出问题了: https://github.com/altercation/solarized/blob/62f656a02f93c5190a8753159e34b385588d5ff3/xresources/solarized#L64.

看来这个问题的根源是 solarized 设计的时候只定义了 8 种 accent color, 但终端需要 16 色调色板,扩展的时候就出了问题。 Solarized 上游基本上已经是放弃维护了, gnome terminal 也不愿意管这个事情,只能自己改一下配置来解决问题了。

修复

按照 gnome terminal 的 bug report 里的建议,自己把调色板里的那个颜色调亮一点。可以用这个网站: https://colorizer.org, 把调色板里原来的 sRGB 色彩值 #002B36 转换为 Lab, 再把 L 分量调高。最后我转成了 #274C57,一个色调和背景色相同,亮度稍微高一点的色彩。


  1. https://en.wikipedia.org/wiki/ANSI_escape_code ↩︎

  2. https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands ↩︎

  3. https://ethanschoonover.com/solarized/ ↩︎


最后修改于 2024-11-03