如果想在一系列连续行上执行一条普通模式命令,可以用Vim :normal 命令 (缩写形式 :norm)。此命令在与 . 命令vim宏结合使用时,只需花费很少的努力就能完成大量重复性任务。

一、Vim normal命令介绍

Vim normal命令的使用形式为 :{range}norm[al][!] {commands},表示在 {range} 指定的范围内的每行执行若干 普通模式命令 {commands}。{commands} 不能以空格开始,除非在空格前面加个计数 1。

例如,vim命令 :normal ggdd 会将光标移动到文件的第一行( gg) 并删除它( dd )。

Vim normal命令使得在命令行模式执行普通模式命令成为可能。撤销操作会撤销所有的命令。

如果某行执行命令时发生错误,不会影响其他行的命令执行,即vim normal命令是在所有目标行上 并行 执行。

注意:在执行 {commands} 之前,会先将光标定位在每一行的第一列;

因此,vim命令 :%normal i// 可以注释掉整个文件,而不用担心当前光标所在的位置。但是,当vim :normal命令还在工作的时候,整个屏幕显示不会被刷新。

二、避免vim映射

normal命令中的可选参数 ! 用于指示vim在当前命令中不使用任何vim映射;如果没有显式使用 ! 选项,即便是执行一个非递归映射 (noremap) 命令,它的参数仍有可能被重新映射。

例如,假设已经设置了vim映射 :nnoremap G dd,则在vim普通模式按下 G 将执行命令 dd,即会删除一整行;此时,若在vim命令行模式下执行命令 :normal G 同样将删除当前行而不会跳转到当前文件的末行。

为了在即便 G 命令已经被设置了映射的条件下也能在vim normal命令中不改变 G 命令原始的含义,需要使用 :normal! G。通过 ! 选项显式指示Vim在当前命令中不使用任何vim映射。

所以,在任何时候写Vim脚本时,都建议总是使用 normal!,永远不要使用 normal 而给自己埋下不确定性的问题。

三、normal命令与vim重复命令

虽然用 :normal 命令可以执行任意的普通模式命令,但当它和Vim的重复命令结合在一起时最为强大。当需要重复的操作比较简单时,可以配合使用 :normal . 命令,而如果需要执行的重复操作比较复杂时,可以使用 :normal @q 命令来发挥vim宏强大的操作记录功能。

四、normal命令使用示例

4.1 行尾批量加分号

假设想在某个文件的一系列行尾添加一个分号 ;,使用vim重复操作命令 . 当然可以完成这一任务。但是如果想对100行内容执行末尾加分号的操作,如果使用 . 命令,则需要按100次 j.,这显然不是一个好的方法。

为了完成上述任务,vim教程网介绍一种使用 normal 命令执行 . 命令的新方法。

  • 首先使用命令 A; 在光标所在当前行末尾增加 ;
  • 然后按 j 跳到下一行末尾后按 V 进入vim块选择可视化模式,然后按 G 跳转到文件尾行,从而完成目标行的选择
  • 最后,在vim命令行模式下执行命令 :'<,'>normal .

:'<,'>normal . 命令可以解读为 对高亮选区中的每一行 执行普通模式下的 . 命令。无论是操作 100 行还是 1000 行文本,这种方法都能高效地完成任务,而且在可视模式中选中这些行可以摆脱计数的负担。

vim normal命令

'<,'> 代表高亮选区的范围。在可视化模式下选择完范围后,如果按下 : 键,vim命令行上就会自动填充 :'<,'>

4.2 文件每行结尾加分号

更特别一点,如果想在当前vim打开文件的每行的结尾都添加一个分号,可以使用命令 :normal A;

符号 % 代表整个文件范围,因此 :%normal A; 告诉 Vim 在文件每行的结尾都执行vim普通模式下的命令 A;。在做此修改时会切换到插入模式,但是在修改完后 Vim 会自动返回到普通模式。

4.3 修改数字编号为单括号

假设希望将以下文本内容的每个行编号修改为单括号,并将首个单词首字母大小。

转换成vim下的操作就是:需要将每行首个 . 字符修改成 ),再将下一个单词的首字母变为大写。

1
2
3
4
5
6
6. six
7. seven
8. eight
// break up the monotony
9. nine
10. ten

为了高效地实现上述文本转换,首先,在vim普通模式下录制宏 qa0f.r)w~q,然后按键 jVG 选择操作区域后,再执行命令 :'<,'>normal @a 即可完成任务。

:normal @a 命令指示 Vim 在高亮选区中的每一行上执行保存在寄存器a中的宏内容。虽然宏操作在第 4 行会被中断 (f.没有在该行找到目标字符 .),但并不会影响后续行上宏的执行。

因为前面已经提到过,normal 命令在目标行上是并行执行操作。

vim normal命令

注意:本文提到的 并行 意在类比并联电路的健壮性,从本质上来说,vim仍然是顺序地执行宏,而不会真正地并发执行多处修改。

嗯,扫一扫就可以找到小女子我啦~