如果你听说过 vim,那么你应该知道,这是一个非常神奇、可以不依赖鼠标只靠键盘进行编辑的编辑器。在我们开始之前,不如先思考一个问题:如果要你设计一个可以脱离鼠标的编辑器,你会怎么做呢?你可能会想,在一些现代的编辑工具中,我们可以依靠上下左右键、Home、End 等移动光标,将一些常用的需要鼠标操作的功能绑定到功能键开头(例如 Ctrl、Alt)的快捷键上。好了,就这样你成功发明了 Emacs 和 Nano。
然而,这样做存在一些问题。譬如说,用上下左右一次只能移动一位,但这显然非常低效。你可能会说,我们可以再绑一个快捷键,比如说用 Ctrl + 5 代表一次向下移动5行。可这依然不是一个好的设计,且不说这样做会导致快捷键几乎无限制地增长、导致记忆负担大大增加;由于我们不可避免会使用非功能区的按键,为了将这些按键和正常文字内容输入区别开来,我们势必需要用功能键前缀 + 非功能键的方式来创建快捷键,而随着快捷键的增长,我们就需要长时间将小拇指按压在 Ctrl、Alt 等键上的同时进行快捷键中其他按键的敲击,然后你就会发现,这样非常伤你的小拇指……
(BTW,我个人是弹钢琴的,手指比较有力,所以长时间按这种边边角角的键并不是什么费劲的事情,但是我多少也觉得 Ctrl 按多了不太舒服)
于是,我们决定进一步改进这个设计——既然长时间按压功能键让人不适,我们干脆绑定一个按键,使得这个按键按下的时候自动进入到快捷键输入模式,此时输入的内容不会被作为文字内容添加进去,而是被当作快捷键的一部分。好了,这就是 vim 的基本思路——模式编辑。
不过,你可能会注意到虽然前文我们一直在说 vim,但是教程系列的名称里用的是 neovim。neovim 是 vim 的一个 fork 版本,二者基本操作基本相同,但是 neovim 对默认设置做了一些更加合理的调整、将 vim 的配置语言从 vimscript 换成了 lua 等一系列调整。总而言之就是,neovim 是一个更新、用起来(我个人认为)更加方便的 vim。
# 0 为什么你可能不需要 vim / neovim
是的,在开始教程之前,我是要劝退一波的,因为我见到了太多人用 neovim 只是因为脑子一热,但到头来不但没学会 neovim 还耽误了手头的工作。所以:
- 如果你只是编程的初学者,请不要碰 vim / neovim / emacs 等任何需要大量自定义的编辑器
- 一来,你不应该把宝贵的学习时间花费在配置编辑器上;先把那门编程语言学明白
- 二来,neovim 的配置也是需要编程能力的,我并不认为一个初学者有能力解决配置过程中可能出现的问题
- 如果你没有时间进行 DIY 或者没有 DIY 的意愿,VsCode / VS / JetBrains 系等工具更适合你
- 一些插件会有 api 更新,如果你长时间不更新插件后哪一天突然想起来更新一下,可能会出现旧配置无效的情况(类似于 Arch 的滚挂)
- 多数插件是社区维护的,所以作者可能会停止维护(比如说 null-ls),你可能需要自己找替代品
- 当然,你可以选择一些现成的配置比如说 LazyVim,但我个人不喜欢这么做,具体原因后续教程会讲
很多人会说使用 vim 的都是高手,也有人说使用的工具并不是判断一个人是不是高手的依据。那么实际上呢?我认为,熟练使用 vim 的人一定以高手居多——不一定是那种顶尖的大牛,但技术一定不算差;然而,需要明白的是,这些人是因为熟悉技术所以能够熟练使用 vim,而不是因为使用了 vim 才成为了高手。所以,学习 vim 之前,至少打好基础,弄明白一些基础概念,学明白至少一门语言,培养合理的编码风格。否则,学习 vim 只会是浪费时间。
# 1 为什么你可能需要 vim / neovim
关于这一点,我曾在另一篇博客里写过。与一些主流的观点不同,我并不认为使用 vim 会提高我们的效率:
需要明确,我们是在写代码而不是在聊天,这也就意味着我们大多数时间是在思考而不是在劈里啪啦地敲键盘;而即使到了敲键盘的时候,其效率也要看我们的打字速度——vim千好万好,也不会让我们打字的速度提高……
某种角度来说,vim和现代通用的编辑模式的区别,就类似于用手柄打游戏和用键鼠打游戏……很多人会觉得手柄打游戏比键鼠打游戏舒服,但一定不会有人觉得手柄打游戏会比键鼠更快让我们通关。
事实上,我认为 vim 真正的优势在于以下几点:
- 只用键盘确实很舒服——当你习惯键鼠协同操作的时候可能感受不到这一点,但一旦你习惯了纯键盘操作,就会意识到频繁操作鼠标有多么麻烦
- 高度的可定制性——这个编辑器,哪怕有一点点让你不满意的,都可以非常方便地去修改;e.g., 添加快捷键
- 一些可以在某些时候大幅度提高效率的功能——比如,宏操作
- 轻便而统一的开发环境
# 2 Neovim 的安装
初学者会有一个疑问:vim / neovim 在 Linux 上是公认的神器,那么它在 windows 上是否同样可用呢?不可否认,neovim 在 windows 上运行存在一些性能问题,但这种性能问题我觉得并不影响日常使用——事实上,我所遇到的性能问题无非是 UI 加载时间慢了 100 ms 这样的差别;再不济,你也可以选择在 wsl 中使用 neovim。
不过,无论你在哪个平台上使用 neovim,至少第一步的安装都还是比较简单的。你可以从 GitHub 上下载安装文件、安装,也可以用包管理器(scoop / winget / apt / pacman / brew / ……)进行安装。
在安装后,我们可以在终端里输入 nvim
启动 neovim。如果想用 neovim 打开某个文件,可以用 nvim filename
的方式打开文件。
# 3 如何学习 neovim
Neovim 之所以这么劝退,是因为它确实很难学。难学并不仅仅体现在想要攒一份好用的配置费时费力;它还体现在大量的默认快捷键上——如果你在 26 个字母里看一圈,你会发现几乎每个字母自己都能单独构成一个快捷键,而很多时候一个字母的大小写还代表了不同的快捷键;而 vim 自身又提供了海量的命令。其体量有多么巨大,去看看文档就足以知道个大概。这往往给初学者带来了有一个困难——他们即使背诵了所有快捷键,也不知道什么时候用什么快捷键更好。
然而,初学者需要明确的一点是,这些并不是刚刚接触 vim 的人应该 care 的。计算机知识浩如烟海,但初学 C 语言的同学并不需要掌握编译原理才能开始编程。事实上,学习 vim 只需要从几个基础的概念、快捷键和命令开始,至于其他更加复杂的内容,你会在使用的过程中逐步发现自己目前掌握的内容不足以满足自己的需求,此时你自然而然就会去寻找解决方案。
学习 vim 是一个积累的过程——在各种意义上。你的配置不可能一开始就是完美的,你的操作习惯不可能一开始就是合理的,但是你一定要有勇气推翻重来。当你自己定义的快捷键不合理,要敢于克服不习惯的感觉修改快捷键(事实上,我在开始写 IceNvim 的时候就推翻了很多自己用了一年多的快捷键);当你的操作习惯在 vim 中有更好的方式,你也要敢于换成更好的那种方式(比如说,把 ddo
改成 cc
,比如说从 xi
到 r
,比如说.s
)。
# 4 那么,初识 neovim 需要掌握什么呢?
第一个需要了解的,是 vim 的模式编辑——这一名词我们在前文提到过。当我们使用 neovim 打开一个文件的时候,我们此时所处的模式叫做 normal mode
。此时我们按键输入的内容是不会被作为文字添加到文件里的。
而如果要输入文字,我们需要按下 i 键,进入到 insert mode
中。此时,如果你的 neovim 没有经过任何配置,那么它的左下角是应该显示 -- INSERT --
的。此时,我们就可以愉快地进行输入了,输入的位置位于刚才光标所在处的前面。注意,这里按下的是小写的 i 键。虽然你会发现大写的 I 键同样可以让我们开始输入,但后面我们会了解到,二者的功能是有区别的。
在 insert mode
当中,很多我们习惯的输入方式都是可以沿用的。比如说,按 Enter 换行,按 Home 和 End 跳转到行首 / 行尾,按上下左右移动光标等。但是,更多更方便更常用的操作并不是在 insert mode
中、而是在 normal mode
中进行的。而当我们想要回到 normal mode
,可以按 Esc 键。
在 normal mode
下可以进行的操作很多,我们前面学过的一个操作就是进入 insert mode
。这里,我们再讲一个简单的操作:光标的上下左右移动。此时,我们仍然可以用上下左右移动光标,但是这样做不是很舒服,因为 vim 快捷键的一个基本思路实际上是让你的手指保持在键盘的中心区域,尽量减少移动,而上下左右键位于键盘右下角。所以,vim 推荐的上下左右移动的按键是 k / j / h / l。
我相信每一个初学者在看到这个键位的时候一定非常崩溃——这完全没有规律可循嘛!但是,这个设计在我看来其实蛮巧妙的,原因如下:
- 这几个键位于编辑区的中间一行,作为非常常用的按键,位置很合适
- 这几个键彼此离得很近,安排很合理
- 标准打字动作要求我们将食指分别放在 f 和 j 键上
- 我们上下移动的频率远高于左右移动(你会发现,很多时候我们不需要左右移动,因为有跳转到行首、行尾等诸多快捷键)
- 这个键位安排符合人体构造
- h 和 l 分别位于最左面和最右面,对应左和右
- j 和 k,虽然没有左右那么直观,但是——当你的右手食指放置在 j 键上、中指放在 k 键上时,你会发现你的中指很自然地比你的食指更靠近键盘上半部分,所以 j 对应向下而 k 对应向上。
不过实际上,这大概不是 vim 采用这种设计的原因。据资料显示,vim 使用 hjkl 是因为 Bill Joy 在发明 vi(vim 的前身)的时候使用的键盘上的 hjkl 键上印有 ↑ ↓ ← → 符号,如下图:
好了,作为学习 vim 的第一节课,这些内容足够了。你可以尝试使用 neovim 编写一些简单的内容,感受一下这款编辑器的优秀。