使用 Visual Studio Code 和 Vim 提升你的编码能力
本文最初发布于barbarianmeetscoding.com。
Visual Studio Code 非常出色。它提供了无与伦比的用户体验,并支持多种语言和开发生态系统。它拥有出色的默认设置,并且非常易于使用和上手。
Vim 太棒了。它的模态特性和文本编辑功能使其在众多编辑器中独树一帜。Vim 提供的文本编辑能力、速度和准确性都远超其他同类产品。
两者的结合简直太棒了(是的,我刚刚就是这么做的)。
在接下来的几分钟内,您将在您最喜欢的编辑器 Visual Studio Code 中引入 Vim 编辑器中的许多非常有用的工具,从而提高您的 Visual Studio 编辑技能。
以下是我们将要介绍的内容:
- 什么是 Vim?为什么在 VSCode 中使用 Vim?
- 如何在 VSCode 中安装 Vim?
- Vim 的基本生存技能
- 使用 Core Vim Motions 实现极速移动
- 使用 Vim 操作符和动作以思维速度进行编辑
- Vim 的秘密语言
- 用 Vim 插入文本
- 在可视模式下选择文本
- 使用 Vim Surround 来环绕事物
- 使用 Sneak 和 EasyMotion 插件实现更快的移动速度
本文不需要任何 Vim 基础知识,所以即使你不熟悉 Vim 也不用担心。我将指导你了解高效使用 VSCode 和 Vim 所需的所有概念和技巧。
什么是 Vim?
Vi是一款古老的文本编辑器,甚至在世界诞生之前就已经存在了。它被设计用于在一种叫做终端的装置上工作,这种装置具有一个非常罕见却又极具创意的特性:以模态方式运行。也就是说,它有一种模式用于插入文本,另一种模式用于编辑文本,还有一种模式用于选择文本,等等。
Vi 最新、最受推崇的版本是Vim(Vim 已验证,以前称为Vim itation ),它同时支持文本和图形界面,在vi 的基础上进行了大量的改进,并支持所有已知的平台。但 Vim 的影响远不止于 Vim,Vim 的理念如此卓越,以至于它们已经超越了 Vim 编辑器本身,并传播到其他编辑器中。如今,几乎可以在任何你能想到的编辑器和 IDE 中找到类似 Vim 的模式,例如在Visual Studio Code中。
为什么选择 Vim?Visual Studio Code 还不够吗?
在如今这个时代,你为什么要费心去学习一个古老的编辑器?它真的会对我 VSCode 的设置造成很大的影响吗?
事实上,Vim 提供了一种我从未见过的文本交互方式,它能让你在编辑代码时获得完全不同的掌控力和流畅度。在经验丰富的用户手中,用 Vim 编辑文本就像变魔术一样:
- Vim 让你更快。
- Vim 让你更精确
- Vim 解锁了文本编辑中完全不同的控制级别
- Vim 削弱了你的大脑和计算机之间的接口
- 做演示的时候真是令人惊叹:D
太棒了!但是 Vim 是如何实现这一切的呢?
Vim 的模态特性赋予你的键盘控制编辑器各个方面的能力。每种模式都如同一张白纸,赋予你的键盘全新能力:闪电般快速编辑文本、以思维速度导航、随心所欲地选择和移动文本等等。
有了 Vim,你不再局限于插入文本,也不再受制于鼠标点击、导航或选择文本的束缚。不会的。使用 Vim 一段时间后,你就会像一位代码外科医生,随时随地以外科手术般的精准度进行专业切割,以闪电般的速度和精准度,完全由键盘驱动的工作流程,浏览你的代码和代码库。
那么,在当今时代,你为什么要学习 Vim?套用《实用 Vim》一书的作者、Vim 最晦涩技巧的大师Drew Neil 的话:
Vim 专为想要提升编程水平的程序员而设计。在专家的手中,Vim 能以思维的速度快速处理文本。
但:
为什么 VSCode 中使用 Vim 而不是仅仅使用 Vim?
你可能会想……好吧。如果 Vim 这么好,那么……为什么不直接在 Visual Studio Code 中使用 Vim 而不是 Vim 呢?
好问题!事实上,要让 Vim 拥有与现代文本编辑器类似的功能并非易事。代码补全、代码导航、编辑器内错误信息等功能虽然 Vim 支持,但并非开箱即用。
Visual Studio Code 和 Vim 提供了一个非常完美的结合点,平衡了 Visual Studio Code 超丰富的开发用户体验和 Vim 中的许多令人惊叹的功能。
在 Visual Studio Code 中安装 Vim
为了将 Vim 的强大功能引入 Visual Studio Code,您需要安装VsCodeVim 插件:
- 打开 Visual Studio Code
- 前往扩展
vim
在搜索框中输入- 第一个名为Vim的插件就是你想要的
- 点击安装按钮
- 史诗般的胜利!
现在,安装扩展后,您可能需要重新启动 Visual Studio Code 才能使更改生效。1
你重启过它吗?打开你最新项目的代码文件,看看光标。它看起来像个矩形吗?是的?欢迎使用 Vim。
Vim 的小小进步
如果你现在尝试输入文本,你会惊讶地发现什么都没发生。或者更准确地说,什么也没有发生。也就是说,当你输入的时候,屏幕上没有任何字符被输入。这是因为 Vim 的核心模式是普通模式,而不是插入模式。
在普通模式下,您无法插入文本,而是移动并编辑文本。这种设计决策源于我们意识到,我们花在阅读、浏览和修改代码上的时间比插入文本的时间要多。
以下是您在 Vim 中生存所需的基本知识:
- 四处走动
hjkl
- 进入插入模式,
i
您可以照常输入内容 <ESC>
使用或返回正常模式<CTRL-C>
hjkl
是 Vim 中最核心、最基本的动作。它们允许你将光标向各个方向移动一格:
^
|
|
<-- h j k l -->
|
|
v
它们并非 Vim 中移动的最有效方式,也不是最高效的移动方式。但它们确实能让你在普通模式下更灵活、更自信地移动文件。学习hjkl
有效地移动就像学习走路或骑自行车一样。
在您熟悉更多 Vim 动作之后,您将不会使用hjkl
那么多,但它们对于短距离移动和小幅修正非常方便。
将 Caps Lock 键映射到 Control 键
使用 Vim(以及其他任何编辑器)时,有一件非常方便的事情是将Caps Lock键重新映射到Control 键。这意味着您可以从舒适的主行轻松访问诸如Control之类的超级常用键。
如果您使用的是 Mac,可以直接在“偏好设置”的“键盘”中执行此操作。否则,您可能需要在开发机器上安装一些软件,但这应该非常简单。Google 是你的朋友。Google 一下。
使用核心 Vim Motions 实现极速移动
动作(Motion)指的是在 Vim 中移动的方式。这些命令输入后会高速精准地移动光标。动作有很多种,每种都最适合不同类型和长度的移动。我发现它们与 VSCode 原生的“前往”功能(例如“前往文件”和“前往符号”)配合使用效果极佳。
以下是最有用的功能的简要列表:
逐字水平移动
Word Motions可让您水平移动得更快:
- 用于
w
在单词之间跳转(以及b
向后跳转) - 用于
e
跳转到单词的末尾(以及ge
向后执行) - Vim 中的单词仅包含字母、数字和数值。如果您想将
.
、(
、{
等特殊字符视为单词的一部分(Vim 术语中称为 WORD),可以使用上述按键的大写对应键(W
、B
、E
、gE
)。
一般来说,文字动作可以实现更精确的变化,而 WORD 动作可以实现更快的移动。
移动到特定字符
发现角色动作可以让你快速且高精度地水平移动:
- 使用find
f{char}
命令移动到行中下一个出现的字符(以及向后移动)。例如,移动到下一个双引号。char
F
f"
- 用于
t{char}
将光标移动到下一个字符出现之前(un* t *il)char
使用后,f{char}
您可以键入;
转到下一个匹配项或,
转到上一个匹配项。您可以看到;
和,
是重复上一个字符搜索的命令。
关于音符、旋律和和弦
Vim 非常特别。如果你用过其他编辑器,你可能习惯于按键的和弦,也就是同时按下多个键的组合。例如,CTRL-C 复制,CTRL-V 粘贴。Vim 也使用和弦,但更依赖于按键的旋律。
如果你把键盘想象成音符,那么旋律就是一系列一个接一个的音符。这是在普通模式下使用 vim 的最常见方式。所以,当你看到“需要键入”
f{char}
来查找一行中的某个字符时,这意味着你先键入f
,然后再键入该字符{char}
。虽然这有点陌生,但非常方便,因为控制编辑器突然感觉就像在输入文本一样。这对你的手腕健康也很有好处。
水平移动极限
要进行极度水平移动,请使用:
0
:移动到一行的第一个字符^
:移动到一行的第一个非空白字符$
:移至行尾g_
:移动到行尾的非空白字符
垂直移动
从k
和开始j
,我们继续讨论一种更快的垂直操纵方法:
}
向下跳转整个段落{
类似但向上CTRL-D
让我们向下移动半页CTRL-U
让我们向上移动半页
具有搜索模式的高精度垂直运动
当您心中有目标时,要想垂直移动得更快,最好的选择是使用和命令进行搜索:/{pattern}
?{pattern}
- 用于在文件内向前
/{pattern}
搜索 - 用于向后
?{pattern}
搜索
你会发现,当你输入时,匹配的模式会被高亮显示。当你找到所需内容时,输入<Enter>
后光标会跳转到搜索的第一个匹配项。在那里,你可以根据需要进行一些编辑,之后使用n
跳转到下一个匹配项(或N
上一个匹配项)。你可以将其视为n
重复搜索。
Vim 乐于帮你节省时间:你可以随时输入/<Enter>
或?<Enter>
来运行上次搜索(向前或向后)。用于*
搜索光标下的单词。
通过计数加快移动速度
计数是可以作为命令前缀的数字,用于倍增该命令的效果。例如,2w
允许我们将光标向前移动 2 个单词。用于{count}motion
将动作{count}
次数倍增。
垂直移动的一个好方法是利用 counts 与j
和 的组合k
。当你启用相对行号(通过 VSCode 首选项)时,这种方法非常有效,因为{count}
上下跳行以到达目标行变得非常自然。
语义移动
- 使用
gd
跳转到光标下的内容的定义 - 用于
gf
在导入时跳转到文件
还有一些更漂亮的核心动作
gg
转到文件顶部{line}gg
转到特定行G
转到文件末尾%
跳转到匹配({[]})
使用 Vim 操作符进行神奇的编辑
动作不仅仅是用来移动。它们可以与一系列称为操作符的命令组合使用,以便在普通模式下编辑代码。这些组合通常采用以下形式:
an action to perform: delete, change, yank, etc
/
/
/ ____ a motion that represents a piece
| / of text to which to appy the action
| / defined by the operator
{operator}{count}{motion}
\
\
\
\_ a multiplier to "perform an action
{count} times"
其中一个命令是通过按键触发的删除d
:
d5j
删除以下 5 行df'
删除当前行中第一次出现该'
字符之前的所有内容(包括该字符)dt'
会像上面那样做,但不包括字符(所以直到之前)d/hello
删除所有内容,直到第一次出现hello
ggdG
删除整个文档
其他有用的运算符有:
c
更改。这是最有用的操作符。它会删除并让你进入插入模式,这样你就可以输入y
Vim 术语中的y ank 或 copyp
用 Vim 术语来粘贴g~
切换大写字母
所有这些运算符都有一些有用的简写语法,旨在节省您的打字时间并提高常见用例的速度:
- 双击运算符使其对整行进行操作:
dd
删除整行、cc
更改整行等。 - 将运算符大写,使其从光标操作到行尾:
D
从光标删除到行尾、C
更改为行尾等。
注意到动作和命令键有多重要吗?
Vim 中的命令和动作通常很容易学习,因为它们通俗易懂,而且很容易猜到。想要更改某些内容?你可能想使用
c
运算符。想要逐字移动?试试w
。想要删除某些内容?试试d
运算符等等。
当我们将运算符与一类称为文本对象的特殊动作结合起来时,运算符和动作才会真正发挥作用。
使用文本对象编辑缺口
文本对象是结构化的文本片段,或者,如果你愿意,也可以称之为文档领域模型的实体。文档由什么组成?单词、句子、引用文本、段落、块、(HTML)标签等等。这些都是文本对象。
在命令中指定文本对象的方式是将字母a
(代表文本对象加上空格)或i
(内部对象不带空格)与代表文本对象本身的字符组合:w
用于表示单词、s
用于表示句子、'
"
用于表示引号、p
用于表示段落、用于表示b
被包围的块(
、B
用于表示被包围的块{
以及t
用于表示标签。因此,要删除不同的文本片段,您可以:
daw
删除一个单词(加上尾随空格)ciw
改变内在词das
删除一个句子(删除内部句子)dis
da"
删除双引号中的内容(包括引号)ci"
改变双引号内的内容dap
删除一个段落dab
da(
或da)
删除被包围的块(
daB
da{
或da}
删除被包围的块{
dat
删除 HTML 标签cit
更改 HTML 标签的内容
将文本对象与运算符组合起来非常强大,你会经常用到它们。像cit
、ci"
和cib
这样的运算符简直太棒了。
假设我们想将下面这个字符串的内容更改为其他内容:
const salute = 'I salute you oh Mighty Warrior'
你输入ci'Hi!<ESC>
后它变成:
const salute = 'Hi!'
就这样。你不用再去抓鼠标,选中文本,然后再写别的了。只需输入三个字母,Boom 就搞定了。
注意到大多数 Vim 键都位于手指附近吗?
Vim 拥有模式功能,允许主行附近的按键在各个模式下重复使用,从而最大限度地减少了缓慢而复杂的组合键操作,并提高了你的速度和手指手腕的耐用性。这太棒了!
使用点运算符重复上次更改
Vim 还为你准备了另一个旨在节省更多按键次数的技巧:神奇.
命令。该.
命令允许你重复上次所做的更改。想象一下,你运行dd
删除一行。你可以dd
再次键入 删除另一行,但你也可以使用 ,.
这只需一次按键即可。好吧,你节省了一次按键,那又怎样?好吧,你可以使用该.
命令重复任何类型的更改,而不仅仅是单个命令。例如,你可以像这样 更改“Awesome”这个词cawAwesome<CR>
,然后只需使用 即可重复执行所有按键操作,重复执行整个命令.
。想想看,可能性有多大!
该命令与重复搜索命令( 、或).
配合使用效果极佳。假设您想删除所有出现的。另一种选择[^3]是搜索 cucumber ,然后用 删除它。之后,您可以使用转到下一个匹配项并将其删除!只需两次按键!?!再次想象一下各种可能性!;
,
n
N
cucumber
/cucumber
daw
n
.
Vim 的秘密语言
你可能已经注意到,所有这些运算符、计数和动作构成了一种(编程)语言。你可以将运算符视为函数,将计数和动作视为参数,或者使用更简单的类比……你可以将运算符视为动词,将计数视为形容词,将动作视为宾语。
Vim 真正的魔力在于组合。随着你逐渐积累操作符和动作的词汇量,你会发现你可以随心所欲地组合它们。所以,一旦你掌握了上一段中c
、cl
、caw
、ciw
,,你不仅能够使用,还能将它与你已有的所有动作以及、、等ct.
dl
dl
daw
diw
dt
这太酷了。使用 Vim 时,你会感觉自己正在文本编辑的元宇宙中遨游,就像编程或控制文本编辑和编写机制一样。如果你熟悉 git 以及使用 git 命令行进行源代码管理的感受,你可以将 Vim 视为文本编辑界的 git。(先不说 Vim 比 git 早出现近 30 年的事实)。使用 Vim,你查看一段文本时,看到的不再仅仅是单词或文本,而是无数操作符和动作应用的可能性。
用 Vim 插入文本
你迟早都要写代码。在 Vim 中,你写代码是在插入模式下进行的。你在使用命令时已经了解了一些插入模式c
,但让我们再深入一点。有两个核心命令可以让你进入插入模式:i
for insert和a
for append。
插入命令会在光标前i
进入插入模式。而附加命令会在光标后进入插入模式(就像在光标所在的任何位置附加内容)。从那时起,你就处于插入模式,Vim 的行为与其他编辑器几乎一样(欢迎回来,VSCode!)。a
与许多其他 Vim 命令一样i
,a
具有大写对应命令,可执行更强的插入和附加功能。I
在当前行的开头将您置于插入模式,而A
在结尾将您置于插入模式。
除此之外,i
还有a
另外三个超级有用的命令我喜欢用它们来进入插入模式:
o
在当前行下方插入一个新行并进入插入模式(助记符在下面打开一行)O
在当前行上方插入一个新行,并进入插入模式gi
让你从上次退出插入模式的位置进入插入模式。如果你不小心退出了插入模式,想回到上次退出的位置继续输入,这个功能非常有用。
好的,假设你现在处于插入模式,正在打字,然后犯了一个错误,比如打字错误。你会回到正常模式,修正打字错误,然后再回到插入模式吗?不会!有几个绑定可以帮助你在插入模式下直接修复错误:
C-h
可以删除你输入的最后一个字符C-w
让你删除你输入的最后一个单词C-u
让你删除你输入的最后一行
不过,你最终还是会想退出插入模式去做其他事情。有三种方法可以做到这一点:<ESC>
、C-[
和C-C
。其中,最容易输入的是C-C
。
在可视模式下选择文本
可视模式相当于 Vim 中使用鼠标选择文本。不过,你不用鼠标,而是使用 Vim 动作。当你需要选择文本时,此模式会非常方便,因为它会在你操作时提供视觉反馈。
有三种方法可以启动视觉模式:
v
针对字符的可视模式。当你移动时,你会逐个字符地选择V
适用于可视模式的逐行选择。移动时,您将逐行选择<C-V>
适用于块级视觉模式。当你移动时,你可以选择矩形文本块
可视化模式对于复制粘贴内容以及操作文本块或代码块非常有用。它的工作方式与普通模式相反:
- 在正常模式下,首先定义运算符,然后定义表示要应用该运算符的文本的动作
- 在可视模式下,首先选择文本,然后输入运算符
拆分、标签以及它们之间的切换
Vim 的一大亮点在于它对拆分和制表符的支持。在 Vim 中,创建、调整大小、重新排列以及在拆分和制表符之间移动都非常轻松快捷。VSCodeVim 对这项 Vim 功能提供了相当不错的支持。
分裂
分割功能非常棒。它允许你将工作区划分为垂直和水平分割窗口:
- 使用
:sp {nameoffile}
命令打开水平分割 - 使用命令
:vsp {nameoffile}
打开垂直分割
您可以使用<C-W>
+在它们之间移动hjkl
。
键入命令
注意到这些命令前面的 : 了吗?冒号会触发命令行模式,并让你输入命令(也称为 Ex 命令,在本书后面深入探讨命令行模式时,你会明白为什么)。
要输入 ex 命令,只需输入 :
:
加上命令名称即可(例如 :vsp)。输入冒号和命令后,该命令将显示在屏幕左下方。
标签
- 用于
:tabnew {file}
在新选项卡中打开文件 - 用于
:tabn
转到下一个选项卡 - 用于
:tabp
转到上一个选项卡
使用 Vim Surround 来环绕事物
VsCodeVim内置了许多实用的 Vim 插件。其中之一就是 vim-surround,它扩展了 Vim 的秘密语言,添加了一个新的运算符:环绕运算符 或s
。
使用这个运算符,我们可以像使用 Vim 中的任何其他运算符一样使用它来包围大段文本:
ds'
删除周围的'
(ds{char}
)cs'"
改变周围'
环境"
(cs{old}{new}
)ysaptli>
<li>
用标签(ys{motion}{char}
)包围段落
您还可以通过在可视模式下选择一些文本然后使用 vim-surroundS{desired character}
使用 vim-sneak 和 vim-EasyMotion 实现更快的移动
Vim-sneak和vim-EasyMotion是两个 Vim 插件,它们可以增强 Vim 中的移动体验。这两个插件都需要通过 VSCodeVim 首选项启用。
Vim-sneak 是字符搜索(行内)和模式搜索(文件内)之间的中间地带:
- 你输入后
s{char}{char}
,光标会移动到这两个字符序列的第一次出现处。之后,输入 即可找到;
下一个出现的位置,输入 即可找到,
上一个出现的位置。 的S{char}{char}
操作方式类似,但顺序相反。
vim-surround 使用运算符扩展了 Vim 的秘密语言,而 vim-sneak 则实现了相同的功能,只不过增加了一个动作。因此,你可以将它与其他运算符结合使用:
- 类型
{operator}z{char}{char}
和运算符将应用于潜行动作遍历的文本。
Vim-EasyMotion是 Vim 插件中比较奇特的一个。它完全绕过了 Vim 的手势操作,并以一种奇特而又令人眼花缭乱的方式重新定义了手势操作。当你触发一个 Easy Motion动作时,它会用一个组合键标记整个文档中可能的目标,并以叠加层的形式(覆盖在相关文本上)显示。输入这个组合键,你就会传送到该位置。
例如,输入“ \\w
”(这\\
是触发 EasyMotion 的方式),EasyMotion 就会标记你前面所有单词的开头。输入“ ” \\f'
,EasyMotion 就会标记所有出现该'
字符的地方。是不是很酷炫?
一些方便的 Visual Studio Code 专用键映射:
这些是 VSCodeVim 团队专门为 VSCode 提出的一些方便的映射:
gb
在找到的下一个与光标下的单词相同的单词上添加另一个游标。类似*
,但不是跳转到下一个出现位置,而是创建多个游标。af
是一个视觉 moe 命令,可以选择越来越大的文本块。gh
相当于将鼠标悬停在光标所在位置。这非常方便,可以启用纯键盘工作流程,同时仍能使用一些只能通过鼠标使用的功能(例如错误消息、类型等)。
下一步我该去哪里?
太棒了!本文涵盖了非常多的内容,希望它能作为您在 Visual Studio Code 中使用 Vim 的指南。接下来,您需要一点一点地练习,直到您能够熟练使用 Vim。不要试图一次性应用本文中学到的所有知识。只需选择一些您认为更有用的操作符,然后慢慢将它们添加到您的工作流程中即可。
尽管我们讨论了很多内容,但仍有大量内容我们没有谈到:
- VSCodeVim 中还有更多插件可用。快来看看有没有你感兴趣的吧。
- Vim 的核心功能之一是其出色的可定制性。VSCodeVim 通过自定义按键映射实现了部分可定制性。也就是说,它允许您定义自定义按键映射,使常用操作更易于输入。点击此处查看一些精彩示例。
- 考虑安装Neovim并在 VSCode 中启用它。它提供了非常棒的命令行模式支持。没错,又一个 Vim 模式,可以实现一些很棒的功能。
- 以下是VsCodeVim目前可用功能的完整列表。没错,它非常庞大,还有很多好东西有待探索。
去吧,享受你新获得的知识,提高你的技能和工作效率,如果你想了解更多关于 Vim 的知识,我为你准备了更多精彩的东西:
- 尝试探索 Vim系列,获取更多关于 Vim 的文章
- 或者阅读5 分钟 Vim系列的简短文章
- 或者更好的是,获得《Vim 的使用向导》,这是一本关于 Vim 的精美书籍,我将一步步指导你如何更出色地使用 Vim
保重,去踢一些屁股吧!:D
2月10日更新:嘿!我刚刚开始了一个新视频博客系列,希望能帮你更快上手。好好享受吧!
(我无法在 dev.to 中嵌入播放列表,因此这里是前三个视频,这里是完整播放列表的链接)
2019年7月12日更新:这篇文章已经变成了一本关于VSCode和Vim的完整书籍!哇哦!你可以在leanpub、亚马逊上购买,也可以在线免费阅读。
Windows 或 Linux 系统中的 VSCode 用户?读读这篇文章吧!
@mccabiles在一条精彩的评论中指出,在 Windows 或 Linux 上使用 VSCode 时,一些你习惯使用的快捷键会失效(例如CTRL+C
、CTRL+V
等)。原因是 Vim 通常有比这些快捷键更有效的方法来达到相同的效果(例如y
和p
命令等)。如果你还不习惯这些 Vim 命令,但仍希望保留CTRL-C
、CTRL-V
或其他与它们原始行为相关的快捷键,别担心!你可以按照以下说明在 VSCode 设置中配置哪些快捷键会被 Vim 覆盖:
-
VSCode 的最新版本立即提供了对插件的支持,但谁也不知道。:D ↩