天天看點

GVim 配置說明

*map.txt*	For Vim version 7.2.  最後更新: 2008年6月
 
 
  

 
 
  

 
 
  		  VIM 參考手冊    作者: Bram Moolenaar
 
 
  		  		  譯者:  con<[email protected]>
 
 
  				  http://vimcdoc.sf.net
 
 
  

 
 
  

 
 
  鍵映射、縮寫和使用者定義的指令。
 
 
  

 
 
  本主題在使用者手冊 |05.3|,|24.7| 和 |40.1| 中有過介紹。
 
 
  

 
 
  1. 鍵映射			|key-mapping|
 
 
     1.1 映 射 命 令			|:map-commands|
 
 
     1.2 特殊參數				|:map-arguments|
 
 
     1.3 映射與運作模式			|:map-modes|
 
 
     1.4 列出映射				|map-listing|
 
 
     1.5 映射特殊鍵			|:map-special-keys|
 
 
     1.6 特殊字元				|:map-special-chars|
 
 
     1.7 映射哪些鍵			|map-which-keys|
 
 
     1.8 示例				|map-examples|
 
 
     1.9 使用映射				|map-typing|
 
 
     1.10 映射 ALT 鍵			|:map-alt-keys|
 
 
     1.11 映射操作符			|:map-operator|
 
 
  2. 縮寫				|abbreviations|
 
 
  3. 局部映射和函數		|script-local|
 
 
  4. 使用者定義的指令		|user-commands|
 
 
  

 
 
  ==============================================================================
 
 
  1. 鍵映射				*key-mapping* *mapping* *macro*
 
 
  

 
 
  鍵映射用于改變輸入鍵的含義。最常見的用途是把功能鍵定義為一系列的指令。比如: >
 
 
  

 
 
  	:map <F2> a<C-R>=strftime("%c")<CR><Esc>
 
 
  

 
 
  這個映射會在光标之後追加目前的日期和時間 (用 <> 記法 |<>|)。
 
 
  

 
 
  

 
 
  1.1 映 射 命 令						*:map-commands*
 
 
  

 
 
  有很多指令用于定義新的映射,删除映射和列出目前的映射。可以從 |map-overview| 參
 
 
  考 "映射" 指令的不同形式及其與模式的關系。
 
 
  

 
 
  {lhs}	表示左手邊	*{lhs}*
 
 
  {rhs}	表示右手邊	*{rhs}*
 
 
  

 
 
  :map	{lhs} {rhs}		|mapmode-nvo|		*:map*
 
 
  :nm[ap]	{lhs} {rhs}		|mapmode-n|		*:nm* *:nmap*
 
 
  :vm[ap]	{lhs} {rhs}		|mapmode-v|		*:vm* *:vmap*
 
 
  :xm[ap]	{lhs} {rhs}		|mapmode-x|		*:xm* *:xmap*
 
 
  :smap	{lhs} {rhs}		|mapmode-s|		      *:smap*
 
 
  :om[ap]	{lhs} {rhs}		|mapmode-o|		*:om* *:omap*
 
 
  :map!	{lhs} {rhs}		|mapmode-ic|		*:map!*
 
 
  :im[ap]	{lhs} {rhs}		|mapmode-i|		*:im* *:imap*
 
 
  :lm[ap]	{lhs} {rhs}		|mapmode-l|		*:lm* *:lmap*
 
 
  :cm[ap]	{lhs} {rhs}		|mapmode-c|		*:cm* *:cmap*
 
 
  			在映射指令作用的模式中把鍵系列 {lhs} 映射為 {rhs}。并
 
 
  			且映射後的 {rhs} 也被進行映射掃描。這個特性可以用來進
 
 
  			行映射的嵌套和遞歸。
 
 
  

 
 
  

 
 
  :no[remap]  {lhs} {rhs}		|mapmode-nvo|		*:no*  *:noremap*
 
 
  :nn[oremap] {lhs} {rhs}		|mapmode-n|		*:nn*  *:nnoremap*
 
 
  :vn[oremap] {lhs} {rhs}		|mapmode-v|		*:vn*  *:vnoremap*
 
 
  :xn[oremap] {lhs} {rhs}		|mapmode-x|		*:xn*  *:xnoremap*
 
 
  :snor[emap] {lhs} {rhs}		|mapmode-s|		*:snor* *:snoremap*
 
 
  :ono[remap] {lhs} {rhs}		|mapmode-o|		*:ono* *:onoremap*
 
 
  :no[remap]! {lhs} {rhs}		|mapmode-ic|		*:no!* *:noremap!*
 
 
  :ino[remap] {lhs} {rhs}		|mapmode-i|		*:ino* *:inoremap*
 
 
  :ln[oremap] {lhs} {rhs}		|mapmode-l|		*:ln*  *:lnoremap*
 
 
  :cno[remap] {lhs} {rhs}		|mapmode-c|		*:cno* *:cnoremap*
 
 
  			在映射指令作用的模式中把鍵序列 {lhs} 映射為 {rhs} 。禁
 
 
  			止對映射後的 {rhs} 進行映射掃描。這個特性可以避免映射
 
 
  			的嵌套和遞歸。通常用于重定義一個指令。{Vi 無此功能}
 
 
  

 
 
  :unm[ap]  {lhs}			|mapmode-nvo|		*:unm*  *:unmap*
 
 
  :nun[map] {lhs}			|mapmode-n|		*:nun*  *:nunmap*
 
 
  :vu[nmap] {lhs}			|mapmode-v|		*:vu*   *:vunmap*
 
 
  :xu[nmap] {lhs}			|mapmode-x|		*:xu*   *:xunmap*
 
 
  :sunm[ap] {lhs}			|mapmode-s|		*:sunm* *:sunmap*
 
 
  :ou[nmap] {lhs}			|mapmode-o|		*:ou*   *:ounmap*
 
 
  :unm[ap]! {lhs}			|mapmode-ic|		*:unm!* *:unmap!*
 
 
  :iu[nmap] {lhs}			|mapmode-i|		*:iu*   *:iunmap*
 
 
  :lu[nmap] {lhs}			|mapmode-l|		*:lu*   *:lunmap*
 
 
  :cu[nmap] {lhs}			|mapmode-c|		*:cu*   *:cunmap*
 
 
  			在映射指令作用的模式中删除 {lhs} 的映射。該映射仍然可
 
 
  			以在其它模式中保留其定義。
 
 
  			備注: {lhs} 包含末尾的空格。該映射取消操作_不會_生效:
 
 
  				:map @@ foo
 
 
  				:unmap @@ | print
 
 
  

 
 
  :mapc[lear]			|mapmode-nvo|		*:mapc*   *:mapclear*
 
 
  :nmapc[lear]			|mapmode-n|		*:nmapc*  *:nmapclear*
 
 
  :vmapc[lear]			|mapmode-v|		*:vmapc*  *:vmapclear*
 
 
  :xmapc[lear]			|mapmode-x|		*:xmapc*  *:xmapclear*
 
 
  :smapc[lear]			|mapmode-s|		*:smapc*  *:smapclear*
 
 
  :omapc[lear]			|mapmode-o|		*:omapc*  *:omapclear*
 
 
  :mapc[lear]!			|mapmode-ic|		*:mapc!*  *:mapclear!*
 
 
  :imapc[lear]			|mapmode-i|		*:imapc*  *:imapclear*
 
 
  :lmapc[lear]			|mapmode-l|		*:lmapc*  *:lmapclear*
 
 
  :cmapc[lear]			|mapmode-c|		*:cmapc*  *:cmapclear*
 
 
  			在映射指令作用的模式中删除_所有_的映射。{Vi 無此功能}
 
 
  			警告: 同時也會删除預設的映射。
 
 
  

 
 
  :map				|mapmode-nvo|
 
 
  :nm[ap]				|mapmode-n|
 
 
  :vm[ap]				|mapmode-v|
 
 
  :xm[ap]				|mapmode-x|
 
 
  :sm[ap]				|mapmode-s|
 
 
  :om[ap]				|mapmode-o|
 
 
  :map!				|mapmode-ic|
 
 
  :im[ap]				|mapmode-i|
 
 
  :lm[ap]				|mapmode-l|
 
 
  :cm[ap]				|mapmode-c|
 
 
  			在映射指令作用的模式中列出所有的鍵映射。注意 ":map" 和
 
 
  			":map!" 是最常用的,因為它們包括其它模式。
 
 
  

 
 
  :map    {lhs}			|mapmode-nvo|		*:map_l*
 
 
  :nm[ap] {lhs}			|mapmode-n|		*:nmap_l*
 
 
  :vm[ap] {lhs}			|mapmode-v|		*:vmap_l*
 
 
  :xm[ap] {lhs}			|mapmode-x|		*:xmap_l*
 
 
  :sm[ap] {lhs}			|mapmode-s|		*:smap_l*
 
 
  :om[ap] {lhs}			|mapmode-o|		*:omap_l*
 
 
  :map!   {lhs}			|mapmode-ic|		*:map_l!*
 
 
  :im[ap] {lhs}			|mapmode-i|		*:imap_l*
 
 
  :lm[ap] {lhs}			|mapmode-l|		*:lmap_l*
 
 
  :cm[ap] {lhs}			|mapmode-c|		*:cmap_l*
 
 
  			在映射指令作用的模式中列出以 {lhs} 開頭的鍵映射的鍵系
 
 
  			列。 {Vi 無此功能}
 
 
  

 
 
  這些指令用于把一個鍵或鍵系列映射成一個字元串。可以用來在功能鍵裡放置一系列命
 
 
  令,把一個鍵轉換成另一個,等等。如何儲存和恢複目前映射可以參考 |:mkexrc|。
 
 
  

 
 
  							*map-ambiguous*
 
 
  當兩個映射以相同的字元順序開始,它們是有二義性的。例如: >
 
 
  	:imap aa foo
 
 
  	:imap aaa bar
 
 
  當 Vim 讀入 "aa" 後,它需要取得另外一個字元才能決定應該映射 "aa" 還是 "aaa"。
 
 
  這意味着輸入 "aa" 後映射還不會展開,Vim 還在等待另一個字元。如果你接着輸入一個
 
 
  空格,那麼将插入 "foo" 加上空格。如果你輸入一個 "a",那麼将插入 "bar"。
 
 
  {Vi 不允許有二義性的映射}
 
 
  

 
 
  

 
 
  1.2 特 殊 參 數						*:map-arguments*
 
 
  

 
 
  "<buffer>","<silent>","<special>"、"<script>"、"<expr>" 和 "<unique>" 可以按
 
 
  任意順序使用。它們必須緊跟在指令的後邊,而在其它任何參數的前邊。
 
 
  

 
 
  				*:map-local* *:map-<buffer>* *E224* *E225*
 
 
  如果這些指令的第一個參數是 "<buffer>",映射将隻局限于目前的緩沖區内。例如: >
 
 
  	:map <buffer>  ,w  /[.,;]<CR>
 
 
  然後你可以在另一個緩沖區内把 ",w" 作另外的映射: >
 
 
  	:map <buffer>  ,w  /[#&!]<CR>
 
 
  局部緩沖區映射在全局映射之前被應用。
 
 
  "<buffer>" 參數也可以用于清除映射: >
 
 
  	:unmap <buffer> ,w
 
 
  	:mapclear <buffer>
 
 
  當一個緩沖區被删除時局部映射也會被清除,但是在它被解除安裝時不會。就象局部選項值的
 
 
  情況一樣。
 
 
  

 
 
  						*:map-<silent>* *:map-silent*
 
 
  要在定義一個映射時不在指令行上回顯該映射,可以使用 "<silent>" 作為第一個參數,
 
 
  例如: >
 
 
  	:map <silent> ,h /Header<CR>
 
 
  在使用這個映射時搜尋字串将不回顯。不過被執行指令的資訊仍然會。要把它也關掉,可
 
 
  以在執行的指令裡加入一個 ":silent": >
 
 
  	:map <silent> ,h :exe ":silent normal /Header\r"<CR>
 
 
  仍然會給出提示,比如使用 inputdialog() 的時候。
 
 
  在縮寫上使用 "<silent>" 是可以的,但它的作用是使指令行不進行重繪。
 
 
  

 
 
  						*:map-<special>* *:map-special*
 
 
  定義映射時,特殊鍵可用 <> 記法,即使 'cpoptions' 包含了 "<" 标志位也沒問題。這
 
 
  可用于不希望看到設定 'cpoptions' 時出現的副作用的場合。例如: >
 
 
  	:map <special> <F12> /Header<CR>
 
 
  <
 
 
  						*:map-<script>* *:map-script*
 
 
  如果給用于定義新映射或縮寫的指令的第一個參數是 "<script>",該映射隻使用通過以
 
 
  "<SID>" 開頭來定義的的腳本局部映射來重映射 {rhs} 中的字元。這可以用于避免來自
 
 
  外部的腳本的幹擾 (舉例來說,在 mswin.vim 中 CTRL-V 被重新映射的時候就是如此),
 
 
  但是又需要使用該腳本中定義的其它映射的情形。
 
 
  備注: ":map <script>" 和 ":noremap <script>" 做同樣的事情。這裡 "<script>" 超
 
 
  越指令名。不過,更推薦使用 ":noremap <script>",因為它更清晰地表示了重映射已被
 
 
  (大多數時候) 禁止。
 
 
  

 
 
  						*:map-<unique>* *E226* *E227*
 
 
  如果給用于定義新映射或縮寫的指令的第一個參數是 "<unique>" 并且它該映射或縮寫已
 
 
  經存在,則該指令會失敗。例如: >
 
 
  	:map <unique> ,w  /[#&!]<CR>
 
 
  定義一個局部映射時,同時也會檢查是否已存在了一個相同的全局映射。
 
 
  這個例子将失敗: >
 
 
  	:map ,w  /[#&!]<CR>
 
 
  	:map <buffer> <unique> ,w  /[.,;]<CR>
 
 
  如果你想給鍵進行映射,但同時又想執行原來映射的内容,參見 |maparg()|。
 
 
  

 
 
  						*:map-<expr>* *:map-expression*
 
 
  如果給用于定義新映射或縮寫的指令的第一個參數是 "<expr>",那麼參數會作為表達式
 
 
  來進行計算,結果作為實際使用的 {rhs}。例如: >
 
 
  	:inoremap <expr> . InsertDot()
 
 
  會插入 InsertDot() 函數的傳回值。這可以用來檢查光标之前的文本并在一定條件下啟
 
 
  動全能 (omni) 補全。
 
 
  

 
 
  要非常小心副作用!計算表達式的同時正在擷取字元,是以很有可能你使得該指令不再可
 
 
  用。為此原因禁止以下行為:
 
 
  - 改變緩沖區文本 |textlock|
 
 
  - 編輯其它緩沖區
 
 
  - |:normal| 指令
 
 
  - 可以移動光标,但事後光标會被恢複
 
 
  - 你可以使用 getchar(),但不能看到已有的預輸入,而新的預輸入也會被丢棄。
 
 
  如果你希望通過映射來完成這些操作,讓傳回的字元做這些事情。
 
 
  

 
 
  這裡是插入遞增的清單編号的例子: >
 
 
  	let counter = 0
 
 
  	inoremap <expr> <C-L> ListItem()
 
 
  	inoremap <expr> <C-R> ListReset()
 
 
  

 
 
  	func ListItem()
 
 
  	  let g:counter += 1
 
 
  	  return g:counter . '. '
 
 
  	endfunc
 
 
  

 
 
  	func ListReset()
 
 
  	  let g:counter = 0
 
 
  	  return ''
 
 
  	endfunc
 
 
  

 
 
  CTRL-L 插入下一個數值,CTRL-R 複位計數且傳回空字元串,這樣就不會插入任何内容。
 
 
  

 
 
  注意 要使特殊鍵工作并轉義文本中的 CSI 位元組需要一些特殊處理。|:map| 指令已經做
 
 
  好了,是以你應該避免做重複的操作。這樣不行: >
 
 
  	:imap <expr> <F3> "<Char-0x611B>"
 
 
  因為 <Char- 序列作為 |:imap| 的參數被轉義,而 <expr> 又做一次。這樣就可以: >
 
 
  	:imap <expr> <F3> "\u611B"
 
 
  在其它文本之前使用單個位元組出現的 0x80 是不行的。它會被看作一個特殊鍵。
 
 
  

 
 
  

 
 
  1.3 映 射 與 運 行 模 式				*:map-modes*
 
 
  			*mapmode-nvo* *mapmode-n* *mapmode-v* *mapmode-o*
 
 
  

 
 
  有五種映射存在
 
 
  - 用于普通模式: 輸入指令時。
 
 
  - 用于可視模式: 可視區域高亮并輸入指令時。
 
 
  - 用于操作符等待模式: 操作符等待中 ("d","y","c" 等等之後)。
 
 
    見下: |omap-info|。
 
 
  - 用于插入模式: 也用于替換模式。
 
 
  - 用于指令行模式: 輸入 ":" 或 "/" 指令時。
 
 
  

 
 
  特殊情況:當在普通模式裡為一個指令輸入一個計數時,對 0 的映射會被禁用。這樣在
 
 
  輸入一個帶有 0 的計數時不會受到對 0 鍵映射的幹擾。
 
 
  

 
 
  						*map-overview* *map-modes*
 
 
  關于每個映射指令對應的工作模式的概況:
 
 
  

 
 
      指令:					模式: ~
 
 
  					普通	可視+選擇	操作符等待 ~
 
 
  :map   :noremap   :unmap   :mapclear	是	是		是
 
 
  :nmap  :nnoremap  :nunmap  :nmapclear	是	-		-
 
 
  :vmap  :vnoremap  :vunmap  :vmapclear	-	是		-
 
 
  :omap  :onoremap  :ounmap  :omapclear	-	-		是
 
 
  

 
 
  修道院之外也有 :nunmap (譯者注: nun,修女)。
 
 
  						*mapmode-x* *mapmode-s*
 
 
  有的指令能同時用于可視和選擇模式,有的隻能用于其中一個。注意 很常見的情況是提
 
 
  到 "可視" 的時候實際同時适用可視和選擇兩種模式。|Select-mode-mapping|
 
 
  

 
 
      指令:				    模式: ~
 
 
  					可視	選擇 ~
 
 
  :vmap  :vnoremap  :vunmap  :vmapclear	是	是
 
 
  :xmap  :xnoremap  :xunmap  :xmapclear	是	-
 
 
  :smap  :snoremap  :sunmap  :smapclear	-	是
 
 
  

 
 
  			*mapmode-ic* *mapmode-i* *mapmode-c* *mapmode-l*
 
 
  有的指令同時支援插入模式和指令行模式,有的不是:
 
 
  

 
 
      指令:					模式: ~
 
 
  					插入	指令行	Lang-Arg ~
 
 
  :map!  :noremap!  :unmap!  :mapclear!	是	是	-
 
 
  :imap  :inoremap  :iunmap  :imapclear	是	-	-
 
 
  :cmap  :cnoremap  :cunmap  :cmapclear	-	是	-
 
 
  :lmap  :lnoremap  :lunmap  :lmapclear	是*	是*	是*
 
 
  

 
 
  原來的 Vi 沒有針對普通/可視/操作符等待模式和針對插入/指令行模式的獨立映射。因
 
 
  此 ":map" 和 ":map!" 指令為多個模式定義和回顯映射。在 Vim 中你可以使用
 
 
  ":nmap"、":vmap"、:omap"、":cmap" 和 ":imap" 指令來對每個不同的模式分别定義映
 
 
  射。
 
 
  

 
 
  							*omap-info*
 
 
  操作符等待映射可以用來定義和任何操作符一起使用的移動指令。簡單例子:
 
 
  ":omap { w" 會使 "y{" 等同于 "yw","d{" 也等同于 "dw"。
 
 
  

 
 
  要忽略光标原來所在的位置并選擇另外的文本,你可以使 omap 進入可視模式來選擇要操
 
 
  作的文本。例如,要在位于目前行的函數名上操作: >
 
 
  	onoremap <silent> F :<C-U>normal! 0f(hviw<CR>
 
 
  CTRL-U (<C-U>) 用于删除指令行上 Vim 可能插入的範圍。普通模式指令尋找第一個 '('
 
 
  字元并選擇之前的第一個單詞。通常那就是函數名了。
 
 
  

 
 
  要為普通和可視模式但不包括操作符等待模式輸入一個映射,首先在所有的三個模式中定
 
 
  義該映射,然後在操作符等待模式中取消該映射: >
 
 
  	:map    xx something-difficult
 
 
  	:ounmap xx
 
 
  對于一個同時用于可視和操作符等待模式、或同時用于普通和操作符等待模式的映射也可
 
 
  照此辦理。
 
 
  

 
 
  						*language-mapping*
 
 
  ":lmap" 定義一個應用于以下情況的映射:
 
 
  - 插入模式
 
 
  - 指令行模式
 
 
  - 輸入一個搜尋模式時
 
 
  - 接受一個文本字元作為參數的指令,比如 "r" 和 "f"
 
 
  - 對于 input() 行
 
 
  更一般地: 任何輸入的字元是緩沖區文本的一部分而非一個 Vim 指令字元的時候。
 
 
  "Lang-Arg" 不是真正的另外一個模式,它僅用來表示這些情況的存在。
 
 
     載入一個相關語言映射集合的最簡單的方法是通過使用 'keymap' 選項。
 
 
  參考 |45.5|。
 
 
     在插入模式和指令行模式中可用 CTRL-^ 指令來關閉映射 |i_CTRL-^| |c_CTRL-^|。
 
 
  普通指令行 (非模式搜尋) 開始輸入時,映射被關閉直到輸入 CTRL-^ 為止。而插入模式
 
 
  和模式搜尋卻會分别記住上次使用的狀态。需要輸入一個字元作為參數的指令,如 "f"
 
 
  或 "t" 之類,也使用插入模式的狀态。
 
 
     語言映射永遠不能應用于已經映射的字元上。它們僅用于鍵入的字元上。這意味着輸
 
 
  入映射時,語言映射已經完成。
 
 
  

 
 
  

 
 
  1.4 列 出 映 射						*map-listing*
 
 
  

 
 
  當列出映射時,前面兩欄的字元表示 (可有多個):
 
 
  

 
 
        字 符	模 式	~
 
 
       <Space>	普通、可視、選擇和操作符等待
 
 
  	n	普通
 
 
  	v	可視和選擇
 
 
  	s	選擇
 
 
  	x	可視
 
 
  	o	操作符等待
 
 
  	!	插入和指令行
 
 
  	i	插入
 
 
  	l	插入、指令行和 Lang-Arg 模式的 ":lmap" 映射
 
 
  	c	指令行
 
 
  

 
 
  {rhs} 之前可能顯示一個特殊字元:
 
 
  	*	表示它不可重映射
 
 
  	&	表示僅腳本的局部映射可以被重映射
 
 
  	@	表示緩沖區的局部映射
 
 
  

 
 
  從 {lhs} 以後的第一個非空字元到行的末尾 (或 '|') 都被認為是 {rhs} 的一部分。這
 
 
  允許 {rhs} 以一個空格結尾。
 
 
  

 
 
  注意: 在可視模式裡使用映射時,你可以使用 "'<" 位置标記,它表示目前緩沖區中最後
 
 
  被選中的可視區域的開始 |'<|。
 
 
  

 
 
  							*:map-verbose*
 
 
  如果 'verbose' 非零,列出鍵映射的同時可以顯示它在哪裡定義。例如: >
 
 
  

 
 
  	:verbose map <C-W>*
 
 
  	n  <C-W>*      * <C-W><C-S>*
 
 
  		Last set from /home/abcd/.vimrc
 
 
  

 
 
  |:verbose-cmd| 說明詳情。
 
 
  

 
 
  

 
 
  1.5 映 射 特 殊 鍵					*:map-special-keys*
 
 
  

 
 
  有三種方法來映射一個特殊鍵:
 
 
  1. Vi 相容的方法: 對鍵碼進行映射。通常這是一個以 <Esc> 開頭的序列。要輸入一個
 
 
     這樣的映射先輸入 ":map " 然後再敲入功能鍵之前得先輸入一個 CTRL-V。注意如果
 
 
     鍵碼在 termcap (t_ 開頭的選項) 裡,它會被自動轉換到内碼并變成映射的第二種方
 
 
     法 (除非 'cpoptions' 裡包括了 'k' 标志位)。
 
 
  2. 第二種方法是使用功能鍵的内碼。要輸入這樣的映射輸入 CTRL-K 并敲要映射的功能
 
 
     鍵,或者使用 "#1","#2",.. "#9","#0","<Up>","<S-Down>","<S-F7>" 等等的
 
 
     形式 (參考鍵表 |key-notation|,所有從 <Up> 開始的鍵都可以使用)。頭十個功能
 
 
     鍵能以兩種方式被定義: 僅用數字,比如 "#2";或者使用 "<F>",如 "<F2>"。兩種
 
 
     都代表功能鍵 F2。"#0" 表示功能鍵 F10,由選項 't_f10' 定義,它在某些鍵盤上可
 
 
     能是 F0。<> 的形式在 'cpoptions' 包含 '<' 标志位時不能使用。
 
 
  3. 使用 termcap 條目,以 <t_xx> 的形式出現,這裡 "xx" 是 termcap 條目的名字。
 
 
     可以使用任何字元串條目。例如: >
 
 
       :map <t_F3> G
 
 
  <  把功能鍵 13 映射成 "G"。'cpoptions' 包括 '<' 标志位時不能使用這種方式。
 
 
  

 
 
  第二種和第三種方法的優點是不加修改就可以在不同的終端上使用 (功能鍵會被轉換成相
 
 
  同的内碼或實際的鍵碼,不論使用何種終端都是如此。termcap 必須正确才能正常工作,
 
 
  并且必須使用相同的映射)。
 
 
  

 
 
  細 節: Vim 首先檢查是否從鍵盤輸入的序列是否已被映射。否的話将試圖使用終端鍵碼
 
 
  (參考 |terminal-options|)。如果找到終端編碼,它會被替換成内碼。然後再次檢查一
 
 
  個映射是否已完成 (是以你也能把一個内碼映射成其它東西)。在腳本檔案中寫入什麼東
 
 
  西取決于何者被識别。如果終端鍵碼被識别為映射,寫入鍵碼本身;如果它被識别為一個
 
 
  終端編碼,則在腳本中寫入内碼。
 
 
  

 
 
  

 
 
  1.6 特 殊 字 符						*:map-special-chars*
 
 
  							*map_backslash*
 
 
  注意這裡僅提及 CTRL-V 可以作為用于映射和縮寫的特殊字元。當 'cpoptions' 不包含
 
 
  'B' 時,反斜杠也可起到 CTRL-V 一樣的作用,這時可以完全地使用 <> 記法 |<>|。但
 
 
  你不能期望 "<C-V>" 像 CTRL-V 那樣轉換後來者的特殊含義。
 
 
  

 
 
  要映射一個反斜杠,或者在 {rhs} 中使用一個字面意義的反斜杠,可以使用特殊字元序
 
 
  列 "<Bslash>" 。這可以避免在使用嵌套映射時使用雙反斜杠的需要。
 
 
  

 
 
  							*map_CTRL-C*
 
 
  {lhs} 裡可以使用 CTRL-C,但隻有在 Vim 等待輸入鍵時才可以,Vim 忙着做别的事情的
 
 
  時候不行。如果 Vim 在忙,CTRL-C 總是中斷/打斷該指令。
 
 
  使用 MS-Windows 上的 GUI 版本時 CTRL-C 能被映射以允許複制到剪貼闆的指令。使用
 
 
  CTRL-Break 來中斷 Vim。
 
 
  

 
 
  							*map_space_in_lhs*
 
 
  要在 {lhs} 中包含一個空格,在前面輸入一個 CTRL-V (每個空格之前實際要輸入兩個
 
 
  CTRL-V)。
 
 
  							*map_space_in_rhs*
 
 
  如果你需要 {rhs} 以空格開頭,使用 "<Space>"。要與 Vi 完全相容 (但不可讀),不要
 
 
  使用 |<>| 記法,在 {rhs} 前面先輸入一個單獨的 CTRL-V (你必須輸入 CTRL-V 兩
 
 
  次)。
 
 
  							*map_empty_rhs*
 
 
  你可以通過在一個單獨的 CTRL-V (你必須輸入 CTRL-V 兩次) 後面什麼也不輸入來建立
 
 
  一個空的 {rhs}。不幸的是在 vimrc 檔案中你不能使用這種方式。
 
 
  

 
 
  							*<Nop>*
 
 
  得到什麼都不做的映射的更容易的方法是在 {rhs} 中使用 "<Nop>"。僅當 |<>| 記法允
 
 
  許時這種方法才生效。例如確定功能鍵 F8 什麼事情都不做:
 
 
  	:map  <F8>  <Nop>
 
 
  	:map! <F8>  <Nop>
 
 
  

 
 
  							*map-multibyte*
 
 
  可以對多位元組字元映射,但隻能是整個字元。不能僅映射第一個位元組。這是為了避免下面
 
 
  場景中的問題:
 
 
  	:set encoding=latin1
 
 
  	:imap <M-C> foo
 
 
  	:set encoding=utf-8
 
 
  <M-C> 的映射是在 latin1 編碼中被定義的,結果是一個 0xc3 位元組。如果你在 UTF-8 
 
 
  解碼中輸入 á (0xe1 <M-a>) 它是雙位元組 0xc3 0xa1。這個時候你不希望 0xc3 位元組被映
 
 
  射,否則的話将不能輸入 á 字元了。
 
 
  

 
 
  					*<Leader>* *mapleader*
 
 
  要定義一個使用 "mapleader" 變量的映射,可以使用特殊字串 "<Leader>"。它會被
 
 
  "mapleader" 的字串值所替換。如果 "mapleader" 未設定或為空,則用反斜杠代替,例
 
 
  如:
 
 
  	:map <Leader>A  oanother line<Esc>
 
 
  和下面一樣: >
 
 
  	:map \A  oanother line<Esc>
 
 
  但是當: >
 
 
  	:let mapleader = ","
 
 
  時,又相當于: >
 
 
  	:map ,A  oanother line<Esc>
 
 
  

 
 
  注意 "mapleader" 的值僅當定義映射時被使用。後來改變的 "mapleader" 不會影響已定
 
 
  義的映射。
 
 
  

 
 
  					*<LocalLeader>* *maplocalleader*
 
 
  <LocalLeader> 和 <Leader> 類似,除了它使用 "maplocalleader" 而非 "mapleader"
 
 
  以外。<LocalLeader> 用于局部于緩沖區的映射,例如: >
 
 
        :map <LocalLeader>q  \DoItNow
 
 
  <
 
 
  在一個全局插件裡應該使用 <Leader> 而在一個檔案類型插件裡應該用 <LocalLeader>。
 
 
  "mapleader" 和 "maplocalleader" 可以是相同的。盡管如此,如果你把它們設為不同,
 
 
  全局插件和檔案類型插件的映射沖突的機會是不是會小一點呢?例如,你可以保持把
 
 
  "mapleader" 設定為預設的反斜杠,而設定 "maplocalleader" 為下劃線。
 
 
  

 
 
  							*map-<SID>*
 
 
  在一個腳本中有一個特殊關鍵字叫 "<SID>" 能被用來定義一個局部于腳本中的映射。
 
 
  具體細節請參考 |<SID>|。
 
 
  

 
 
  							*<Plug>*
 
 
  叫做 "<Plug>" 的特殊關鍵字可以用于一個内部映射,它不與任何鍵的序列比對。這在插
 
 
  件中有用 |using-<Plug>|。
 
 
  

 
 
  							*<Char>* *<Char->*
 
 
  要根據一個字元的十進制,八進制或十六進制數字形式進行映射,可以使用 <Char> 來構
 
 
  造:
 
 
  	<Char-123>	字元 123
 
 
  	<Char-033>	字元 27
 
 
  	<Char-0x7f>	字元 127
 
 
  它可以用來在一個 'keymap' 檔案裡指定一個 (多位元組) 字元。大小寫的差別此處不計。
 
 
  

 
 
  							*map-comments*
 
 
  在這些指令的後面不可能放置注釋,因為 '"' 字元被認為是 {lhs} 或 {rhs} 的一部
 
 
  分。
 
 
  

 
 
  							*map_bar*
 
 
  因為字元 '|' 用來分隔映射指令和後面的指令,是以包括 '|' 的 {rhs} 要做一些特殊
 
 
  的處理,有三種方法:
 
 
     使用	     可用于			   示例	~
 
 
     <Bar>     '<' 不在 'cpoptions' 裡	   :map _l :!ls <Bar> more^M
 
 
     \|	     'b' 不在 'cpoptions' 裡	   :map _l :!ls \| more^M
 
 
     ^V|	     總可以,Vim 和 Vi 都行	   :map _l :!ls ^V| more^M
 
 
  

 
 
  (這裡 ^V 表示 CTRL-V;要輸入一個 CTRL-V 你必須按鍵兩次;在這裡不能使用 <> 記法
 
 
  "<C-V>")。
 
 
  

 
 
  當你使用 'cpoptions' 的預設設定時三種方式都可以正常工作。
 
 
  

 
 
  當 'b' 出現在 'cpoptions' 中時,"\|" 會被認為是一個映射的結束,後面的是另一個
 
 
  指令。這是為了和 Vi 相容,但是和其它指令比較時有點不合常理。
 
 
  

 
 
  							*map_return*
 
 
  當你的映射包含 Ex 指令時,你需要在其後放置行終結符才能讓它執行。在這裡推薦使用
 
 
  <CR>  (參考 |<>|)。例如: >
 
 
     :map  _ls  :!ls -l %<CR>:echo "the end"<CR>
 
 
  

 
 
  在插入或指令行模式中輸入時要避免字元被映射,可以先輸入一個 CTRL-V。在插入模式
 
 
  中如果 'paste' 選項被打開的話,映射也會被禁止。
 
 
  

 
 
  注意 當遇到錯誤時 (會導緻一個錯誤資訊或蜂鳴) 剩下的映射将不會被執行。這是為了
 
 
  保持和 Vi 相容。
 
 
  

 
 
  注意 @zZtTfF[]rm'`"v 和 CTRL-X 指令的第二個字元 (參數) 不被映射。這樣做是為了
 
 
  能夠使用所有的命名寄存器和位置标記,即使同名的指令被映射時也是如此。
 
 
  

 
 
  

 
 
  1.7 映 射 哪 些 鍵					*map-which-keys*
 
 
  

 
 
  如果你要做一些映射,你得選擇在 {lhs} 中要用哪些鍵。你應該避免使用 Vim 指令所使
 
 
  用的那些鍵。否則你将不能再使用這些指令了。下面是一些建議:
 
 
  - 功能鍵 <F2>、<F3> 等;Shift 加功能鍵 <S-F1>、<S-F2> 等等。注意 <F1> 已經用作
 
 
    幫助指令。
 
 
  - 帶 Meta 的鍵 (和 ALT 鍵一起按下)。|:map-alt-keys|
 
 
  - 使用 '_' 或 ',' 字元然後加上任何其它的字元。"_" 和 "," 指令在 Vim 中是存在
 
 
    的 (參考 |_| 和 |,|),但你也許永遠不會用到它們。
 
 
  - 使用和其它指令的同義的熱鍵。例如: CTRL-P 和 CTRL-N。使用一個附加的字元可以定
 
 
    義更多的映射。
 
 
  

 
 
  參考檔案 "index" 可以知道哪些鍵沒有被使用,進而使映射不會覆寫任何内建的功能。
 
 
  也可使用 ":help {key}^D" 來找出是否一個鍵已經用于某些指令。 ({key} 用于指定你
 
 
  要尋找的鍵,^D 是 CTRL-D)。
 
 
  

 
 
  

 
 
  1.8 示 例						*map-examples*
 
 
  

 
 
  以下是一些例子 (照字面輸入它們,對于 "<CR>" 你輸入四個字元;為此 '<' 标志位不
 
 
  應出現在 'cpoptions' 中)。 >
 
 
  

 
 
     :map <F3>  o#include
 
 
     :map <M-g> /foo<CR>cwbar<Esc>
 
 
     :map _x    d/END/e<CR>
 
 
     :map! qq   quadrillion questions
 
 
  

 
 
  計數相乘
 
 
  

 
 
  如果你在激活映射前輸入計數,實際效果就像是該計數在 {lhs} (譯者注: 疑為 {rhs})
 
 
  之前輸入一樣。例如,對下面的映射: >
 
 
     :map <F4>  3w
 
 
  輸入 2<F4> 會得到 "23w"。不是移動 2 * 3 個單詞,而是 23 個單詞。
 
 
  如果你希望得到計數相乘的效果,可使用表達式寄存器: >
 
 
     :map <F4>  @='3w'<CR>
 
 
  引号之間的部分是待執行的表達式。 |@=|
 
 
  

 
 
  

 
 
  1.9 使 用 映 射						*map-typing*
 
 
  

 
 
  當你輸入一個被映射序列的頭部時 Vim 開始比較你的輸入。如果比對尚不完全,它會等
 
 
  待更多的字元輸入直到可以确定是否比對。例如: 如果你映射了 map! "qq",然後你輸入
 
 
  的第一個 'q' 将不會顯示在螢幕上,直到你輸入另一個 'q' 或其它字元。如果打開了
 
 
  'timeout' 選項 (這是預設選項) Vim 僅會等待一秒鐘 (或任何 'timeoutlen' 指定的時
 
 
  間)。之後,它假定 'q' 已經不會再被輸入。如果你的輸入很慢,或者你的系統很慢,複
 
 
  位 'timeout' 選項。這時,你可能還需要是否置位 'ttimeout' 選項。
 
 
  

 
 
  							*map-keys-fails*
 
 
  有若幹情況鍵碼可能不被識别:
 
 
  - Vim 僅能讀取部分的鍵碼。通常僅僅是第一個字元。在某些 Unix 版本的 xterm 上有
 
 
    這種情況。
 
 
  - 鍵碼在已經映射的字元之後。舉例來說,"<F1><F1>" 或 "g<F1>"。
 
 
  

 
 
  其結果是在這種情況下鍵碼不會被識别,是以映射失敗。有兩種方法可以避免此問題:
 
 
  

 
 
  - 從 'cpoptions' 中删除 'K' 标志位。這會使 Vim 等待功能鍵的其餘部分。
 
 
  - 使用 <F1> 到 <F4> 時,實際産生的鍵碼可能是 <xF1> 到 <xF4>。存在 <xF1> 到
 
 
    <F1>,<xF2> 到 <F2> 的映射等,但是在映射的後一半的那些依然不會被識别。确認從
 
 
    <F1> 到 <F4> 的鍵碼是正确的: >
 
 
  	:set <F1>=<type CTRL-V><type F1>
 
 
  < 以四個字元輸入 <F1>。"=" 号後面的部分必需以實際的字元輸入,而不是字面的文
 
 
    本。
 
 
  另一種解決方法是在映射中為第二個特殊鍵使用實際的鍵碼: >
 
 
  	:map <F1><Esc>OP :echo "yes"<CR>
 
 
  不要輸入一個真正的 <Esc>,總之 Vim 将識别鍵碼并把它替換為 <F1>。
 
 
  

 
 
  另一個問題可能是保持 ALT 或 Meta 的時候,終端在前面附加 ESC 而不是給第 8 位置
 
 
  位。見 |:map-alt-keys|。
 
 
  

 
 
  						*recursive_mapping*
 
 
  如果 {rhs} 中包括了 {lhs},那麼你定義了一個遞歸映射。當 {lhs} 被輸入,它會被替
 
 
  換成 {rhs}。當遇到 {rhs} 中包含的 {lhs} 又會被替換成 {rhs},依此類推。
 
 
  這可用來使一個指令重複無數次。這種情況唯一的問題是出錯是停止它的唯一方法。解決
 
 
  迷宮的宏會用到這個,去那裡找找例子吧。有一個例外: 如果 {rhs} 以 {lhs} 開始,第
 
 
  一個字元不會被再次映射 (這與 Vi 相容)。
 
 
  例如: >
 
 
     :map ab abcd
 
 
  将執行 "a" 指令并且在文本中插入 "bcd"。{rhs} 中的 "ab" 不會被再次映射。
 
 
  

 
 
  如果你要交換兩個鍵的含義,應該使用 :noremap 指令。例如: >
 
 
     :noremap k j
 
 
     :noremap j k
 
 
  這會交換光标上移和光标下移指令。
 
 
  

 
 
  如果使用普通 :map 指令,并且 'remap' 選項被打開,映射一直進行直到文本不再是某
 
 
  個 {lhs} 的一部分。例如,如果你用: >
 
 
     :map x y
 
 
     :map y x
 
 
  Vim 将把 x 替換成 y,并把 y 替換成 x,等等。這種情況會發生 'maxmapdepth' 次
 
 
  (預設為 1000),然後 Vim 會給出錯誤資訊 "recursive mapping" (遞歸映射)。
 
 
  

 
 
  							*:map-undo*
 
 
  如果你在一個被映射的序列中包含了一個 undo 指令,将會把文本帶回宏執行前的狀态。
 
 
  這和原始的 Vi 是相容的,隻要被映射的序列僅包含一個 undo 指令 (原始的 Vi 中被映
 
 
  射的序列有兩個 undo 指令是無意義的,你會得到第一個 undo 之前的文本)。
 
 
  

 
 
  

 
 
  1.10 映 射 ALT 鍵					*:map-alt-keys*
 
 
  

 
 
  GUI 上,Vim 自己處理 Alt 鍵,是以用 ALT 鍵的映射應該總沒有問題。但在終端上,
 
 
  Vim 得到位元組的序列,它必須自己判斷是不是按了 ALT 鍵。
 
 
  

 
 
  Vim 預設假設按下 ALT 鍵等于置位輸入字元的第 8 位。多數正常的終端如此工作,包括
 
 
  xterm、aterm 和 rxvt。假如你的 <A-k> 映射不能工作,可能的原因是你的終端用在字
 
 
  符前加上 ESC 字首的方法。但是你本來也可能在字元前輸入 ESC,這時 Vim 就不知道到
 
 
  底發生了什麼 (隻能檢查字元間的延遲,但這并不可靠)。
 
 
  

 
 
  在此文寫作時,有些主流的終端,如 gnome-terminal 和 konsole,使用 ESC 字首。沒
 
 
  有辦法讓它們用置位第 8 位來代替。Xterm 預設應該沒有問題。Aterm 和 rxvt 啟動時
 
 
  如果使用 "--meta8" 參數也可以如此。你也可以修改資源來達到目的:
 
 
  "metaSendsEscape"、"eightBitInput" 和 "eightBitOutput"。
 
 
  

 
 
  Linux 控制台上,可以用 "setmetamode" 指令切換此行為。記住不使用 ESC 字首可能和
 
 
  其它程式發生沖突。確定你的 bash 把 "convert-meta" 選項設為 "on",確定 Meta 鍵
 
 
  盤綁定仍然工作 (這是預設的 readline 行為,除非你的系統配置專門作了改變)。為
 
 
  此,你需要加入這行: >
 
 
  

 
 
  	set convert-meta on
 
 
  

 
 
  到你的 ~/.inputrc 檔案。如果你建立此檔案,可能想把: >
 
 
  

 
 
  	$include /etc/inputrc
 
 
  

 
 
  放在第一行,如果此檔案在你的系統中存在的話。這樣可以保持全局的選項設定。不過,
 
 
  這可能會使 umlaut 這樣的特殊字元的輸入有問題。這時,輸入字元前用 CTRL-V 前導。
 
 
  

 
 
  要知道有報告說 convert-meta 使得 UTF-8 locale 的使用有問題。在 xterm 這樣的終
 
 
  端裡,可以在 "Main Options" 菜單裡随時切換 "metaSendsEscape" 資源,或者終端上
 
 
  按 Ctrl-LeftClick 也可以;如果你需要給 Vim 之外的其它應用程式發送 ESC,這是最
 
 
  後應急的方法。
 
 
  

 
 
  

 
 
  1.11 映 射 操 作 符					*:map-operator*
 
 
  

 
 
  操作符應用于 {motion} 指令之前。要定義你自己的操作符,你需要先建立映射來設定
 
 
  'operatorfunc' 選項,然後調用 |[email protected]| 操作符。這樣使用者輸入 {motion} 指令後,會調
 
 
  用指定的函數。
 
 
  

 
 
  							*[email protected]* *E774* *E775*
 
 
  [email protected]{motion}		調用 'operatorfunc' 選項設定的函數。
 
 
  			'[ 位置标記定位在 {motino} 跨越的文本的開始處,而 ']
 
 
  			位置标記在此文本的結束處。
 
 
  			函數調用時,帶一個字元串參數:
 
 
  			      參數               如果
 
 
  			    "line"	{motion} 本是 |linewise|
 
 
  			    "char"	{motion} 本是 |characterwise|
 
 
  			    "block"	{motion} 本是 |blockwise-visual||
 
 
  			不過,"block" 很少出現,因為它隻能來自可視模式,那裡
 
 
  			"[email protected]" 不是很有用。
 
 
  			{僅當編譯時加入 +eval 特性才有效}
 
 
  

 
 
  這裡是一例,<F4> 來計算空格數目: >
 
 
  

 
 
  	nmap <silent> <F4> :set opfunc=CountSpaces<CR>[email protected]
 
 
  	vmap <silent> <F4> :<C-U>call CountSpaces(visualmode(), 1)<CR>
 
 
  

 
 
  	function! CountSpaces(type, ...)
 
 
  	  let sel_save = &selection
 
 
  	  let &selection = "inclusive"
 
 
  	  let reg_save = @@
 
 
  

 
 
  	  if a:0  " 在可視模式裡調用,使用 '< 和 '> 位置标記。
 
 
  	    silent exe "normal! `<" . a:type . "`>y"
 
 
  	  elseif a:type == 'line'
 
 
  	    silent exe "normal! '[V']y"
 
 
  	  elseif a:type == 'block'
 
 
  	    silent exe "normal! `[\<C-V>`]y"
 
 
  	  else
 
 
  	    silent exe "normal! `[v`]y"
 
 
  	  endif
 
 
  

 
 
  	  echomsg strlen(substitute(@@, '[^ ]', '', 'g'))
 
 
  

 
 
  	  let &selection = sel_save
 
 
  	  let @@ = reg_save
 
 
  	endfunction
 
 
  <
 
 
  注意 'selection' 選項暫時設為 "inclusive",以便可視模式下用 '[ 到 '] 位置标記
 
 
  可以抽出正确的文本。
 
 
  

 
 
  也要 注意 這裡為可視模式提供了專用的映射。它先删除 ":" 在可視模式裡插入的
 
 
  "'<,'>" 範圍,然後調用函數,調用時使用了 visualmode() 和一個額外的參數。
 
 
  

 
 
  ==============================================================================
 
 
  2. 縮寫			*abbreviations* *Abbreviations*
 
 
  

 
 
  縮寫在插入,替換和指令行模式中使用。如果你輸入一個是縮寫的單詞,它會被替換成所
 
 
  表示的東西。這可以在經常輸入的長單詞時節省鍵擊。并且能用它來自動更正經常犯的拼
 
 
  寫錯誤。例如:
 
 
  

 
 
  	:iab ms Microsoft
 
 
  	:iab tihs this
 
 
  

 
 
  有三種類型的縮寫:
 
 
  

 
 
  full-id	  "full-id" 類型完全由關鍵字字元組成 (字母和 'iskeyword' 選項的字元)。
 
 
  	  這是最普通的縮寫。
 
 
  

 
 
  	  例如: "foo","g3","-1"
 
 
  

 
 
  end-id	  "end-id" 類型以一個關鍵字字元結尾,但所有其它字元都不是關鍵字字元。
 
 
  

 
 
  	  例如: "#i","..f","$/7"
 
 
  

 
 
  non-id	  "non-id" 類型以一個非關鍵字字元結尾,其它字元可以是任意類型,除了空
 
 
  	  格和制表。{Vi 不支援這種類型}
 
 
  

 
 
  	  例如: "def#","4/7$"
 
 
  

 
 
  不能被縮寫的字串例子: "a.b","#def","a b","_$r"
 
 
  

 
 
  僅當你輸入一個非關鍵字字元時縮寫才會被識别,這也包括用 <Esc> 退出插入模式或用
 
 
  <CR> 結束一個指令的情形。結束縮寫的非關鍵字字元被插入到縮寫的擴充後面。一個例
 
 
  外是字元 <C-]>,它用來擴充一個縮寫,但不插入任何附加字元。
 
 
  

 
 
  例如: >
 
 
     :ab hh	hello
 
 
  <	    "hh<Space>" 被擴充為 "hello<Space>"
 
 
  	    "hh<C-]>" 被擴充為 "hello"
 
 
  

 
 
  光标前的字元必需和縮寫比對。每種類型還有附加規則:
 
 
  

 
 
  full-id	  比對的前面是一個非關鍵字字元,或者是在行或插入的開始。例外: 當縮寫僅
 
 
  	  有一個字元時,如果它前面有一個非關鍵字字元則不會被識别,除非那是空格
 
 
  	  和制表。
 
 
  

 
 
  end-id	  比對的前面是一個關鍵字字元,或者空格或制表,或者行或插入的開始。
 
 
  

 
 
  non-id	  比對的前面是一個空格、制表或者行或插入的開始。
 
 
  

 
 
  例如: ({CURSOR} 是你輸入一個非關鍵字字元的地方) >
 
 
     :ab foo   four old otters
 
 
  <		" foo{CURSOR}"	  被擴充為 " four old otters"
 
 
  		" foobar{CURSOR}" 不被擴充
 
 
  		"barfoo{CURSOR}"  不被擴充
 
 
  >
 
 
     :ab #i #include
 
 
  <		"#i{CURSOR}"	  被擴充為 "#include"
 
 
  		">#i{CURSOR}"	  不被擴充
 
 
  >
 
 
     :ab ;; <endofline>
 
 
  <		"test;;"	  不被擴充
 
 
  		"test ;;"	  被擴充為 "test <endofline>"
 
 
  

 
 
  要在插入模式中避免縮寫: 輸入縮寫的一部分,以 <Esc> 退出插入模式,再用 'a' 重新
 
 
  進入插入模式并輸入剩下的部分。或者在縮寫之後的字元前面輸入 CTRL-V。
 
 
  要在指令行模式中避免縮寫: 在縮寫的某處輸入 CTRL-V 兩次來避免它被替換。不然,一
 
 
  個普通字元前面的 CTRL-V 通常會被忽略。
 
 
  

 
 
  縮寫進行之後移動光标是可能的: >
 
 
     :iab if if ()<Left>
 
 
  如果 'cpoptions' 裡面包含 '<' 标志位時,這不能正常工作。|<>|
 
 
  

 
 
  你甚至可以做更複雜的事情。例如,要消滅一個縮寫後面輸入的空格: >
 
 
     func Eatchar(pat)
 
 
        let c = nr2char(getchar(0))
 
 
        return (c =~ a:pat) ? '' : c
 
 
     endfunc
 
 
     iabbr <silent> if if ()<Left><C-R>=Eatchar('\s')<CR>
 
 
  

 
 
  沒有預設的縮寫。
 
 
  

 
 
  縮寫永遠不會遞歸。你可以設定 ":ab f f-o-o" 而不會有任何問題。但是縮寫能被映
 
 
  射。{一些版本的 Vi 支援遞歸縮寫,這毫無道理}
 
 
  

 
 
  'paste' 選項打開時,縮寫被禁止。
 
 
  

 
 
  				*:abbreviate-local* *:abbreviate-<buffer>*
 
 
  和映射一樣,縮寫可以被局部于一個緩沖區之内。這經常用于 |filetype-plugin| 文
 
 
  件。一個 C 插件檔案的例子: >
 
 
  	:abb <buffer> FF  for (i = 0; i < ; ++i)
 
 
  <
 
 
  						*:ab* *:abbreviate*
 
 
  :ab[breviate]		列出所有的縮寫。第一欄中的字元表示該縮寫作用的模式:
 
 
  			'i' 指插入模式,'c' 指指令行模式,'!' 指兩種模式都有。
 
 
  			這和映射的相同,參看 |map-listing| 。
 
 
  

 
 
  						*:abbreviate-verbose*
 
 
  如果 'verbose' 非零,縮寫列出的同時顯示它最近定義的位置。例如: >
 
 
  

 
 
  	:verbose abbreviate
 
 
  	!  teh		 the
 
 
  		Last set from /home/abcd/vim/abbr.vim
 
 
  

 
 
  |:verbose-cmd| 說明詳情。
 
 
  

 
 
  :ab[breviate] {lhs}	列出以 {lhs} 開頭的縮寫
 
 
  

 
 
  :ab[breviate] [<expr>] {lhs} {rhs}
 
 
  			增加一個從 {lhs} 到 {rhs} 的縮寫。如果 {lhs} 已經存在
 
 
  			則它會被替換成新的 {rhs}。{rhs} 可包含空格。
 
 
  			|:map-<expr>| 說明可選的 <expr> 參數。
 
 
  

 
 
  						*:una* *:unabbreviate*
 
 
  :una[bbreviate] {lhs}	從清單中删除 {lhs} 的縮寫。如果找不到,删除 {rhs} 比對
 
 
  			這裡的 {lhs} 參數的縮寫。這是為了友善你删除擴充後的縮
 
 
  			寫。要避免擴充,插入 CTRL-V (記住輸入兩次)。
 
 
  

 
 
  						*:norea* *:noreabbrev*
 
 
  :norea[bbrev] [<expr>] [lhs] [rhs]
 
 
  			與 ":ab" 一樣,但 {rhs} 不進行重映射。{Vi 無此功能}
 
 
  

 
 
  						*:ca* *:cabbrev*
 
 
  :ca[bbrev] [<expr>] [lhs] [rhs]
 
 
  			與 ":ab" 一樣,但僅在指令行模式中使用。{Vi 無此功能}
 
 
  

 
 
  						*:cuna* *:cunabbrev*
 
 
  :cuna[bbrev] {lhs}	與 ":una" 一樣,但僅在指令行模式中使用。{Vi 無此功能}
 
 
  

 
 
  						*:cnorea* *:cnoreabbrev*
 
 
  :cnorea[bbrev] [<expr>] [lhs] [rhs]
 
 
  			與 ":ab" 一樣,但僅在指令行模式中使用并且 {rhs} 不進行
 
 
  			重映射。{Vi 中無此功能}
 
 
  

 
 
  						*:ia* *:iabbrev*
 
 
  :ia[bbrev] [<expr>] [lhs] [rhs]
 
 
  			與 ":ab" 一樣,但僅在插入模式中使用。{Vi 無此功能}
 
 
  

 
 
  						*:iuna* *:iunabbrev*
 
 
  :iuna[bbrev] {lhs}	與 ":una" 一樣,但僅在插入模式中使用。{Vi 無此功能}
 
 
  

 
 
  						*:inorea* *:inoreabbrev*
 
 
  :inorea[bbrev] [<expr>] [lhs] [rhs]
 
 
  			與 ":ab" 一樣,但僅在插入模式中使用并且 {rhs} 不進行重
 
 
  			映射。{Vi 無此功能}
 
 
  

 
 
  							*:abc* *:abclear*
 
 
  :abc[lear]		删除所有的縮寫。{Vi 無此功能}
 
 
  

 
 
  							*:iabc* *:iabclear*
 
 
  :iabc[lear]		為插入模式删除所有的縮寫。{Vi 無此功能}
 
 
  

 
 
  							*:cabc* *:cabclear*
 
 
  :cabc[lear]		為指令行模式删除所有的縮寫。{Vi 無此功能}
 
 
  

 
 
  							*using_CTRL-V*
 
 
  在一個縮寫的 {rhs} 中使用特殊字元是可能的。CTRL-V 可以用來避免多數不可顯示字元
 
 
  的特殊含義。需要輸入多少個 CTRL-V 取決于你如何輸入縮寫。此處讨論同樣适用于映
 
 
  射。這裡使用一個例子說明。
 
 
  

 
 
  假設你需要把 "esc" 縮寫為輸入一個 <Esc> 字元。當你在 Vim 中輸入 ":ab" 指令,你
 
 
  必需這樣輸入: (這裡 ^V 是一個 CTRL-V 并且 ^[ is <Esc>)
 
 
  

 
 
  你輸入:   ab esc ^V^V^V^V^V^[
 
 
  

 
 
  	所有的鍵盤輸入都經過 ^V 引用解釋,是以第一個,第三個,和第五個 ^V 字元
 
 
  	隻是為了把第二個、第四個  ^V 和 ^[ 輸入到指令行裡。
 
 
  

 
 
  你看到:    ab esc ^V^V^[
 
 
  

 
 
  	指令行裡在 ^[ 之前包含兩個實際的 ^V。如果你采用這種方法,這是該行在你
 
 
  	的 .exrc 檔案應該出現的樣子。第一個 ^V 作為引用第二個 ^V 的字元: 這是
 
 
  	因為 :ab 指令使用 ^V 作為它自己的引用字元,以便你能在縮寫中包含被引用
 
 
  	的空白字元或 | 字元。:ab 指令對 ^[ 字元并不做特殊的事情,是以它不需要
 
 
  	被引用。(盡管引用也沒有害處;因而輸入 7 個 [8 個不行!] ^V 也會工
 
 
  	作。)
 
 
  

 
 
  被儲存為:  esc     ^V^[
 
 
  

 
 
  	解析後,該縮寫的簡短形式 ("esc") 和擴充形式 (兩字元 "^V^[") 被儲存在縮
 
 
  	寫表中。如果輸入不帶參數的 :ab 指令,這是該縮寫被顯示的形式。
 
 
  

 
 
  	然後當使用者輸入單詞 "esc" 而擴充該縮寫時,擴充形式服從和一般鍵盤輸入同
 
 
  	樣形式的 ^V 解釋。是以 ^V 保護 ^[ 字元不被解釋為 "退出插入模式" 的字
 
 
  	符,而把 ^[ 插入到文本裡。
 
 
  

 
 
  擴充為: ^[
 
 
  

 
 
  [Steve Kirkendall 提供示例]
 
 
  

 
 
  ==============================================================================
 
 
  3. 局部映射和函數				*script-local*
 
 
  

 
 
  當使用多個 Vim 腳本檔案時,一個腳本和另一個腳本使用同樣名字的映射和函數是危險
 
 
  的。為了避免這種情況,它們可以局部在腳本。
 
 
  

 
 
  						*<SID>* *<SNR>* *E81*
 
 
  字串 "<SID>" 能用于映射或菜單。這要求 'cpoptions' 中沒有 '<' 标志位。
 
 
     當執行映射指令時,Vim 将把 "<SID>" 替換成特殊鍵碼 <SNR>,後跟一個每個腳本唯
 
 
  一的數字編号,和一個下劃線。例如: >
 
 
  	:map <SID>Add
 
 
  會定義一個映射 "<SNR>23_Add"。
 
 
  

 
 
  當在一個腳本中定義一個函數的時候,可以在名字的前面用一個 "s:" 來使它局部于腳本
 
 
  中。但當一個映射 (譯者注: 似應為函數) 從腳本外面被執行時,它不知道該函數在哪個
 
 
  腳本中被定義。為了避免這種情況,使用 "<SID>" 來代替 "s:"。映射也做同樣的變換。
 
 
  這使得在映射裡可以定義一個函數調用。
 
 
  

 
 
  當一個局部函數被執行時,它在定義腳本的上下文中運作。這意味着,它定義的新函數和
 
 
  映射也可以使用  "s:" 或 "<SID>",并且使用和函數本身定義時相同的唯一數字編号。
 
 
  此外,也能用 "s:var" 腳本局部變量。
 
 
  

 
 
  當執行一個自動指令或一個使用者指令時,它将在定義腳本的上下文中運作。這使得該指令
 
 
  可以調用一個局部函數或者使用一個局部映射。
 
 
  

 
 
  除此以外,在腳本上下文之外使用 "<SID>" 是錯誤的。
 
 
  

 
 
  如果你需要在一個複雜的腳本中取得腳本的數字編号,使用此函數: >
 
 
  	function s:SID()
 
 
  	  return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
 
 
  	endfun
 
 
  

 
 
  列出函數和映射時會顯示 "<SNR>"。可以用來它們在哪裡被定義。
 
 
  

 
 
  指令 |:scriptnames| 可以用來檢視哪些腳本已經被讀入以及它們的 <SNR> 數字編号。
 
 
  

 
 
  這些都是 {Vi 無此功能} 并且 {僅當編譯時加入 +eval 特性才有效}。
 
 
  

 
 
  ==============================================================================
 
 
  4. 使用者定義的指令				*user-commands*
 
 
  

 
 
  可以定義你自己的 Ex 指令。使用者自定義指令可以和内建指令一樣運作 (它可以有範圍或
 
 
  參數,參數可以是自動補全的檔案名或緩沖區名,等等),除了當該指令執行時,它會被
 
 
  轉換成一個普通的 ex 指令然後再被執行以外。
 
 
  

 
 
  對于初學者來說: 參考使用者手冊中的 |40.2| 。
 
 
  

 
 
  						*E183* *user-cmd-ambiguous*
 
 
  所有使用者定義的指令都必須以大寫字母開頭,來避免與内建指令的沖突。(要注意的是,
 
 
  有少數内建指令比如 :Next,:Print and :X,也以大寫字母開頭。在這些情況下内建的
 
 
  指令總是優先執行的)。使用者指令的其它字元可以是大寫字母,小寫字母或數字。當使用
 
 
  數字時,小心會和其它以數字作為參數的指令混淆。例如,指令 ":Cc2" 可能是不帶參數
 
 
  的使用者指令 ":Cc2",也可能是參數為 "2" 的指令 "Cc"。建議在指令名和參數之間放置
 
 
  一個空格來避免這些問題。
 
 
  

 
 
  當使用一個使用者定義的指令時,該指令可以縮寫。但是,如果縮寫不唯一,會發生錯誤。
 
 
  此外,内建指令總是優先執行。
 
 
  

 
 
  例如: >
 
 
  	:command Rename ..。
 
 
  	:command Renumber ..。
 
 
  	:Rena				" 意味着 "Rename"
 
 
  	:Renu				" 意味着 "Renumber"
 
 
  	:Ren				" 錯誤 - 有二義性
 
 
  	:command Paste ..。
 
 
  	:P				" 内建的 :Print
 
 
  

 
 
  建議在腳本中使用使用者自定義指令的全名。
 
 
  

 
 
  :com[mand]						*:com* *:command*
 
 
  			列出所有使用者自定義指令。在列出指令時,
 
 
  			前兩欄的字元表示
 
 
  			    !	指令有 -bang 屬性
 
 
  			    "	指令有 -register 屬性
 
 
  			    b	指令局部于目前緩沖區
 
 
  			(下面給出屬性的較長的描述)
 
 
  

 
 
  :com[mand] {cmd}	列出以 {cmd} 開頭的使用者指令
 
 
  

 
 
  							*:command-verbose*
 
 
  如果 'verbose' 非零,指令列出的同時顯示它最近定義的位置。例如: >
 
 
  

 
 
      :verbose command TOhtml
 
 
  <	Name	    Args Range Complete  Definition ~
 
 
  	TOhtml	    0	 %		 :call Convert2HTML(<line1>, <line2>) ~
 
 
  	    Last set from /usr/share/vim/vim-7.0/plugin/tohtml.vim ~
 
 
  

 
 
  |:verbose-cmd| 介紹詳情。
 
 
  

 
 
  							*E174* *E182*
 
 
  :com[mand][!] [{attr}...] {cmd} {rep}
 
 
  			定義一個使用者指令。指令的名字是 {cmd},而替換的文本是
 
 
  			{rep}。該指令的屬性 (參考下面) 是 {attr}。如果該指令已
 
 
  			存在,報錯,除非已經指定了一個 !,這種情況下指令被重定
 
 
  			義。
 
 
  

 
 
  :delc[ommand] {cmd}				*:delc* *:delcommand* *E184*
 
 
  			删除使用者定義指令 {cmd}。
 
 
  

 
 
  :comc[lear]						*:comc* *:comclear*
 
 
  			删除所有使用者定義指令。
 
 
  

 
 
  指令屬性
 
 
  

 
 
  Vim 和任何其它 ex 指令一樣對待使用者自定義指令。它能有參數,也可以指定範圍。參數
 
 
  可以進行檔案名,緩沖區等補全。具體的工作方式取決于指令的屬性,屬性在指令被定義
 
 
  時被指定。
 
 
  

 
 
  屬性可分四大類: 參數處理、補全行為、範圍處理和特殊情況。下面分類描述之。
 
 
  

 
 
  參數處理					*E175* *E176* *:command-nargs*
 
 
  

 
 
  預設時,使用者自定義指令不接受參數 (如果使用了任何參數會報錯)。但通過使用 -nargs
 
 
  屬性可以允許指令接受參數。有效的值為:
 
 
  

 
 
  	-nargs=0    不允許有參數 (預設情況)
 
 
  	-nargs=1    要求一個參數
 
 
  	-nargs=*    允許任何數目的參數 (0,1 或更多)
 
 
  	-nargs=?    允許 0 或 1 個參數
 
 
  	-nargs=+    必需給出參數,但是數目任意
 
 
  

 
 
  這個上下文中認為 (未轉義的) 空格或制表用來分隔參數。
 
 
  

 
 
  注意 參數被作為文本使用,不是表達式。特别是,"s:var" 會使用定義指令的腳本的局
 
 
  部變量,不是執行時的!例如:
 
 
      script1.vim: >
 
 
  	:let s:error = "None"
 
 
  	:command -nargs=1 Error echoerr <args>
 
 
  <   script2.vim: >
 
 
  	:source script1.vim
 
 
  	:let s:error = "Wrong!"
 
 
  	:Error s:error
 
 
  執行 script2.vim 會回顯 "None",不是你想要的!解決方法可以通過調用函數實作。
 
 
  

 
 
  自動補全行為					*:command-completion* *E179*
 
 
  					*E180* *E181* *:command-complete*
 
 
  預設時,使用者定義指令的參數不進行自動補全。但是,通過指定以下的一個或多個屬性
 
 
  後,參數可以進行自動補全:
 
 
  

 
 
  	-complete=augroup	自動指令組
 
 
  	-complete=buffer	緩沖區名
 
 
  	-complete=command	Ex 指令 (及其參數)
 
 
  	-complete=dir		目錄名
 
 
  	-complete=environment	環境變量名
 
 
  	-complete=event		自動指令事件
 
 
  	-complete=expression	Vim 表達式
 
 
  	-complete=file		檔案和目錄名
 
 
  	-complete=shellcmd	外殼指令
 
 
  	-complete=function	函數名
 
 
  	-complete=help		幫助主題
 
 
  	-complete=highlight	高亮組
 
 
  	-complete=mapping	映射名
 
 
  	-complete=menu		菜單
 
 
  	-complete=option	選項
 
 
  	-complete=tag		标簽
 
 
  	-complete=tag_listfiles	标簽,但敲入 CTRL-D 時顯示檔案名
 
 
  	-complete=var		使用者變量
 
 
  	-complete=custom,{func} 使用者定制的自動補全,通過 {func} 來定義
 
 
  	-complete=customlist,{func} 使用者定制的自動補全,通過 {func} 來定義
 
 
  

 
 
  

 
 
  使用者定制的自動補全		 	*:command-completion-custom*
 
 
  					*:command-completion-customlist*
 
 
  					*E467* *E468*
 
 
  通過 "custom,{func}" 或 "customlist,{func}" 自動補全參數可以定義定制的自動補全
 
 
  方案。其中 {func} 是有如下聲明的函數:
 
 
  

 
 
  	:function {func}(ArgLead,CmdLine,CursorPos)
 
 
  

 
 
  該函數不需要使用所有的這些參數,它應該提供自動補全候選作為傳回值,
 
 
  

 
 
  對于 "custom" 參數,函數應該傳回字元串,每行一個候選,用換行符分隔。
 
 
  

 
 
  對于 "customlist" 參數,函數應該傳回 Vim 清單形式的補全候選。忽略清單裡的非字
 
 
  符串項目。
 
 
  

 
 
  該函數的參數是:
 
 
  	ArgLead		目前自動補全的前導參數
 
 
  	CmdLine		完整的指令行
 
 
  	CursorPos	裡面的光标位置 (位元組位置)
 
 
  該函數可能要根據這些來判别上下文。對 "custom" 參數,它無須用 ArgLead (裡面的隐
 
 
  式規則) 來過濾候選。在函數傳回時 Vim 将用它的正規表達式引擎來進行過濾,這種方
 
 
  式在大多數情況下效率更高。對于 "customlist" 參數,Vim 不會過濾傳回的補全候選,
 
 
  使用者提供的函數應該自己過濾候選。
 
 
  

 
 
  以下的例子為列出 Finger 指令的使用者名 >
 
 
      :com -complete=custom,ListUsers -nargs=1 Finger !finger <args>
 
 
      :fun ListUsers(A,L,P)
 
 
      :    return system("cut -d: -f1 /etc/passwd")
 
 
      :endfun
 
 
  

 
 
  下例從 'path' 選項指定的目錄補全檔案名: >
 
 
      :com -nargs=1 -bang -complete=customlist,EditFileComplete
 
 
  			\ EditFile edit<bang> <args>
 
 
      :fun EditFileComplete(A,L,P)
 
 
      :    return split(globpath(&path, a:ArgLead), "\n")
 
 
      :endfun
 
 
  <
 
 
  

 
 
  範圍處理				*E177* *E178* *:command-range*
 
 
  							*:command-count*
 
 
  預設時,使用者定義的指令不接受一個行号範圍。不過,可以使指令接受一個範圍 (-range
 
 
  屬性),或者接受一個任意的數量值,該數量可以出現在指定行号的位置 (-range=N,類
 
 
  似于 |:split| 指令的風格),也可以來自一個 "count" 參數 (-count=N,類似于
 
 
  |:Next| 指令的風格)。此時計數可以用 |<count>| 從參數裡得到。
 
 
  

 
 
  可能的屬性有:
 
 
  

 
 
  	-range	    允許使用範圍,預設為目前行
 
 
  	-range=%    允許使用範圍,預設是整個檔案 (1,$)
 
 
  	-range=N    出現在行号位置的一個數量 (預設是 N) (類似于 |:split|)
 
 
  	-count=N    出現在行号位置或者作為首個參數的一個數量 (預設是 N) (類似
 
 
  		    于 |:Next|)。
 
 
  		    指定 -count (不設預設值) 等價于 -count=0。
 
 
  

 
 
  注意 -range=N 和 -count=N 是互斥的,隻應該指定其中的一個。
 
 
  

 
 
  特殊情況				*:command-bang* *:command-bar*
 
 
  					*:command-register* *:command-buffer*
 
 
  有如下特殊情況:
 
 
  

 
 
  	-bang	    這些指令可以使用一個 ! 修飾符 (和 :q 或 :w 類似)
 
 
  	-bar	    這些指令可以跟随一個 "|" 和其它指令。那麼指令參數中就
 
 
  		    不允許有 "|" 。用一個 " 可以開始一個注釋。
 
 
  	-register   給這些指令的第一個參數可以是一個可選的寄存器名
 
 
  		    (和 :del,:put,:yank 類似)。
 
 
  	-buffer	    這些指令僅在目前緩沖區裡有效。
 
 
  

 
 
  -count 和 -register 屬性的情況,如果提供了可選的參數,它會被從參數清單中删除,
 
 
  并且和替換文本分别處理。
 
 
  

 
 
  替換文本
 
 
  

 
 
  使用者自定義指令的替換文本掃描使用 <...> 記法的特殊轉義序列。指令行輸入的值中,
 
 
  轉義序列被替換,其它文本不變。最終字元串被作為 Ex 指令來執行。要避免替換,使用
 
 
  <lt> 代替初始的 <。這樣,要按本義包含 "<bang>",請使用 "<lt>bang>"。
 
 
  

 
 
  有效的轉義序列有
 
 
  

 
 
  						*<line1>*
 
 
  	<line1>	指令處理範圍的開始行。
 
 
  						*<line2>*
 
 
  	<line2>	指令處理範圍的末尾行。
 
 
  						*<count>*
 
 
  	<count>	提供的數量 (在 '-range' 和 '-count' 屬性中描述)。
 
 
  						*<bang>*
 
 
  	<bang>	(參考 '-bang' 屬性) 如果指令執行時帶了 ! 修飾符,擴充為 !,否
 
 
  		則什麼也不擴充。
 
 
  						*<reg>* *<register>*
 
 
  	<reg>	(參考 '-register' 屬性) 如果指令行上指定,可選的寄存器名。否則
 
 
  		什麼也不擴充。<register> 是它的一個同義詞。
 
 
  						*<args>*
 
 
  	<args>	指令的參數,和實際提供的完全相同 (但正如上面提到過的,數量或寄
 
 
  		存器會消耗若幹參數,它們不再是 <args> 的一部分)。
 
 
  	<lt>	一個單獨的 '<' (小于号) 字元。擴充轉義序列時,如果需要以上轉義
 
 
  		序列按字面意義出現的版本時有用。- 例如,要獲得 <bang>,使用
 
 
  		<lt>bang>。
 
 
  

 
 
  							*<q-args>*
 
 
  如果一個轉義序列的最前兩個字元是 "q-" (例如,<q-args>) 那麼該值用引号括起,使
 
 
  之在表達式裡使用時成為合法的值。這種方式把參數當做單個值。如果沒有參數,
 
 
  <q-args> 是空字元串。
 
 
  							*<f-args>*
 
 
  要允許指令把參數傳送給使用者定義的函數,有一種特殊的形式 <f-args> ("function
 
 
  args",函數參數)。它在空格和制表處分割指令行參數,每個參數分别用引号括起,然後
 
 
  把 <f-args> 序列替換為括起參數用逗号分隔的清單。參考下面的 Mycmd 示例。沒有參
 
 
  數時,<f-args> 被删除。
 
 
     要在 <f-args> 的參數中嵌入空白字元,在前面加上反斜杠。<f-args> 把每對反斜杠
 
 
  (\\) 用單個反斜杠替代。反斜杠後如跟非空白或反斜杠字元,保持不變。總覽如下:
 
 
  

 
 
  	指令		   <f-args> ~
 
 
  	XX ab		   'ab'
 
 
  	XX a\b		   'a\b'
 
 
  	XX a\ b		   'a b'
 
 
  	XX a\  b	   'a ', 'b'
 
 
  	XX a\\b		   'a\b'
 
 
  	XX a\\ b	   'a\', 'b'
 
 
  	XX a\\\b	   'a\\b'
 
 
  	XX a\\\ b	   'a\ b'
 
 
  	XX a\\\\b	   'a\\b'
 
 
  	XX a\\\\ b	   'a\\', 'b'
 
 
  

 
 
  示例 >
 
 
  

 
 
     " 删除從這裡到末尾的所有東西
 
 
     :com Ddel +,$d
 
 
  

 
 
     " 把目前緩沖區改名
 
 
     :com -nargs=1 -bang -complete=file Ren f <args>|w<bang>
 
 
  

 
 
     " 用一個檔案的内容來替換某個範圍内的内容
 
 
     " (請用一行輸入本指令)
 
 
     :com -range -nargs=1 -complete=file
 
 
  	 Replace <line1>-pu_|<line1>,<line2>d|r <args>|<line1>d
 
 
  

 
 
     " 計算範圍内的行數
 
 
     :com! -range -nargs=0 Lines  echo <line2> - <line1> + 1 "lines"
 
 
  

 
 
     " 調用一個使用者函數 (<f-args> 的示例)
 
 
     :com -nargs=* Mycmd call Myfunc(<f-args>)
 
 
  

 
 
  當執行: >
 
 
  	:Mycmd arg1 arg2
 
 
  時,它将調用: >
 
 
  	:call Myfunc("arg1","arg2")
 
 
  

 
 
     :" 一個更實用的例子
 
 
     :function Allargs(command)
 
 
     :	let i = 0
 
 
     :	while i < argc()
 
 
     :	   if filereadable(argv(i))
 
 
     :	    execute "e " . argv(i)
 
 
     :	     execute a:command
 
 
     :      endif
 
 
     :      let i = i + 1
 
 
     :   endwhile
 
 
     :endfunction
 
 
     :command -nargs=+ -complete=command Allargs call Allargs(<q-args>)
 
 
  

 
 
  指令 Allargs 接受任意 Vim 指令作為參數并在參數清單裡的所有檔案上執行。使用示例
 
 
  (注意使用 "e" 标志位來忽略錯誤,以及用 "update" 指令來重新整理修改過的緩沖區):
 
 
  	:Allargs %s/foo/bar/ge|update
 
 
  它将調用: >
 
 
  	:call Allargs("%s/foo/bar/ge|update")
 
 
  <
 
 
  在腳本裡定義使用者指令時,它可以調用局部于腳本中的函數和使用局部于腳本的映射。用
 
 
  戶調用使用者指令時,該指令将運作在定義它的腳本的上下文裡,如果一個指令中使用了
 
 
  |<SID>|,這一點很重要。
 
 
  

 
 
   vim:tw=78:ts=8:ft=help:norl:
 
 
  

 
 
  轉載位址:https://github.com/chagel/vimrc/blob/master/doc/map.cnx