Vim技巧

这是最近看《Vim实用技巧》的记录,以后如果有Vim方面的技巧会继续追加。

  1. 插入模式下使用方向键相当于使用Esc + hjkl + i,会改变.u等按键的行为。
  2. 经常使用Esc能够帮助理清思路和控制回退粒度。
  3. 针对文本对象的操作威力强劲,试试dawci"或者yapp。定义文本对象时,除了一些显而易见的分隔符之外还有wWspt,另外bB分别与)}等价。
  4. 操作的效率和可重复性都需要关注。
  5. 如果光标不在数字上,键入[n]<C-a>[n]<C-x>会先自动跳转到当前行的下一个数字再执行。
  6. Vim默认将0开头的数字解释成八进制,此时使用<C-a>结果可能出乎预料,可以考虑设置nrformats参数。
  7. d3wdw..各有千秋。前一种形式键入少,撤销连贯,后一种形式不需要数数,撤销粒度细。
  8. Vim除了几个常用模式之外还有很多小模式,比如在键入dw时在两次按键中间短暂存在"操作符待决模式"。
  9. 单词写错之后,删除整个单词重写能够有效降低再次犯错的概率。另外键入start可能比键入art更快。
  10. 在插入模式下使用能够进入"插入-普通模式",允许我们执行一次普通模式命令。
  11. Caps映射成Ctrl键非常有用,够不着Esc可以使用<C-[>替代。不过如果一年有300天每天有10个小时手是放在键盘上的,为什么不买个HHKB呢?
  12. 在插入模式下可以使用<C-r>{register}插入对应寄存器内的数据,这种插入是相当于从键盘上一个一个键入的,如果开了自动补全功能可能出现奇怪的结果。使用<C-r><C-p>{register}则按原义插入,建议插入多行时还是先退回到普通模式。如果需要粘贴从其他程序内复制来的文本,可以:set paste保证粘贴结果(也可以使用"+p来避免切换paste)。
  13. 使用gRgr进入"虚拟替换模式",该模式会将制表符当做一组空格处理。其实更建议启用expandtab,只使用空格。
  14. ga显示当前字符的编码,<C-v>按编码插入字符。
  15. 为什么要使用<C-g>从可视模式切换到选择模式呢?
  16. gv可以重新选定上次选定的文本范围,不过如果上次选定的文本被删了结果可能就有点奇怪。在可视模式下o可以切换选区的活动端。
  17. <C-v>5j$Aa:.,.+5 norm Aa都可以在光标所在行及其后五行的行尾加上字符a
  18. 行内跳转使用f;,可能比hl效果好,实际上可以只在光标距离目标只有一两个字符的时候使用hl。尽量选择目标附近的非常见字符,如使用fxh而不是fe;;;
  19. 将光标处于一对圆括号的(上时,将这对圆括号改成方括号的一种方法是:%r]``r[
  20. `.跳转到最后修改的位置,g;则可以依次向更早的修改的位置跳转。gi则使用`^恢复退出插入模式时的光标位置并切换到插入模式,是个好用的功能。
  21. 配合pathsuffixesadd参数,可以很方便的使用gf打开当前文件中引用的文件,就像超链接一样。:find可以在path中搜索指定文件并打开;:edit可以打开指定文件,使用:e!放弃所有修改将文件重新加载到缓冲区是一个很常用的功能。
  22. "_为黑洞寄存器。与其小心翼翼保护无名寄存器,不如将内容保存到指定寄存器。使用y时,内容不但会覆盖到无名寄存器,同时会保存到复制专用寄存器"0"+寄存器与系统粘贴板等效,可以使用该寄存器完成Vim与粘贴板互通(使用:version查看xterm_clipboard确定该功能在编译时是否开启)。使用小写字母引用有名寄存器,会覆盖该寄存器原有内容,使用大写字母则追加。
  23. 在可视模式时,使用p可以使用指定寄存器的内容来替换高亮文本,同时将高亮文本覆盖到无名寄存器中。
  24. 使用vim -u NONE -N启动Vim时不加载vimrc并禁用插件,使用于原生Vim。
  25. H/M/L可以将光标移动到屏幕的顶部/中部/下部。zt/zb/zz则将光标所在行滚动到屏幕的顶部/中部/下部。
  26. 粘贴多行文本时,使用gp会在粘贴后将光标移动到粘贴内容的结尾。
  27. 10;.;10.显然都是不好用的,但是qq;.q之后再10@q是好用的。另外,f只在当前行查询,如果不想数需要执行多少次,可以试试22@q,因为2@在同一个键上。
  28. 使用norm可以在多行并行执行宏,一行上出错不会中止其他行上的执行。具体采用并行还是串行需要根据情况。
  29. Vim的寄存器不过是一些保存文本的容器。如果需要在宏中追加命令,只需要使用大写字母引用宏进行录制。可以将宏导出到文本里并进行修改(使用<C-v>输入Esc等),然后使用0"ay$之类的命令导入到宏寄存器,不使用"add的原因是防止引入拖尾字符^J,从文本中导入宏要特别注意键盘编码。另外还可以通过Vim脚本修改宏。
  30. 给全文本加上行号的按键序列为:gg:let i=1<CR>qaI<C-r>=i<CR>)<Esc>:let i += 1<CR>qjVG:norm @a<CR>。可见norm的并行也不是完全意义上的并行。
  31. Vim的magic搜索模式半途而废,只为部分一般意义上的正则特殊符号赋予特殊含义。方括号本身具有特殊含义、圆括号匹配原义字符需要加\才能转义具有特殊含义、花括号的闭括号可以省略转义而圆括号则不行,这些看起来特别混乱。可以使用\v开启very magic模式,此时除了_、字母和数字之外的所有字符都当做具有特殊含义的字符(像#这样暂时没有特殊含义的当然还是直接匹配),以下三组效果一样:#\([0-9a-fA-F]\{6}\|[0-9a-fA-F]\{3}\)\v#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})\v#(\x{6}|\x{3});或者使用\V开启原义模式,此时只有\具有特殊含义。
  32. 在Vim中,<>相当于\b,用来界定单词边界;\_s相当于\s,用以表示空白字符;zs(zone start)和ze(zone end)相当于环视断言,提供了只匹配查找模式所得到的一部分内容的功能;在圆括号前面的%相当于?,使圆括号只分组不捕获。即使在原义模式下,正向查找的/和反向查找的?也需要转义,否则会被当做查找域的结束符:如/abc/e<CR>中的/e是一种标志位,使得光标移动到每个匹配的结尾。
  33. 执行替换命令时,可以设定/n标志位,只统计匹配的数量而不实际执行替换操作。替换域中的特殊字符除了\t\1等,还有&(插入匹配模式所有内容)、~(使用上一次s命令的替换域内容)、\={vim script}(执行vim表达式,并将结果作为替换域内容,其实@{register}也是一个Vim命令)。
  34. 将替换命令的查找域留空时Vim将会重用上次的查找模式,这消除了查找和替换之间的耦合性,方便查找模式的测试,也可以利用*等命令减少查找模式的输入,缺点是该命令历史记录缺失,不方便重用(必要的时候在查找域中输入<C-r>/来填充)。另外,使用q/进入查找历史列表可以很方便的修改查找模式。
  35. :&相当于重新执行上一次替换命令,但是不包括标志位,如果想保留标志位,可以使用:&&g&则相当于%s//~/&,在整个文件范围内重复上一次替换命令,带标志位。
  36. grep原来是从:g/re/p演化来的。:v:g!是对匹配模式取反。
  37. g/{/ .+1,/}/-1 >可以将每对花括号的内容增加一级缩进(实际上如果存在嵌套这个命令就不够看了)。书中认为这是global命令的广义形式:g/{start}/ .,{finish} [cmd],但是我觉得将.+1,/}/-1 >理解为一个EX命令会更准确,g命令本来就是先标记,后执行,多生产一个概念没什么好处。
  38. :argsargdo配合使用可以很方便的在多个缓冲区执行命令。如果执行改变缓冲区的命令,需要启用hidden选项。
  39. :w !sudo tee % > /dev/null命令可以让我们使用sudo权限保存文件。
  40. 像这种技巧如果能凑个整,比如100条,就会显得特别高大上,我没这么丧心病狂,先凑个四十条吧:Vim不太适合编辑汉字文档。
Loading Disqus comments...
Table of Contents