我有一个「终身技能」清单,其中包含了我认为可以获得超过 20 年复利的技能,比如写作、Vim。
我对 Vim 的热情在观看 devaslife 的视频后急速升温,他使用 Vim 编辑代码的高效和优雅让我印象深刻。终于在 2023 年五月的一个下午,我开始学习 Vim/Neovim。
从使用 Neovim 开始,我逐步升级了自己的工作流,在终端中度过了一段快乐时光,但最终还是选择在 VS Code 中使用 Neovim。
初试 Neovim
我的目标不是成为 Vim 大师并用从零开始构造一个 IDE,而是提高自己的文本编辑效率。
vimtutor 是一个很好的开始,包含了所有必学的基础操作。之后我开始寻找一套合适的配置,避免自己为了让配置更完美而花费太多时间(虽然后来仍投入了几十个小时)。尝试了 Astro、Lunar 等热门的配置后,我留在了 LazyVim。巧的是之后不久 devaslife 也切换到了 LazyVim,侧面印证了 LazyVim 的质量。
LazyVim 是一套各方面都十分优秀的配置,极易上手,预设键位符合人体力学(这些键位已经成了我对 vim 的初始记忆)。它集成了几乎一个代码编辑器需要的所有功能,同时又让人感到十分清爽。
得益于 Language Server Protocol 和 Tree-sitter,Neovim 中的代码补全、语法高亮能力与 VS Code 是一致的。只需要像插件一样安装对应的包,就可以获得对各种语言的支持。
一两个星期后,常用 Vim 操作已经进入了肌肉记忆,结合 LazyVim 预设的 space space
、sf
、gg
、space e
等键位,我明显感受到 Vim 或者说 LazyVim 带来的效率提升,开始体会到纯键盘操作一切的快感。
终端工作流
使用了 Neovim 就自然地会想要优化终端工作流。经过一段时间的探索,我目前的常用工具如下:
- Wezterm:一个 Rust 实现的支持 GPU 加速的终端模拟器,支持使用 Lua 作为配置
- zsh + pure:我对 shell 没有太多要求,但是得兼容 Debian 上默认的 sh/bash,所以没有使用 fish。zsh 没有过多配置,简单写了个函数做插件管理器,安装了 fzf-tab、zoxide、direnv,以及 zsh-users 系列必装的自动补全和语法高亮,最终
.zshrc
就一百多行,然后用 pure 这套简单的提示符配置替换了 oh-my-zsh - 现代版工具
- fd:更好的 find
- ripgrep:更好的 grep
- fzf:模糊搜索,可以与 history、
ctrl+r
等结合,提升搜索质量 - bat:带语法高亮的 cat
- lazygit:非常好用的 Git 工具,现在除了 rebase、解决合并冲突等情况,我都会用它而不是手敲命令
- stow:管理上述工具的配置文件
这些工具构成了符合我核心需求的终端环境,并且干净简单。
我也尝试过引入更复杂的工具,比如 tmux/zellij、平铺式窗口管理器。但最终意识到我需要的只是横/纵向分屏,给 Wezterm 添加几个类似 item2 的快捷键就够了。
Neovim -> VS Code + Neovim
高度的自定义能力带给人无穷的想象空间。每天打开 Neovim,我的第一反应不是项目,而是 Neovim 还有哪里可以再配置一下。即使有意地避免自定义配置,不知不觉中我也投入了太多时间在 Neovim Lua API 文档、插件文档、YouTube 相关视频。
除了忍不住追求更好的插件,Neovim 社区中的开发者勤奋且才华横溢,这些插件往往也具有超高的更新频率,不免带来稳定性上的隐患。项目的突然停止维护则可能导致已有的配置、依赖的插件都要更改,意味着用户又要投入大量时间来适应,比如 null-ls 停止维护。
当再次花了几小时优化配置后,我突然意识到自己在试图构造一个 VS Code,这违背了学习 Vim 的初衷。于是我开始寻求在 VS Code 上复现这套 Neovim 配置。
VS Code 中有两个流行的 Vim 插件,其中 vscode-neovim 是将用户行为代理到本机上的 Neovim 中,理论上有更好的性能和稳定性。而在 Neovim 配置文件中可以设置当通过 VS Code 使用时不激活 LazyVim,比如:
if vim.g.vscode then
-- yank to system's clipboard
vim.opt.clipboard:append("unnamedplus")
-- undo/REDO via vscode
-- https://github.com/vscode-neovim/vscode-neovim/issues/1139
vim.keymap.set("n", "u", "<Cmd>call VSCodeNotify('undo')<CR>")
vim.keymap.set("n", "<C-r>", "<Cmd>call VSCodeNotify('redo')<CR>")
else
require("config.lazy")
end
这样我可以在终端中使用 LazyVim,在 VS Code 中使用裸 Neovim。偶尔 VS Code 会丢失与 Neovim 的同步,运行 “Reload Window” 即可修复。
这种方案结合了 VS Code 和 Neovim 的优势,但我也非常怀念在 Neovim 中使用 ctrl+hjkl
移动到任意窗口,以及通过悬浮窗使用 telescope 和 lazygit,一切都是那么自然流畅。
由此 Vim 完全融入了我的开发流,在一次次的键盘敲击中为我节省了大量时间。
反思
技术人对生产力的追求永不停息,但应当时刻提醒自己目标是获得更多产出或节省更多时间,当意识到自己的关注点聚焦在提升生产力本身上,或许就应该停下来了。