準備好,下面的內容會比較難以理解。
目前為止,我們已經使用`map`、`nmap`、`vmap`以及`imap`創建了實用的按鍵映射。 他們很方便,但是有個缺點。運行下面的命令:
~~~
:nmap - dd
:nmap \ -
~~~
試試按下`\`(在normal模式)。有什么現象?
當你按下`\`時,Vim會解釋其為`-`。但是我們又映射了`-`!Vim會繼續解析`-`為`dd`, 即它會刪除整行。
你使用那些命令創建的映射可能會被Vim解釋成?_其它_?的映射。乍一聽這像是一個優點, 但實際上這很變態。解釋原因之前,我們先用如下命令刪除那些映射:
~~~
:nunmap -
:nunmap \
~~~
## 遞歸
運行命令:
~~~
:nmap dd O<esc>jddk
~~~
上面的命令看上去像是要映射`dd`為:
* 在當前行之前添加新行
* 退出insert模式
* 向下移動一行
* 刪除當前行
* 向上移動到新加的行
貌似這個映射的作用是“清除當前行”。但你可以試試。
當你按下`dd`后,Vim就不動了。按下`<c-c>`才可以繼續,但是你的文件中會多出許多 空行!想想發生了什么?
這個映射實際上是?_遞歸_?的!當你按下`dd`后,Vim解釋為:
* `dd`存在映射,執行映射的內容。
* 新建一行。
* 退出insert模式。
* 向下移動一行。
* `dd`存在映射,執行映射的內容。
* 新建一行。
* 退出insert模式。
* 向下移動一行。
* `dd`存在映射,執行映射的內容。然后一直這樣。
這個映射永遠不會結束!刪除這個可怕的映射再繼續:
~~~
:nunmap dd
~~~
## 負面影響
`*map`系列命令的一個缺點就是存在遞歸的危險。另外一個是如果你安裝一個插件,插件 映射了同一個按鍵為不同的行為,兩者沖突,有一個映射就無效了。
當安裝一個新的插件時,可能你不會使用或記住每一個其創建的映射。即使你記住了,你還得 回看下你的`~/.vimrc`文件以確保你自定義的映射與插件創建的沒有沖突。
這導致插件安裝變得乏味,易于出錯。肯定有個解決辦法。
## 非遞歸映射
Vim提供另一組映射命令,這些命令創建的映射在運行時?_不會_?進行遞歸。運行命令:
~~~
:nmap x dd
:nnoremap \ x
~~~
按下`\`看看有什么現象。
當你按下`\`時,Vim忽略了`x`的映射,僅按照`x`的默認操作執行。即刪除當前光標下的字符 而不是刪除整行。
每一個`*map`系列的命令都有個對應的`*noremap`命令,包括:`noremap`/`nnoremap`、?`vnoremap`和`inoremap`。這些命令將不遞歸解釋映射的內容。
該何時使用這些非遞歸的映射命令呢?
答案是:?**任何時候**?。
**是的,沒開玩笑,?_任何時候_?。**
在安裝插件或添加新的自定義映射時使用`*map`系列命令純屬是給自己?_找_?麻煩。 多敲幾個字符以確保這個問題不會發生,救自己于火海。
## 練習
將之前章節中添加到`~/.vimrc`文件中的映射命令全部換成非遞歸版本。
讀幫助文檔`:help unmap`。
- 前言
- 鳴謝
- 預備知識
- 打印信息
- 設置選項
- 基本映射
- 模式映射
- 精確映射
- Leaders
- 編輯你的Vimrc文件
- Abbreviations
- 更多的Mappings
- 鍛煉你的手指
- 本地緩沖區的選項設置和映射
- 自動命令
- 本地緩沖區縮寫
- 自動命令組
- Operator-Pending映射
- 更多Operator-Pending映射
- 狀態條
- 負責任的編碼
- 變量
- 變量作用域
- 條件語句
- 比較
- 函數
- 函數參數
- 數字
- 字符串
- 字符串函數
- Execute命令
- Normal命令
- 執行normal!
- 基本的正則表達式
- 實例研究:Grep 運算符(Operator),第一部分
- 實例研究:Grep運算符(Operator),第二部分
- 實例研究:Grep運算符(Operator),第三部分
- 列表
- 循環
- 字典
- 切換
- 函數式編程
- 路徑
- 創建一個完整的插件
- 舊社會下的插件配置方式
- 新希望:用Pathogen配置插件
- 檢測文件類型
- 基本語法高亮
- 高級語法高亮
- 更高級的語法高亮
- 基本折疊
- 高級折疊
- 段移動原理
- Potion段移動
- 外部命令
- 自動加載
- 文檔
- 發布
- 還剩下什么?