普通模式是Vim的默认状态,这跟其他编辑器差别很大,它们一般都处于类似Vim插入模式的状态中。
普通模式的强大,来源于它可以把操作符和动作命令结合在一起。
停顿时请移开画笔
画家在休息时不会把画笔放在画布上。对Vim而言也是这样,普通模式就是Vim的自然放松状态,其名字(Normal mode)已经寓示了这一点。
就像画家只花小部分时间涂色一样,程序员也只花一小部分时间编写代码。绝大多数时间用来思考、阅读,以及在代码中穿梭浏览。而且,修改也不一定要切换到插入模式,普通模式中,我们有众多工具可以利用。
把撤销单元切成块
在Vim中,我们自己可以控制撤销的粒度。
u键会触发撤销命令,它会撤销最新的修改。一次修改可以是改变文档内文本的任意操作,其中包括在普通模式、可视模式以及命令行模式所触发的命令,而且一次修改也包括了在插入模式中输入或删除的文本(即i{insert some text}
在Vim中,我们可以控制撤销命令的粒度。只要我们控制好对
那么,我们多久离开一次插入模式比较合适呢?当然,这是一个个人喜好的问题。作者本身提出了非常科学合理的建议:让每次可撤销对应一次思考过程,在每一句话的结尾停顿一下,想一想接下来写什么。这形成了自然的中断点,当准备好继续写作时,使用A命令,如果觉得写错了,使用u撤销。这样思路会被切分成条理清晰的块。(果然见底深刻啊)
当处于插入模式时,如果光标位于行尾的话,另起一行的最快方式是按
(作者原话,可以细细品鉴一番)
Note: 在插入模式下移动光标(使用
构建可重复的删除
如果光标在一个单词的末尾,我们该如何删除这个单词呢?
反向删除:按db命令删除光标起始位置到单词开头内容,然后使用x键删除光标处字符。
正向删除:b命令把光标跳至单词开头,使用dw命令删除整个单词。
删除整个单词:使用更为精准的aw文本对象而不是动作命令。连用daw即可删除该单词,可以解读为delete a word便于记忆。
我们可以使用dbx,bdw以及daw三种方式来删除某一个单词。但如果碰到需要重复删除的情况,哪种方式更好呢?请思考一下。
反向删除方案执行.会重复删除一个字符,即.==x。这并没有什么价值。
正向删除方案中,b只是一次普通移动,因此如果后续执行.命令会重复dw,删除从光标位置到下一个单词开头的内容。不过如果我们执行这种方案时删除的是一行最后一个单词的话,那么就没有“下一个单词”这一说了。
最后一种方案只调用了daw操作。它不仅仅删除了单词,还会删除一个空格。因此.命令是会重复daw删除操作的。因此daw是最后的胜者。
可以看出,常常需要经常一番思考才能充分利用.命令。如果我们需要在几个地方做同样的小修改,就可以尝试构造修改,以便于.命令重复执行。
用次数做简单的算数运算
很多普通命令都可以带一个次数前缀,这样Vim就会尝试指定该命令执行的次数,而不是只执行一次(参见 :h count)。
如果光标不在数字上,它在会当前行正向查找一个数字,如果找到就跳到那里执行上述操作。
能够重复,就别用次数
如果你要删除两个单词,有几种方式:d2w和2dw,以及dw.。你会选择哪一种?
如果想要更好地撤销,最好不要费脑子想次数。记住口诀:执行、重复、回退。
当然了,有必要时我们也使用次数,一般是不需要重复的操作时。
双剑合璧,天下无敌
操作符 + 动作命令 = 操作
d{motion}命令可以对一个字符(dl)、一个完整单词(daw)或一整个段落(dap)进行操作,它作用的范围由动作命令决定。c{motion}、y{motion}以及其他命令类似,统称为操作符。使用:h operator可以查看完整列表。
下表给出常见的操作符。
命令
用途
c
修改
d
删除
y
复制到寄存器
g~
翻转大小写
gu
转换为小写
gU
转换为大写
>
增加缩进
<
减少缩进
=
自动缩进
!
使用外部程序过滤{motion}所跨越的行
操作符与动作命令的结合形成了一种语法。学习新的动作命令及操作符,就像在学习Vim词汇一样。随着词汇量的增加,我们就能表达更多的想法。
比如gUaw将当前单词转换为大写,如果知道了ap动作命令,我们能通过gUap将整段文字变成大写。
Vim的语法只有一条额外规则,即当一个操作符命令被连续调用两次时,它会作用于当前行。所以dd删除当前行,而>>缩进当前行。gU命令是一种特殊情况,我们既可以用gUgU,也可以使用gUU。
扩展命令组合的威力
自定义操作符与已有动作协同工作
我们可以定义新的操作符,Tim Pope的commentary.vim插件提供了一个很好的例子,该插件为Vim所支持的编程语言增添了注释及取消注释的命令。
如果想创建自定义操作符,阅读文档:h :map-operator。
自定义动作命令与已有操作符协同工作
我们可以定义新的动作命令及文本对象来进一步增强缺省的动作命令集。
Kana Natsuno的textobj-entire插件是一个很好的例子,它为Vim增加了两种新的文本对象ie和ae,它们作用于整个文件。
如果想创建自定义动作命令,阅读文档:h omap-info。