最近冲浪发现了一个新的 terminal 项目,试用了一下感觉很棒,写篇文章安利一下:
https://github.com/ghostty-org/ghostty
下面这张图来自开发者的博客:
可以去开发者的原始博文中查看他对其中每条项目的说明。
简单来说,作者认为当前主流的 terminal 程序在速度、功能丰富度和平台原生 GUI 三个方面做了不必要的取舍,这三者本应该是可以同时达成的。
I felt that the existing terminal emulators pushed an unnecessary choice between speed, features, and platform-native GUIs.
Ghostty 这个项目便是作者给出的答卷。
快速
Ghostty 和公认极快的 Alacritty 具有相近的性能,处于第一梯队。
功能丰富
支持几乎所有的现代终端规范,内建支持分屏、多 Tab 等功能,此外还包含超多的可配置项。
平台原生的 GUI 体验
和其它主流终端程序对比,Ghostty 使用了更加原生的方式编写应用。不同平台间共享大部分的核心代码,但对于每个平台使用平台原生的 GUI 工具包开发。
具体来说,它在 MacOS 上使用 Swift,在 Linux 上使用 GTK。这允许 Ghostty 更好地利用平台原生功能,如更好的拓展坞集成、输入法支持、桌面通知,甚至 macOS 安全输入模式等。
自从我使用 MacOS 以来,一直在尝试寻找一个快速、可定制性强的终端。
在很长一段时间里,我使用的是大家推荐的 Iterm2,它的体验基本令人满意,可主要问题是太慢了。在我个人的实际体验中,Iterm2 的性能甚至不如 Vscode 的内置终端来得好,在 cat 大文本,甚至快速打字时都能感受到明显的延迟。
正因如此,在寻求切换时我的第一选择便是以性能闻名的 Alacritty:
它的整体体验相当令人满意,可不清楚是配置错误还是程序 bug,日常使用中总有一些让我不舒适的点。
Mac 上比较主流的外观是将交通灯按钮与窗口融合到一起,在 terminal 方面则是标题栏与文本背景同色。这在 Iterm2 有着非常良好的支持,但 Alacritty 则不然。
Alacritty 支持将标题栏配置为透明,这可以实现我上述描述的外观,但奇怪的点在于它对透明标题栏的实现似乎仅仅是在一个无标题栏的窗口上强行安上三个按钮。这意味着:
如果看描述没有画面,可以查看我下面的 GIF:
没办法我只能将标题设置为 buttonless ,并使用 MacOS 中的 cmd + ctrl + 鼠标左键点击窗口任意位置
的方式拖动窗口来规避这些问题。
Alacritty 调整大小时字符会不断抖动,现存文本会逐渐向上移动到窗口外,就像我在不断换行一样,同时会伴有偶发的白色闪烁。
可以查看我的如下 GIF(实际发生了一次闪烁,但似乎录制不出来):
这个我在文章编写过程中没有复现,但发生的次数绝对不少,推测是在 cmd + Q
退出程序后快速重新打开窗口导致的冲突。
正因上述问题,我在看到 Ghostty 后立马萌生了体验的想法。
简单体验后,我并没有发现与 Alacritty 类似的 bug,也没感觉出速度和 Alacritty 有差异。正如作者在 1.0 前瞻中说的那样:
In short, Ghostty 1.0 aims to be the best drop-in replacement for your current terminal emulator on macOS and Linux.
至少对 MacOS 而言,一个性能不输 Alacritty 的原生应用程序确实称得上 “the best drop-in replacement for your current terminal emulator” 了。
哪怕抛开性能不谈,也可以看出 Ghostty 比起 Alacritty 更重视对 MacOS 的支持。不论是单独为 MacOS 适配原生的 Metal API 做渲染,还是使用 Swift 单独编写 MacOS 的 GUI,都能看得出这个项目是将 MacOS 作为第一平台开发的。
因此最终我决定切换过来。Ghostty 的官方文档写得很详细,对照官方文档可以很容易将现有的 Alacritty 外观迁移到 Ghostty。
下面是我的配置成果图与配置项参考。
左边是 Alacritty,右边是 Ghostty,经过配置后主体部分基本看不出任何区别。
font-family = "ZedMono NFM Extd"
font-style-bold = "Medium"
font-style-bold-italic = "Medium Italic"
font-size = 13.4
font-thicken = true
grapheme-width-method = "unicode"
adjust-cell-width = -5%
palette = 0=#212733
palette = 1=#f08778
palette = 2=#53bf97
palette = 3=#fdcc60
palette = 4=#60b8d6
palette = 5=#ec7171
palette = 6=#98e6ca
palette = 7=#fafafa
palette = 8=#686868
palette = 9=#f58c7d
palette = 10=#58c49c
palette = 11=#ffd165
palette = 12=#65bddb
palette = 13=#f17676
palette = 14=#9debcf
palette = 15=#ffffff
background = #1f2430
foreground = #cbccc6
selection-invert-fg-bg = true
cursor-style = "bar"
cursor-style-blink = true
scrollback-limit = 100000
window-padding-x = 20
window-padding-y = 2,10
window-save-state = "always"