[博客翻译]终端颜色很狡猾


原文地址:https://jvns.ca/blog/2024/10/01/terminal-colours/


终端颜色的挑战

你知道吗?在终端中设置一个自己满意的颜色方案可能需要花费很长时间,因为色彩搭配真是个微妙的艺术。让我们一起探讨一下为什么这如此困难,以及如何解决这些问题。

问题一:蓝色在黑色背景上的阅读问题

许多人抱怨说,蓝色在黑色背景下很难看清。比如,在Terminal.app中,如果把背景设为黑色,运行ls命令,目录会显示为不太明显的蓝色:

3.png

要理解这个问题,我们需要了解ANSI颜色。终端有16种编号的颜色,包括黑、红、绿、黄、蓝等,以及它们的亮色版本。

程序通过打印ANSI转义码来使用这些颜色,比如你可以用下面的Python代码查看所有16种颜色:


def color(num, text): 

    return f"\033[38;5;{num}m{text}\033[0m" 

for i in range(16): 

    print(color(i, f"number {i:02}")) 

问题一又半:亮黄色在白色背景上的问题

亮黄色在白色上比蓝色在黑色上更糟糕,看看默认设置下的效果:

这几乎无法阅读,其他颜色如浅绿色也会造成类似问题。现在我们来看看解决方案!

两种重新配置颜色的方法:

  1. 调整终端模拟器:现代终端模拟器通常允许你自定义颜色,有些甚至预装了主题,可能你会喜欢。

  2. 运行shell脚本:你可以打印ANSI转义码来改变终端的颜色配置,比如base16-shell项目中的脚本。不同终端可能有不同的转义码格式,所以脚本会根据TERM环境变量选择合适的样式。

这两种方法各有优缺点。我倾向于使用shell脚本,因为它跨终端兼容,而且可以方便地让Vim和终端颜色保持一致。

终端颜色配置的优点在于,如果你用的是流行终端,有很多美观的主题可供选择。但也有其局限性,比如颜色选择可能与默认主题冲突。

我自己的终端颜色方案(例如Solarized Light)已经用了好几年,看起来还不错。比如,htop的效果:

当然,找到喜欢的颜色方案后,还有其他问题可能出现:

问题二:支持256色的应用程序

fd这样的工具输出时,颜色对比度可能不佳,比如:

这可能是由于fd使用了扩展的256色集中的颜色。有些新工具(如catdelta)支持自定义主题,虽然这增加了灵活性,但也可能导致默认主题与你的终端背景不协调。

问题三:Solarized主题中的灰色

关于Solarized主题,有人提到灰色的问题。在Base16 Solarized Light主题下,列出目录时:

而iTerm的默认Solarized Light主题则不同:

这是因为iTerm主题中的某些“亮色”被映射成了灰色。原版Solarized的设计可能是为了配合Vim的Solarized颜色方案。

我个人更喜欢修改过的版本,其中“亮色”是真正的颜色,而不是灰色。

问题四:Vim主题与终端背景不匹配

如果Vim主题的背景颜色与终端不一致,就会出现边界问题,如下所示:

这虽是个小问题,但调整终端背景以匹配Vim背景并不难。

问题五:应用程序设置背景颜色

有人提到应用设置了不想要的背景色。比如,ngrok可能会设置背景为#16(黑色),但如果使用了base16-shell脚本,颜色16被设置为亮橙色,导致不协调:

我认为ngrok这样设计是为了给base16-vim提供更多颜色选项。这种情况下,用户偏好可能更重要。

问题六:TERM环境变量设置错误

有些人发现,在远程系统上SSH登录,如果系统的TERM环境变量与本地设置不符,颜色可能无法正常显示。

TERM的工作原理是依赖于终端信息数据库。如果系统中没有对应的终端类型信息,颜色显示就会出问题。解决方法可能包括更改SSH连接方式,如TERM=xterm ssh

问题七:挑选合适的颜色很难

设计或找到合适的终端颜色方案时,人们遇到的问题包括:

  • 对颜色敏感的人难以找到适合的配色

  • 颜色选择可能与程序的默认颜色不协调,比如ngrok的例子

  • 找到与所有程序都兼容的颜色组合不容易

问题八:让nethack/mc等程序看起来正常

一些程序(如nethack或midnight commander)期望有特定的ANSI颜色风格,但在某些主题下可能显得混乱。

解决办法之一是在启动程序前使用定制的ANSI代码调整颜色,比如将黄色映射为更亮的黄色。

问题九:通过管道写入时禁用颜色

当通过管道运行fd | less时,颜色会被禁用:

为查看颜色,可以使用unbuffer fd | less -runbuffer能确保命令写入到真正的TTY,解决管道输出缓冲问题。

问题十:不想让ls等命令使用颜色

有些人不喜欢ls使用颜色,可能因为蓝色在黑色背景下难以阅读,或者他们觉得颜色无用。

解决方法包括设置ls --color=never,或者自定义LS_COLORS环境变量。

问题十一:Vim中的颜色配置

以前,我在Vim中配置颜色时遇到很多麻烦,因为Vim和终端颜色同步是个挑战。现在,Vim和Neovim支持24位颜色,使得颜色配置变得简单。

总结起来,终端颜色的世界充满了细节和挑战。尽管有时让人沮丧,但通过调整像最小对比度这样的设置,我们可以让大多数时候的颜色显示变得更友好。对于我来说,使用像base16这样的工具,配合简单的配置,已经足够满足需求。如果你也想让终端颜色变得更顺眼,不妨试试这些方法。