你好!最近我做了一个终端使用调查,询问大家哪些方面让他们感到困扰。有人评论说:
现代终端体验涉及太多零碎的东西了。真希望开箱就能拥有这一切。
我的第一反应是“哦,获得现代终端体验没那么难,你只需要……”,但越想下去,这个“你只需要……”的清单就越长,而且我不断想到越来越多的注意事项。
所以我想写下一些笔记,谈谈对我来说“现代”终端体验意味着什么,以及我认为是什么让用户难以实现这一目标。
什么是“现代终端体验”?
以下是一些对我很重要的方面,以及系统中负责它们的部分:
- 多行复制粘贴支持:如果你在 shell 中粘贴 3 条命令,它不应该立即全部执行!这太吓人了!(shell、终端模拟器)
- 无限 shell 历史记录:如果我在 shell 中运行了一条命令,它应该永久保存,而不是在 500 条历史记录后就被删除。另外,我希望命令在运行时就立即保存到历史记录中,而不是在退出 shell 会话时才保存(shell)
- 实用的提示符:没有当前目录和当前 git 分支的提示符我无法忍受(shell)
- 24 位真彩色:这对我很重要,因为相比只有 256 色的终端,在支持 24 位真彩色的终端中配置 neovim 主题要容易得多(终端模拟器)
- 剪贴板集成:vim 与操作系统之间的剪贴板集成,这样当我在 Firefox 中复制内容时,只需在 vim 中按
p就能粘贴(文本编辑器,可能也包括操作系统/终端模拟器) - 良好的自动补全:例如 git 这样的命令应该有特定于命令的自动补全(shell)
ls命令有颜色(shell 配置)- 我喜欢的终端主题:我花很多时间在终端里,希望它看起来漂亮,并且主题能与终端编辑器的主题匹配(终端模拟器、文本编辑器)
- 自动终端修复:如果某个程序输出了奇怪的转义码导致终端混乱,我希望它能自动重置,以免终端被搞乱(shell)
- 快捷键:我希望
Ctrl+左箭头能正常工作(shell 或 应用程序) - 能在
less等程序中使用滚轮:(终端模拟器 和 应用程序)
还有无数其他的终端便利功能,不同的人看重不同的东西,但以上这些是我无法忍受没有的。
我如何实现“现代体验”
我的基本方法是:
- 使用
fishshell。基本不做配置,除了:- 将
EDITOR环境变量设为我最喜欢的终端编辑器 - 将
ls别名为ls --color=auto
- 将
- 使用任何支持 24 位色彩的终端模拟器。过去我用过 GNOME Terminal、Terminator 和 iTerm,但对此并不挑剔。除了选择字体外,我基本不做什么配置。
- 使用
neovim,其配置是我在过去大约 9 年里慢慢积累起来的(上一次我删除 vim 配置并从头开始是在 9 年前)。 - 使用 base16 框架 来统一所有主题。
影响我方法的一些因素:
- 我不花太多时间通过 SSH 连接到其他机器
- 我宁愿多用一点鼠标,也不愿想方设法用键盘完成所有操作
- 我参与很多小项目,而不是一个大项目
一些“开箱即用”的“现代”体验选项
如果你想要一个不错的体验,但又不想花太多时间配置呢?弄清楚如何以让自己满意的方式配置 vim 确实花了我大约十年时间,这太久了!
关于如何以最少配置获得合理终端体验,我最好的建议是:
- shell:要么用
fish,要么用带 oh-my-zsh 的zsh - 终端模拟器:几乎任何支持 24 位色彩的都可以,例如以下都很流行:
- linux:GNOME Terminal、Konsole、Terminator、xfce4-terminal
- mac:iTerm(Terminal.app 不支持 256 色)
- 跨平台:kitty、alacritty、wezterm 或 ghostty
- shell 配置:
- 将
EDITOR环境变量设为你最喜欢的终端文本编辑器 - 也许将
ls别名为ls --color=auto
- 将
- 文本编辑器:这个比较难选,也许是 micro 或 helix?我都没有认真用过它们,但两者看起来都是很酷的项目,而且我觉得在 micro 中可以直接使用所有常见的 GUI 编辑器命令(
Ctrl-C复制,Ctrl-V粘贴,Ctrl-A全选),并且它们能按预期工作,这太棒了。我可能会尝试切换到 helix,但重新训练我的 vim 肌肉记忆似乎太难了。而且 helix 还没有 GUI 或插件系统。
就个人而言,我不会使用 xterm、rxvt 或 Terminal.app 作为终端模拟器,因为我过去发现它们缺少一些核心功能(比如 Terminal.app 不支持 24 位色彩),这让终端对我来说更难用。
不过,我不想假装获得“现代”终端体验比实际更容易——我认为有两个问题让它变得困难。我们来谈谈它们!
实现“现代”体验的问题 1:shell
bash 和 zsh 是目前最流行的两个 shell,但它们都没有提供我开箱即用就能满意的默认体验,例如:
- 你需要自定义提示符
- 默认情况下它们不会自带 git 补全功能,需要手动配置
- 默认情况下,bash 只存储 500 行历史记录,而(至少在 Mac OS 上)zsh 默认只配置存储 2000 行,这仍然不算多
- 我觉得 bash 的 Tab 补全很令人沮丧,如果有多个匹配项,就无法通过 Tab 键循环选择它们
尽管我很喜欢 fish,但它不兼容 POSIX 确实让很多人难以切换。
当然,学习如何在 bash 或其他 shell 中自定义提示符是完全可行的,而且甚至不需要太复杂(在 bash 中,我可能会从类似 export PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' 这样的设置开始,或者使用 starship)。但这些“不复杂”的事情累积起来确实不少,尤其是当需要在多台系统之间同步配置时,就更加棘手了。
一个非常流行的获得“现代” shell 体验的解决方案是 oh-my-zsh。它看起来是一个很棒的项目,我知道很多人都在愉快地使用它,但我过去在使用这类配置系统时遇到过困难——目前看来,基础的 oh-my-zsh 会增加大约 3000 行配置,而且我经常发现,额外的配置系统会让排查问题变得更困难。我个人倾向于用这个系统添加大量额外插件,导致系统变慢,然后因为慢而沮丧,最后彻底删除它,从头开始编写新配置。
问题 2:如何获得“现代”体验:文本编辑器
在我最近进行的终端调查中,最受欢迎的终端文本编辑器是 vim、emacs 和 nano。
我认为终端文本编辑器的主要选择有:
- 使用 vim 或 emacs 并按自己的喜好进行配置,只要肯下功夫,几乎可以实现任何想要的功能
- 使用 nano 并接受体验相当有限的事实(例如,我认为在 nano 中无法用鼠标选中文本然后“剪切”)
- 使用
micro或helix,它们似乎提供了相当不错的开箱即用体验,但偶尔可能会遇到使用非主流文本编辑器带来的问题 - 尽可能避免使用终端文本编辑器,也许使用 VSCode,用 VSCode 的终端满足所有终端需求,并且基本不在终端中编辑文件。或者我知道很多人将
code设置为终端中的EDITOR。
问题 3:单个应用程序
最后一个问题是,我使用的某些程序有时会让人有点烦。比如在我的 Mac OS 机器上,/usr/bin/sqlite3 不支持 Ctrl+左箭头 键盘快捷键。要解决这个问题以获得合理的 SQLite 终端体验,过程有点复杂,我不得不:
- 弄清楚原因(Mac OS 不附带 GNU 工具,而“Ctrl-左箭头”支持来自 GNU readline)
- 找到变通方法(从 homebrew 安装 sqlite,它支持 readline)
- 调整我的环境(将 Homebrew 的 sqlite3 加入我的 PATH)
我发现调试这类特定应用的问题真的不容易,而且常常感觉“不值得”——我往往会选择忍受各种小麻烦,因为不想花几个小时去研究它们。我之所以能解决这个问题,唯一的原因是我最近花了大量时间思考终端相关的事情。
要获得“现代”的终端程序体验,很大一部分在于使用更新的终端程序。比如,我懒得去学 top 中排序列的快捷键,但在 htop 里,我只需用鼠标点击列标题就能排序。所以我改用 htop!但发现新的、更“现代”的命令行工具并不容易(虽然我在这里列了个清单),找到实际中我喜欢用的工具需要时间,而且如果你通过 SSH 连接到另一台机器,这些工具不一定存在。
一切都会影响一切
在配置终端以让一切“完美”时,我发现一个棘手的问题是,工作流程中一个看似微小的改变,真的会影响其他所有方面。比如,我现在不用 tmux。但如果我需要再次使用 tmux(例如,因为经常通过 SSH 连接到另一台机器工作),我就得考虑几件事,比如:
- 如果我希望 tmux 的复制功能通过 SSH 与系统剪贴板同步,我需要确保终端模拟器支持 OSC 52
- 如果我想使用 iTerm 的 tmux 集成(将 tmux 标签页变成 iTerm 标签页),我需要改变配置颜色的方式——目前我是在 shell 启动时通过一个脚本设置颜色,但这意味着恢复 tmux 会话时颜色会丢失。
可能还有更多我没想到的问题。“使用 tmux 意味着我必须改变管理颜色的方式”听起来不太可能,但这确实发生在我身上,我决定:“好吧,我现在不想改变管理颜色的方式,所以这个功能我就不用了!”
我也很难记住自己依赖哪些功能——比如,我当前的终端确实支持OSC 52,而且因为通过SSH从tmux复制一直都能正常工作,我甚至没意识到这是需要关注的事情,结果切换终端后它就莫名其妙失效了。
慢慢改变
就我个人而言,虽然觉得自己的配置不算那么复杂,但达到现在的状态也花了20年!因为终端配置变更极可能产生意料之外且难以理解的后果,我发现如果一次性改动太多终端配置,一旦出问题就很难排查原因,这会让人非常困惑。
所以我通常倾向于做很小的改动,并且接受可能需要非常非常长的时间来适应。比如一两年前我把ls换成了eza,虽然喜欢它(因为eza -l默认显示人类可读的文件大小),但至今仍不太确定是否完全适应。不过有时大刀阔斧的改动也值得,比如十年前我从bash切换到fish,现在依然庆幸当初的决定。
获得“现代”终端并不容易
试图解释终端配置有多“简单”反而让我意识到这其实挺难的,而且我自己有时也会困惑。
我发现终端配置永远不存在一种完美方案能兼容所有其他工具。我只能不断尝试,找到某种适合我的局部稳定状态,并接受一个事实:一旦开始使用新工具,就可能打破现有系统,需要重新调整方案。