能够重复,就别用次数
在处理某些特定工作时,使用次数可以使按键次数变得最少,不过我们并不是非得这样不可,我们需要认真考虑次数与重复各自的优缺点.
d2w
2dw
都可以, 但是dw.
的粒度更小. 每次只作用一个单词.多按了一次.命令怎么办?没关系,只要按一次u键就可以回退回来.
只在必要时使用次数
假设我们想把文字”I have a couple of questions”改为”I have some more questions”, 可以用下面的方式做: c3wsome more<Esc>
在此场景下,使用.命令的意义不大,我们可以删除一个单词,然后用.命令删除另一个,但随后我们还得切换到插入模式(例如:使用i或cw)
使用次数的另一个好处是,它保留了一个干净,连贯的撤销历史记录,完成这次修改之后,我们按一下u键就可以撤销整个修改.
技巧12. 双剑合璧,天下无敌.
操作符 +动作命令 = 操作
d{motion}命令可以对一个字符(dl),一个完整单词(daw)或一整个段落(dap)进行操作,它作用的范围由动作命令决定.c{motion}.y{motion}以及其他一些命令也类似,
他们被统称为操作符(operation).你可以用:h opeator 来查询完整的列表
g- , gu , gU 命令要用两次按键来调用,我们可以把上述命令中的g当做一个前缀字符,用以改变后面的按键行为.
操作符与动作命令的结合形成了一种语法.这种语法的第一条规则很简单,即一个操作由一个操作符,后面跟一个动作命令组成.学习新的动作命令及操作符,就像是在学习Vim的词汇一样,如果掌握了这一简单的语法规则,在词汇量增长的同时,就能表达更多的想法.
假如我们已经知道如何用daw删除一个单词,然后又学到了gU命令.他也是一个操作符.我们可以用gUaw把当前单词转化成大写形式,如果我们的词汇进一步扩充,学会了作用段落的ap动作命令,就会发现我们可以进行两个新的操作,用dap删除整个段落,或者用gUap把整段文字转化成大写.
Vim的语法只有一条额外的规则,即当一个操作符命令被连续调用两次时,它会作用于当前行,所以dd删除当前行,而>>缩进当前行,gU命令是一种特殊情况,我们既可以使用gUgU,也可以用简化版的gUU来使它作用于当前行.
vim 操作符命令
命令 | 用途 |
---|---|
c | 修改 |
d | 删除 |
y | 复制到寄存器 |
g- | 翻转大小写 |
gu | 转换为小写 |
gU | 转换为大写 |
> | 增加缩进 |
< | 减小缩进 |
= | 自动缩进 |
! | 使用外部程序过滤{motion}所跨越的行 |
扩展命令组合的威力
使用vim缺省的操作符和动作命令,我们能够执行的操作的数目还是巨大的.然而我们可以通过自定义动作命令及操作符来进一步扩充其数目.
自定义操作符 与已有动作命令协同工作
随同vim发布的标准操作符集合相对比较少,但我们可以定义新的操作符,Tim Pope的commentary.vim插件提供了一个很好的例子.此插件为Vim所支持的编程语言增加了注释及取消注释的命令.
注释命令以\{motion}触发,它会切换到指定行的注释状态.它是一个操作符命令,因此可以把它和所有动作命令结合在一起.\ap将切换当前段落的注释状态.\G 会把从当前行到文件结尾间的所有内容注释掉.而\\注释当前行.
https://github.com/tpope/vim-commentary
如果对创建自定义操作符感兴趣,可以先阅读一下文档: h :map-operator
自定义动作命令与已有操作符协同工作
textobj-entire插件是一个很好的例子,它为Vim增加了两种新的文本对象ie和ae,他们作用于整个文件.
如果想用 = 命令自动缩进整个文件,我们可以执行 gg=G (也就是说,先用gg跳到文件开头,然后用=G自动缩进从光标位置到文件结尾的所有内容).如果安装了textobj插件的时候,简单的执行=ae就可以了,运行这条命令时光标在哪不重要,因为它总是作用于整个文件.
插入模式
技巧13 在插入模式中可即时更改错误
如果在插入模式中文本出了错,我们可以立刻进行更改,无需切换模式.要迅速更正错误,除了用退格键外,我们还可以用插入模式中的其他一些命令.
如果错误在单词开头呢?
可以用如下组合键:
<C-h>删除前一个字符(同退格键)
<C-w>删除前一个单词
<C-u>删除至行首
这些命令不是插入模式所独有的,甚至也不是vim所独有的,在vim的命令行模式中,以及在bash shell中,也可以使用它们.
技巧14.返回普通模式
插入模式只专注于做一件事,那就是输入文字,而普通模式确实我们大部分时间所使用的模式,因此能快速在这两种模式间切换是很重要的,
返回普通模式的经典方法是使用<ESC>
作为替代,可以用<C-[>
<C-o> 切换到插入-普通模式
当我们处于插入模式时,想运行一个普通模式命令,然后马上回到原来的位置继续输入,vim为此提供了一种巧妙的方法,以减少模式切换所带来的不畅.这就是插入-普通模式.
插入普通模式是普通模式的一个特例,它能让我们执行一次普通模式命令,在此模式中,我们可以执行一个普通模式命令,执行完成之后,马上返回到插入模式,要从插入模式切换到插入普通模式,可以按<C-o>
<C-o>zz
可以重回屏幕,把当前行显示在窗口正中,这样就能阅读当前行之上及之下的半屏内容.
技巧15.不离开插入模式,粘贴寄存器中的文本
vim中的复制和粘贴操作一般都在普通模式中执行,不过有时也许我们不想离开插入模式,就能往文档里粘贴文本.
举例:
下面是一段尚未完成的文本.
Practical Vim, by Drew Neil
Read Drew Neil’s Practical Vim.
对于vim用户来说,大小写转换键是一个威胁,如果小写转换键处于大写模式,而你尝试用k或j去移动光标,你触发的将会是K和J命令,简单地说,K命令用于查看处于光标下的那个单词的手册页,参见:h K 而J命令则用于把当前行和下一行连接起来.也就是说,如果你不小心切换到了大写模式,你将会惊讶的发现,缓冲区的内容怎么这么快就乱了?
把大小写转换键映射成<Esc>
键可以省很多力气,尤其是Vim对<Esc>
使用的这么频繁,不过作者更建议把大小写转换键映射为<Ctrl>
键,<C-[>
的功用和<Esc>
键相同,如果<Ctrl>
触手可及,那么这一组合键输入起来也会很容易,另外,不管是在vim还是其他程序中,很多快捷键都会用到<Ctrl>
我们想把本书的书名插到最后一行,以补全该行.
yt,
Practical Vim,by Drew Neil
Read Drew Neil’s jA␣
Practical Vim,by Drew Neil
Read Drew Neil’s <C-r>0
把刚才复制的文本粘贴到光标所在位置. .<Esc>
这个命令的一般格式是<C-r>{register}
.其中{register}是我们想要插入的寄存器的名字 参见 :h i_CTRL-R
对面向字符的寄存器使用<C-r>{register}
命令
在插入模式中,可以用<C-r>{register}
命令很方便地粘贴几个单词,可是如果寄存器中包含大量的文本,你会发现屏幕的更新有些轻微的延迟,这是因为vim在插入寄存器内的文本时,其插入的方式就如同这些文本是由键盘上一个个输入进来的,因此,如果”textwidth” 或者”autoindent”选项被激活的话,最终就可能会出现不必要的换行或额外的缩进.
<C-r><C-p>{register}
命令更智能一点,它会按照原意插入寄存器内的文本,并修正任何不必要的缩进(参见 :h i_CTRL_R_CTRL_P),不过这个命令有点不太好输入!因此,如果我想要从寄存器中粘贴多行文本的时候,我更喜欢切换到普通模式,然后使用某个粘贴命令.