编辑器进化 VSCode + Vim
本文作者为 360 奇舞团前端工程师
VSCode 是一款非常流行的代码编辑器。它支持多种编程语言,拥有丰富的插件和调试功能,不论是处理前端工程还是后端工程,VSCode 都能提供给开发者优秀的用户体验。
鉴于 VSCode 超高的流行度,我会默认各位使用过 VSCode,这里就不对其再多做赘述,我会着重介绍标题里的另一位主角 —— Vim。
本文会从 Vim 的设计哲学和功能特性出发,让你了解 Vim 究竟有怎样的魅力,能在 30 多年里经久不衰,成为众多用户的编辑器第一选择。之后我会回到 VSCode,聊聊如何在 VSCode 中集成 Vim 的强大能力。最后,我会给出 Vim 的学习路线,怎么样,准备好开始这场 Vim 之旅了吗?
引子
不知道大家第一次听到用到 Vim 是什么时候?对我而言,第一次用还是在大学,当时需要在 Linux 上使用 Vim 编辑一些配置文件,那时我还是是一个纯小白,对 Vim 一无所知,只是知道 Vim 是一个编辑器,进去以后我既不知道怎么输入文字,也不知道如何退出(嘿,在 Vim 里 Crtl-C
都退不出去 😂)。后面即便了解了一些基础操作,也不由得感到写起东西来费时费力,心中暗想,在命令行里写东西真是太不方便了,对那个时代程序员的 Respect 油然而生。当时的我一定想不到,我有一天会用 Vim 写一篇安利 Vim 的文章。
好了,该给大家好好介绍下 Vim 这个「老家伙」了。
「老家伙」Vim
Vim 是一款由 Bram Moolenaar 开发的文本编辑器,Vim 的名字是 Vi IMproved 的缩写,意为改进的 Vi 编辑器,于 1991 年首次发布。Vim 只有几兆的体积,但是它有着强大的文本编辑功能和高度的可定制化,有着「编辑器之神」的美誉。
Vim 确实够老了,今年 2023,它已经 32 岁了,不过这家伙还是很有活力的,最新的 Vim 9 于 2022 发布,社区也涌现除了 Neovim 这样的分支版本。另外,Vim 的用户群体也在不断扩大,Vim 的用户群体中有很多大佬,比如说 Linux 的创始人 Linus Torvalds 就是 Vim 的忠实用户。
如果你用过一些支持插件的 IDE 或编辑器,那么你一定能找到一款 Vim 插件。这不但证明了 Vim 用户群体的庞大,也证明了 Vim 的经久不衰,即使到了其他编辑器中,Vim 的操作方式依旧让大家恋恋不舍。
「专注」--- Vim 的「模式」
Vim 的哲学之一是「快速编辑文本」,这是 Vim 的核心理念,也是 Vim 的设计目标。Vim 的设计者 Bram Moolenaar 一直坚持这个哲学,他认为 Vim 的设计应该是简单的且高效的。
Vim 包含多种模式,每种模式都有不同的用途,这些模式之间可以相互切换,这也是 Vim 的核心特性。Vim 的模式粗略分为以下几种:
Normal 模式:用于文本编辑 Insert 模式:用于文本输入 Visual 模式:用于文本选择 Command 模式:用于执行命令
「模式」是 Vim 中最重要的概念,Vim 为每种模式赋予了一种场景,根据不同的场景,切换到不同的模式,让我们能够专注于当前的任务,并迅速处理。有很多人说过 Vim 的编辑模式,容易让人进入「心流」的状态,想必这就是专注的魅力。
默认情况下,Vim 会进入 Normal 模式,这时可以使用 Vim 的各种命令,比如 hjkl
移动光标,dd
删除一行,u
撤销等等。
进入 Vim 后,默认为 Normal 模式。
按下 i
进入 Insert 模式,此时可以输入文本。
此时按下 Esc
键,就可以回到 Normal 模式。
「简练」--- Vim 的语法
很多人都尝试要学习过 Vim,但是却被 Vim 那琳琅满目的快捷键所吓退,但是我想说它的快捷键并不复杂。
Vim 输入命令的方式非常不同,我们常规的命令就像是「和弦」,比如 CMD + C
复制,CMD + Shift + 4
截图,我们需要同时按下多个按键,这种方式叫做「组合键」。而 Vim 就像是在弹奏一段「旋律」,每个音符都是一个命令,我们按照顺序依次输入。
使用 Vim 有的时候就像是在跟它对话,你需要去学习它的语言,而不是死记硬背。人类的语言有很多语法,而 Vim 也不例外,我们来学习其中最重要的一种,这种语法足够覆盖大部分场景了:
verb + noun
或者说 「动词」+「名词」。我举一个例子,dw
这个命令可以理解为 delete word
,d
是动词,w
是名词,d
是删除,w
是单词,所以 dw
就是删除单词。同理,ce
就是 change end
,c
是修改,e
是结尾,所以 ce
就是修改文本直到单词结尾。
⚠️ 这里用了不太准确的说法,旨在让大家理解 Vim 的语法,对于命令的准确解释下文会进一步介绍。
我们还可以加入数字,比如 2dw
或 d2w
来执行 2 次 dw
命令,这样就可以删除两个单词了。
这太令人兴奋了,这意味着我们只要学会 Vim 这门语言的「单词」,我们就能随意排列组合,创造出无数的命令,和 Vim 畅快的对话。
用更 Vim 的话来说:
动词:Operator(操作符) 名词: Motion(动作) Text Object(文本对象)
接下来,我会分别介绍这三个基本概念。
「明了」--- Operator
Operator 是 Vim 负责编辑的命令,它们是一种动作,比如:
d
Delete 删除c
Change 修改y
Yank 复制p
Put 粘贴~
反转大小写
而由于行操作太常见了,所以 Vim 设计了一些快捷指令:
dd
删除一行yy
复制一行cc
修改一行D
删除到行尾C
修改到行尾
「精准」--- Motion
Motion 是 Vim 负责移动光标的命令。最最基础的命令就是 hjkl
,它们分别代表光标的上下左右移动:
但是这些命令只能移动一个字符,如果我们想要移动到指定的位置,就需要使用更加精准的命令了:
w
Word 下一个word
的开头e
End 下一个word
的结尾f{character}
Find 到本行下一个指定字符
其中 word
在 Vim 中是一个特殊的概念,它是由字母、数字、下划线组成的字符串,比如 hello_world
,helloWorld
,hello123
都是 word
。而我们平时编写代码时,经常会带上特殊符号,诸如 helloWorld()
,helloWorld!
,helloWorld?
,这些都不是 word
。不过 Vim 中存在 WORD
的概念,标记了由空格分割的字符串,Vim 为我们提供了 W
,E
这些命令,它们的作用和 w
,e
命令一样,只是它们会跳过特殊符号。
很可惜,Vim 默认并不识别中文的词语,虽说可以通过一些 Vim 插件来实现,但是这并不在本文的讨论范围内。我们更多将 Vim 用作编程,所以中文支持其实我认为意义不大。
「魔法」--- Text Object
Text Object 标明了 Vim 中一个「文本组」。这是我最爱的 Vim 特性,没有之一,是真正让我爱上 Vim 的原因。
Text Object 有两种描述词:
i{object}
:Inner Object,内部对象a{object}
:A Object,外部对象
对象类型就多了,比如:
w
Word 单词b
Bracket 括号B
Big bracket 大括号t
Tag 标签"
引号
比方说 (hello vim)
,就是一个文本对象:
ib
:Inner bracket,内部括号,Vim 会选择hello vim
ab
:A bracket,外部括号,Vim 会选择(hello vim)
在加上我们之前学到的 Operator,我们就可以做出很多有趣的事情了:
通过 dib
快速的删除括号中的内容,通过 dab
快速的删除括号以及括号中的内容:
通过 ciB
快速删除大括号中的内容,来重写整个函数:
通过 dit
快速删除 HTML 标签中的内容:
当你意识到 Vim 可以按一定语义来分割文本的时候,你就能深深体会到 Vim 的强大了。
回到 VSCode
嘿,Vim 说的够多了,不知道你是否能感受到 Vim 的魅力。Vim 不断成长,社区繁荣发展,Vim 可以通过各种插件强化自身,以至于不输市面上任何一款 IDE。
不过,我并不喜欢使用纯 Vim 开发。我也多次尝试过,但总是被各种插件问题搞的头大,最后我跟自己和解了,我爱 Vim 的编辑模式,但不得不说,VSCode 是目前来说我最喜欢的编辑器,它的许多功能早就成为我工作中必不可少的部分了(比如万能的 CMD + P
CMD + Shift + P
),其稳定的插件市场也让人安心。所以 VSCode + Vim 插件,对于我来说,就是双剑合璧!
如果你还不想成为一个 Vim 专家,想要开箱即用的使用 Vim 最核心的功能,那么我强烈推荐你使用 VSCodeVim 插件。
VSCodeVim 是一款为 VSCode 设计的 Vim 模拟器,它把 Vim 中的各种操作映射到 VSCode 中,让你可以在 VSCode 中使用 Vim 的编辑模式。虽说无法体验 Vim 的全部功能,但是它已经足够高效好用了。
进入 VSCode 插件市场,搜索 Vim
,安装 Vim
插件即可。
此时你进入 VSCode,打开一个文件,应该就能注意到那个在 Vim 中很常见的闪烁光标了,左下角也会有一个 -- NORMAL --
,用来表示现在所处的模式。
好了,你可以开始使用 VSCodeVim 了,尝试下我们之前说的一些命令吧!
VSCodeVim 的功能扩充
VSCodeVim 是个有趣的插件,它不仅仅是一个 Vim 模拟器,它还扩充了原本的 Vim 的功能,将 VSCode 中的一些功能映射到了 Vim 中。
首先,它扩充了 Text Object:
e
:Entire file,整个文件q
:Quote,引号(单引号、双引号、反引号)a
:Argument,参数
这个 daa
我真的是太常用了,能够快速的删除一个参数。
除此之外,还有一些其他的 Vim 操作,也都映射为了 VSCode 的功能,而且我觉得比原版更好用,比如:zc
zo
可以开关折叠,zR
zM
可以折叠所有或者展开所有。
VSCodeVim 中的插件
Vim 插件是 Vim 的延伸,提供了相当强大的能力,一些常用 Vim 插件已经被 VSCodeVim 集成了,比如:「Vim Surround」。
它可以让你快速的给文本 添加 / 删除 / 修改 括号、引号、标签等等。
你可以通过检查一下 VSCode 配置文件,确认 Vim Surround 插件是开启的:
比如一个相当常见的场景,如果你想要修改一个标签名,可以这样:
cs
意为 Change Surround,呼出 Vim Surround 插件,t
意为 Tag。cstt
合起来就是 Change Surround from Tag to Tag,也就是 「修改围绕的标签为另一个标签」。
如何自定义快捷键
Vim 的精髓之一就在于自定义快捷键,这样用户就能根据自己的习惯来使用 Vim,而不是被 Vim 的快捷键束缚住。VSCodeVim 当然也支持自定义快捷键,你可以在 VSCode 的设置中找到 vim.normalModeKeyBindings
和 vim.insertModeKeyBindings
,分别对应 Vim 的 Normal 模式和 Insert 模式。
Vim 为了防止用户自定义快捷键和 Vim 内置快捷键冲突,会建议用户在自定义快捷键前面加上一个 「Leader Key」记作 <Leader>
,默认为 \
,你可以在 VSCode 的设置中找到 vim.leader
来修改它。
{
"vim.leader": "<Space>",
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["J"],
"after": ["5", "j"]
},
{
"before": ["K"],
"after": ["5", "k"]
},
{
"before": ["<Leader>", "j"],
"after": ["J"]
},
]
}
比如我们可以进行如上的配置,使用 J
和 K
来快速的上下移动。而为了避免和 Vim 内置快捷键 J
冲突,我们可以使用 <Leader> + j
来代替 J
。
除了用来覆盖 Vim 的快捷键,我们还可以来定义一些新的快捷键来调用 VSCode 的能力,比如可以添加下面的配置:
{
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["<Leader>", "p"],
"commands": [
"workbench.action.showCommands",
]
},
]
}
这样我们就可以通过 <Leader> + p
来调出 VSCode 的命令面板了。
VSCode 的 commands 可以通过查看 VSCode 的快捷键设置 JSON 文件来查看。
何去何从
非常感谢你能看到这里,朋友。希望我能通过这篇文章让你一窥 Vim 的强大能力。我相信 Vim + VSCode 一定会给你带来很多惊喜。
受限于篇幅,本文只展现了 Vim 很小的一部分,还有很多很酷的东西我没有提到,诸如:
查找替换 . 命令 寄存器 Ex command Vim script NeoVim 一系列 Vim 插件
但 VSCodeVim 并无法提供 Vim 全部的能力,所以你可以先学习 Vim 的基础操作,然后再使用 VSCodeVim 来提升你的开发效率,你可以选择性(着重看基础命令,跳过 Vim Script 和 插件开发)的看看下面这些资料,特别是 Boost Your Coding Fu With VSCode and Vim 这本书:
vimtutor,在你安装好 Vim 之后,可以通过 vimtutor
命令来学习 Vim 的基础操作。Boost Your Coding Fu With VSCode and Vim,这是一本 VSCode + Vim 的书籍,它会带你一步步的使用 VSCode + Vim 来提升你的开发效率。 Learn Vim (the Smart Way),这是一本非常好的 Vim 入门书籍,它会带你从 Vim 的基础操作,到 Vim 的高级操作,再到 Vim 的插件开发。 Vim Adventures,这是一个非常有趣的 Vim 游戏,它会带你一步步的学习 Vim 的基础操作。
靡不有初,鲜克有终,Vim 有一定的学习曲线,希望你能给自己多一点时间去适应它,我相信 Vim 不会让你失望。
参考资料
Vim Wiki Learn Vim (the Smart Way) Boost Your Coding Fu With VSCode and Vim