跳到主要内容

第06章 输入模式

输入模式是大部分文本编辑器的默认模式,在这个模式下,所敲即所得。

尽管如此,这并不代表输入模式没什么好学的。Vim的输入模式包含许多有用功能。在这一章节中,你将能够学到如何利用Vim输入模式中的特性来提升你的输入效率。

进入输入模式的方法

我们有很多方式从普通模式进入输入模式,下面列举出了其中的一些方法:

i    从光标之前的位置开始输入文本
I 从当前行第一个非空字符之前的位置之前开始输入文本
a 在光标之后的位置追加文本
A 在当前行的末尾追加文本
o 在光标位置下方新起一行并开始输入文本
O 在光标位置的上方新起一行并开始输入文本
s 删除当前光标位置的字符并开始输入文本
S 删除当前行并开始输入文本
gi 从当前缓冲区上次结束输入模式的地方开始输入文本
gI 在当前行的第一列的位置开始输入文本

值得注意的是这些命令的小写/大写模式,每一个小写命令都有一个与之对应的大写命令。如果你是初学者,不用担心记不住以上整个命令列表,可以从 ia两条命令开始,这两条命令足够在入门阶段使用了,之后再逐渐地掌握更多其他的命令。

退出输入模式的方法

下面列出了一些从输入模式退出到普通模式的方法:

<esc>     退出输入模式进入普通模式
Ctrl-[ 退出输入模式进入普通模式
Ctrl-c 与 Ctrl-[ 和 <esc>功能相同, 但是不检查缩写

我发现 esc键在键盘上太远了,很难够到,所以我在我的机器上将 caps lock 映射成了esc键。 如果你搜索Bill Joy(Vi的作者)的ADM-3A 键盘, 你会发现esc键并不是像现在流行的键盘布局一样在键盘的最左上方,而是在q键的左边,所以我认为将caps lock 映射成esc键是合理的。

另一个Vim用户中常见的习惯是用以下的配置方法在输入模式中把esc映射到jj或者jk

inoremap jj <esc>
inoremap jk <esc>

重复输入模式

你可以在进入输入模式之前传递一个计数参数. 比如:

10i

如果你输入“hello world!”然后退出输入模式, Vim将重复这段文本10次。这个方法对任意一种进入输入模式的方式都有效(如:10I, 11a, 12o

在输入模式中删除大块文本

当你输入过程中出现一些输入错误时,一直重复地用backspace来删除的话会非常地繁琐。更为合理的做法是切换到普通模式并使用d来删除错误。或者,你能用以下命令在输入模式下就删除一个或者多个字符:

Ctrl-h    删除一个字符
Ctrl-w 删除一个单词
Ctrl-u 删除一整行

此外,这些快捷键也支持在 命令行模式 和 Ex模式 中使用(命令行模式和Ex模式将会在之后的章节中介绍)

用寄存器进行输入

寄存器就像是内存里的暂存器一样,可供存储和取出文本。在输入模式下,可以使用快捷键Ctrl-r加上寄存器的标识来从任何有标识的寄存器输入文本。有很多标识可供使用,但是在这一章节中你只需要知道以(a-z)命名的寄存器是可以使用的就足够了。

让我们在一个具体的例子中展示寄存器的用法,首先你需要复制一个单词到寄存器a中,这一步可以用以下这条命令来完成:

"ayiw
  • "a 告诉Vim你下一个动作的目标地址是寄存器a
  • yiw 复制一个内词(inner word),可以回顾Vim语法章节查看具体语法。

现在寄存器a存放着你刚复制的单词。在输入模式中,使用以下的快捷键来粘贴存放在寄存器a中文本:

Ctrl-r a

Vim中存在很多种类型的寄存器,我会在后面的章节中介绍更多他们的细节。

页面滚动

你知道在输入模式中也是可以进行页面滚动的吗?在输入模式下,如果你使用快捷键Ctrl-x进入Ctrl-x子模式,你可以进行一些额外操作,页面滚动正是其中之一。

Ctrl-x Ctrl-y    向上滚动页面
Ctrl-x Ctrl-e 向下滚动页面

自动补全

Vim在进入Ctrl-x子模式后(和页面滚动一样),有一个自带的自动补全功能。尽管它不如intellisense或者其他的语言服务器协议(LSP)一样好用,但是也算是一个锦上添花的内置功能了。

下面列出了一些适合入门时学习的自动补全命令:

Ctrl-x Ctrl-l      补全一整行
Ctrl-x Ctrl-n 从当前文件中补全文本
Ctrl-x Ctrl-i 从引用(include)的文件中补全文本
Ctrl-x Ctrl-f 补全一个文件名

当你出发自动补全时,Vim会显示一个选项弹窗,可以使用Ctrl-nCtrl-p来分别向上和向下浏览选项。

Vim也提供了两条不需要进入Ctrl-x模式就能使用的命令:

Ctrl-n             使用下一个匹配的单词进行补全
Ctrl-p 使用上一个匹配的单词进行补全

通常Vim会关注所有缓冲区(buffer)中的文本作为自动补全的文本来源。如果你打开了一个缓冲区,其中一行是"Chocolate donuts are the best":

  • 当你输入"Choco"然后使用快捷键Ctrl-x Ctrl-l, Vim会进行匹配并输出这一整行的文本。
  • 当你输入"Choco"然后使用快捷键Ctrl-p,Vim会进行匹配并输出"Chocolate"这个单词。

Vim的自动补全是一个相当大的话题,以上只是冰山一角,想要进一步学习的话可以使用:h ins-completion命令进行查看。

执行普通模式下的命令

你知道Vim可以在输入模式下执行普通模式的命令吗?

在输入模式下, 如果你按下Ctrl-o,你就会进入到insert-normal(输入-普通)子模式。如果你关注一下左下角的模式指示器,通常你将看到-- INSERT -- ,但是按下Ctrl-o后就会变为-- (insert) --。 在这一模式下,你可以执行一条普通模式的命令,比如你可以做以下这些事:

设置居中以及跳转

Ctrl-o zz       居中窗口
Ctrl-o H/M/L 跳转到窗口的顶部/中部/底部
Ctrl-o 'a 跳转到标志'a处

重复文本

Ctrl-o 100ihello    输入 "hello" 100 次

执行终端命令

Ctrl-o !! curl https://google.com    运行curl命令
Ctrl-o !! pwd 运行pwd命令

快速删除

Ctrl-o dtz    从当前位置开始删除文本,直到遇到字母"z"
Ctrl-o D 从当前位置开始删除文本,直到行末

聪明地学习输入模式

如果你和我一样是从其他文本编辑器转到Vim的,你或许也会觉得一直待在输入模式下很有诱惑力,但是我强烈反对你在没有输入文本时,却仍然待在输入模式下。应该养成当你的双手没有在输入时,就退出到普通模式的好习惯。

当你需要进行输入时,先问问自己将要输入的文本是否已经存在。如果存在的话,试着复制或者移动这段文本而不是手动输入它。再问问自己是不是非得进入输入模式,试试能不能尽可能地使用自动补全来进行输入。尽量避免重复输入同一个单词。