你有没有试过 Powerlevel10k 这样的终端主题、Starship 这样的命令行提示工具,或者在终端里使用 Nerd Font 之类的字体? 如果用过,你可能会发现,不管用哪一种,图标字体的显示体验总有些不尽如人意。
图标字体有什么问题?
先模拟一下图标在终端中显示时的样子(情况 1):
甚至还可能更糟(情况 2):
有些图标是不是看起来太小了?尤其是 Go 的图标。
而你期待的可能是这样(情况 3):
这是因为大多数图标字体都把图标放进了一个正方形的 viewbox 里。那么,为什么还会出现「更糟」的情况呢?
答案在于终端模拟器对字符的渲染方式。这类图标字体中的字符,通常会被归为 ambiguous characters,也就是宽度不明确的字符。
有些字符,例如部分希腊字母和亚洲文字,在终端窗口中既可以占一个单元格,也可以占两个单元格。 这类字符通常被称为宽度不明确的字符。 默认情况下,终端会以窄字符显示它们,这样在 ASCII 艺术等对排版要求严格的场景里效果更好。 你可以在配置偏好中把它们设为宽字符,这在阅读连续文本时可能更合适。 (来源:GNOME 帮助:字符看起来太窄)
有些终端模拟器支持调整这类字符的宽度。 比如,iTerm2 就有一个「ambiguous characters are double-width」选项,用来调整字体的渲染方式。
情况 1 是按双宽字符显示的效果,而 情况 2 则把图标当成了普通 ASCII 字符。
能不能像 情况 3 那样显示图标?
可以,但也不完全可以。要实现这样的效果,首先需要一套制作方式正确的字体,让图标不再受限于正方形的 viewbox。
我在 simple-icons/simple-icons-font#211 里做了一套预览字体,让所有图标在相同字号下具有一致的高度。
如果试用这套字体,你会发现几乎所有终端模拟器都无法正确显示它。 这是因为修改图标的 viewbox 后,字符宽度就不再固定,而终端模拟器无法自动判断它的宽度,只支持用普通字符宽度或双宽来渲染。
那为什么又说可以呢?答案是 Inline Images Protocol。 我们可以使用 imgcat 工具,直接在终端里显示图片。 你可能还需要 Simple Icons CDN,来获取可以调整颜色和尺寸的图标。
下面是一个例子:
![]()
其中,viewbox=auto 用来把正方形 viewbox 改为高度一致的 viewbox,size 则用于控制渲染尺寸。
不过,这还算不上在终端中渲染图标的解决方案。因为 imgcat -u 会向远程服务器发送 HTTP 请求,下载图标后才能显示,性能并不适合终端提示符。 我在几个终端社区里发起过相关讨论,也欢迎你去分享想法:
- Starship:添加对 Simple Icons 的支持(starship/starship#6216)
- Warp:Warp 的后备字体(warpdotdev/Warp#789#issuecomment-2351406819)
- WezTerm:重新考虑为 imgcat 提供 SVG 支持(wez/wezterm#6042)
- WezTerm:一种全新的图标字体方案(wez/wezterm/discussions#643)
对终端未来的期待
我准备学习一些终端相关的知识,试着深入了解它的原理和开发。 当然,社区的发展也需要大家积极参与讨论和反馈。
也许有一天,我们就能在终端里用上这样的行内字体图标:
。