=======
坚持住,事情会变得有点复杂的。
到现在为止,我们已经使用了map,nmap,vmap和imap来建立按键映射,用以节省时间。这个方法确实很有效,但是这个方法也存在问题。
运行下面的命令:
nmap - dd
nap \ -
现在在normal模式下,按下‘\’试试,发生了什么呢?
当你按下‘\’时,vim找到对应的映射,也即是相当于‘-’。但是我们已经把‘-’映射成了其他的功能!最终vim会根据‘-’的映射来操作,也即是‘dd’命令,所以它把当前行给删掉了。
当你用vim来建立映射时,vim会把映射的目标所对应的映射也考虑进来。这个功能看起来确实很不错,但是实际上是个很恶心的功能。我们后面会讨论这个问题。
=======
运行下面的命令:
nmap dd O<esc>jddk
你可能会认为这个命令会把dd映射成以下几步:
但是实际上,这个映射的功能是删除当前行。试试
当你按下‘dd’的时候,vim好想死掉了。这时候你按下Ctrl+c,vim会恢复运行,但是你的文件里会多了很多很多的空行!到底是怎么一回事呢?
dd
被映射了,所以执行映射所以这样递归下去,这个映射是无法终止的。
=======
并不只是我们所学到的*map命令会有递归的风险,并且我们安装的其他的插件也会有这样的风险。
当你安装一个新的插件时,你可能不会使用也不会记住这个插件所使用的映射。如果你用了,那么你就需要你的~/.vimrc文件去看看你自己的映射按键没有被插件使用,同时还要保证插件使用的映射你自己没有使用。
这个问题会让插件安装比较麻烦,并且很容易出现问题。vim里肯定有更好的办法。
=======
vim提供了另外的一些建立映射的命令,它们不会进行递归的映射。试试下面的命令:
:nmap x dd
:nnoremap \ x
现在试试按‘\’,看看会发生什么。
当你按下‘\’时,vim会把他映射成x的操作,并且忽视x的进一步映射。这次不再是删除当前行了,只会删除当前的字符。
所有的map命令都有对应的noremap命令来忽视递归的映射,它们分别是:nnoremap,vnoremap和inoremap。
=======
什么时候需要用这些映射命令的非递归版本来替代递归版本呢?答案是:一直都需要。
注意,是一直都需要!
使用最基本的nmap命令会让你在按照插件或者建立新的映射时非常的痛苦。为了省去不必要的麻烦,建议你还是多输入几个字符,保证不要出现因递归的映射带来的负效应。
============