Vimscript编程指南

1、操作符-区间 映射

这个章节我们继续来探索vim映射的神奇功能:“操作符-区间 映射”,让我们先来弄懂这个名词的意义,然后在使用他。

一个操作符是一个等待你来输入一个移动命令的命令,然后对你当前位置到移动后的位置之间的文本做操作。

常见的操作符有d,y,c。例如:


          Operator
          vvvvvv
dw    " Delete    to next word
ci(     " Change  inside parents
yt,     " Yank      until comman
                        ^^^^^^^^
                         Movement

在vim里,你创建的移动命令可以和所有现存的命令配合使用。运行下面的命令: :onoremap p i(

现在把下面的文本输入到vim里:

return person.get_pets(type="cat",fluffy_only=True)

把光标放在“cat”上,然后输入dp,会发生什么呢?vim会删除括号里的文本。你可以认为这里面的动作是“选中参数”。

上面的 onoremap 命令让vim是告诉vim当他在等待一个动作时,如果输入了p,那么就把它映射成i(。当我们输入dp的时候,就像是在说“删除参数”一样,对vim而言就是“删除括号里的内容”。

我们可以对所有的命令使用这种新映射方式,把之前的文本再次输入vim: return person.get_pets(type="cat", fluffy_only=True)

把光标放在“cat”上,然后输入cp,这次又发生了什么呢?Vim还是会删除括号里的文本,不同的是这次vim会停留在inset模式,因为你用了“替换”命令,而不是“删除”命令。

下面我们看看另外一个例子,运行下面的命令: :onoremap b /return<cr>

现在在vim里输入以下文本:


     def count(i):
          i += 1
          print i

          return foo

把光标移动到第二行的i上面,然后按下db。会出现什么呢?Vim会删除函数体里的内容,一直到“return”语句,这是因为我们的映射使用了vim的normal模式下的搜索。

当你在考虑怎么来定义一个新的操作符-区间的动作时,你可以按照下面的思路来考虑:

  • 从当前位置开始;
  • 进入visual模式;
  • 然后是动作的映射
  • 最后你要操作的文本都已经选定了

你要做的是把第三步替换成你想要的功能。

改变初始位置

对于我们之前学习的功能,你可能发现了一个问题,如果我们的操作只能从当前位置开始的话,这样会限制我们想要做的。

不过Vim并不会限制我们能过什么,所以这个问题还是有办法来解决的。运行下面的命令: :onoremap in( :<c-u>normal! f(vi(<cr

这个命令看起来很难,不过我们可以先试试这个命令。把下面的文本输入到vim里: print foo(bar)

把你的光标移动到单词“print”的任何位置上,然后输入cin(。Vim会删除括号里的内容,然后把你的光标放在中间,并且是处于insert模式下。

你可以把这个映射当做“在下一个括号里”,它会对当当前行的下一个括号里的内容执行操作符所对应的操作。

接下来我们来做一个和上面相对的命令“在上一个括号里面”。运行下面的命令: :onoremap il( :<c-u>normal! F)vi(<cr>

你自己可以输入一些文本来测试上面的映射,确保它确实有效。

那么这个映射到底是怎么工作的呢?首先,是一个现在可以暂时不考虑的命令——只要知道它的功能是为了让这个映射在所有的情况下都能正常工作的。剔除的话,就剩下: :normal! F)vi(<cr>

:normal!使我们后面将会讨论的一个命令,现在只需要知道它的功能是模拟在normal模式下按下键盘。例如:normal! dddd会删除两行文本,就像按下dddd一样。末尾的表示执行输入的命令。

所以排除上面的那些命令,就只剩下 F)vi(

现在就变得很简单了:

  • F) :移动到最近的‘)’字符;
  • vi(:进入visual模式,并且选中括号里的文本。

最后我们在visual模式下选中了我们要操作的文本,vim接着就会执行我们指定的操作。

常用的规则

操作符-区间 映射的创建方式多种多样,记住下面两条准则可以帮助你方便的来创建操作符-区间映射:

  • 如果你的映射最后的结果是在visual模式下选择了一些文本的话,那么vim会对这些文本进行操作;
  • 否则的话,vim会对光标之前的位置和当前位置之间的文本进行操作。

练习

  • 为“靠近下一个括号”和“靠近上一个括号”建立操作符-区间映射;
  • 对大括号建立上面四种映射;
  • 创建一个“在下一个邮件地址里”的映射,这样的话你就可以来修改下一个邮件地址。in@是一个对实现这个映射有帮助的命令。不过你可能会用/....正则表达式..来实现。
  • 阅读:help omap-info 看看你能否找到的作用。