前面记录了vim的简化方式,最理想的过程,追求的是一键移动,一键操作修改。
达成这个目的除了宏作用之外,次数+操作符+动作命令也扮演了重要作用。
【2dd】就是一个典型的次数+操作符+动作命令:
【2】表明连续执行两次;【d】表示是一个剪切操作;【d】当一个操作符命令被连续调用两次时,表示作用于当前行;
整体含义:连续删除两次当前行。
值得注意的是,【d】本质上属于剪切操作,内容被复制到了寄存器中,【2dd】后再使用【p】,被删除的2行内容会粘贴出来,而非粘贴一行。
操作符与动作命令的结合形成了一种语法,学习新的动作命令及操作符,就好像在学习vim新词汇,我们就能表达更多的想法。
次数还能做简单的算术运算:
【ctrl+a】对数字执行加1,【ctrl+z】对数字执行减1。
如图所示,假设想把128改成130,常规做法是【退格键】删除28,然后重新输入30。
现在只需要在命令模式下按两次【ctrl+a】,完成了+2的操作。
假设想把128改成256,当然不可能让我们连按128次【ctrl+a】,而是按【128ctrl+a】即可。
————————————————————————
远比普通模式命令强大的多的EX命令(仅部分):
命令 | 用途 |
:[range]delete [x] | 剪切指定范围的行到寄存器x中 |
:[range]yank [x] | 复制指定范围的行到寄存器x中 |
:[line]put [x] | 在指定行后粘贴寄存器x中内容 |
:[range]copy {address} | 指定范围的行拷贝到{address}行之下 |
:[range]move {address} | 指定范围的行移动到{address}行之下 |
:[range]join | 连接指定范围的行 |
:[range]normal {commands} | 对指定范围内的每一行执行{commands}命令 |
:[range]substitute/{pattern}/{string}/[flags] | 把指定范围内出现{pattern}的地方替换为{string} |
:[range]global/{pattern}/[cmd] | 对指定范围内匹配{pattern}的所有行,在其上执行EX命令{cmd} |
比起普通模式命令,EX命令提供了构造更加复杂操作的能力。
它无需移动光标,直接在任意位置执行,而且拥有在多行上同时执行的能力。
所有能用普通模式命令解决的问题,都可以用EX命令解决。
在比较简单的操作时,几个单词或者几行内,选择普通命令模式较有效率,复杂一些的操作,跨越多行或代码块,选择EX命令更有效率。
range可以用行号,位置标签或者查找模式来指定范围。
行号指定范围:
: 0 虚拟行,位于文件第一行的上方
: . 点指定光标所在当前行。
: 20 指定第20行,即光标跳转到第20行号。
: 20,40 指定从20行号开始,到40行号结束。
位置标签指定范围:
先用vim自带的mark标记能力,比如mm,mn做好标记。
:'m,'n 指定从m标记开始,到n标记结束
查找模式确定范围:
:/part/, /endpart/ 以 关键字 part开始,以关键字 endpart结束。
假设有如下文本:
我们想对<html>和</html>之间的部分进行操作,一种方式是使用行号指定范围,另一种方式就是查找模式。
输入:/<html>/, /<\html>/
这样无论<html>和</html>之间包含多少行的内容(内容变化会引起行号变化),都能准确处理。
在这个例子里,比起行号指定方式,查找模式要更加灵活,智能。
但是这样处理时,<html>和</html>本身也被包含了,如果想剔除掉它们,可以使用如下方式:
:/part/+1, /endpart/ -1 地址偏移, 以 关键字 part下一行开始,以关键字 endpart上一行结束,即不包括关键字本身。
地址偏移的起始部分,既可以是查找模式的关键字,也可以是行号,甚至是mark标记。
:'m+3,'n-5 地址偏移,从标记m+3开始,到标记n-5结束
: .+3, $ 地址偏移,从当前行+3开始,到最后一行结束
: $ 文件最后一行
: % 起始和结束范围是整个文件
:%d 删除掉整个文件内容,d是delete简写