This page was created by www.chinacode.com.
Address: http://man.chinacode.com/VIM/map.html
Title: VIM: map  •  Size: 98840  •  Last Modified: Thu, 20 Sep 2007 19:59:16 GMT

MAP

*map.txt*       For Vim version 7.1.  æœ€åŽæ›´æ–°: 2007å¹´5月


                  VIM å‚考手册    作者: Bram Moolenaar
                                  译者:  con<con@netease.com>
                                  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}">{lhs}* {rhs} è¡¨ç¤ºå³æ‰‹è¾¹ *{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* æœ‰äº”ç§æ˜ å°„存在 - 用于普通模å¼: 输入命令时。 - 用于å¯è§†æ¨¡å¼: å¯è§†åŒºåŸŸé«˜äº®å¹¶è¾“入命令时。 - 用于æ“作符等待模å¼: æ“作符等待中 ("d","y","c" 等等之åŽ)。 例如: ":omap { w" 会使 "y{" ç­‰åŒäºŽ "yw","d{" 也等åŒäºŽ "dw"。 - 用于æ’入模å¼: ä¹Ÿç”¨äºŽæ›¿æ¢æ¨¡å¼ã€‚ - 用于命令行模å¼: 输入 ":" 或 "/" 命令时。 特殊情况:当在普通模å¼é‡Œä¸ºä¸€ä¸ªå‘½ä»¤è¾“入一个计数时,对 0 的映射会被ç¦ç”¨ã€‚这样在 输入一个带有 0 的计数时ä¸ä¼šå—到对 0 键映射的干扰。 *map-overview* *map-modes* 关于æ¯ä¸ªæ˜ å°„命令对应的工作模å¼çš„æ¦‚况: *mapmode-nvo* *mapmode-n* *mapmode-v* *mapmode-o* 命令: 模å¼: 普通 å¯è§†+选择 æ“作符等待 :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" 命令æ¥å¯¹æ¯ä¸ªä¸åŒçš„æ¨¡å¼åˆ†åˆ«å®šä¹‰æ˜  射。 è¦ä¸ºæ™®é€šå’Œå¯è§†æ¨¡å¼ä½†ä¸åŒ…括æ“作符等待模å¼è¾“入一个映射,首先在所有的三个模å¼ä¸­å®š 义该映射,然åŽåœ¨æ“作符等待模å¼ä¸­å–消该映射: :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 è§£ç ä¸­è¾“å…¥ á (0xea <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* å’Œ <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' 选项,然åŽè°ƒç”¨ |g@| æ“作符。这样用户输入 {motion} 命令åŽï¼Œä¼šè°ƒ 用指定的函数。 *g@* *E774* *E775* g@{motion} 调用 'operatorfunc' 选项设置的函数。 '[ ä½ç½®æ ‡è®°å®šä½åœ¨ {motino} 跨越的文本的开始处,而 '] ä½ç½®æ ‡è®°åœ¨æ­¤æ–‡æœ¬çš„结æŸå¤„。 å‡½æ•°è°ƒç”¨æ—¶ï¼Œå¸¦ä¸€ä¸ªå­—ç¬¦ä¸²å‚æ•°: 傿•° 如果 "line" {motion} 本是 |linewise| "char" {motion} 本是 |characterwise| "block" {motion} 本是 |blockwise-visual|| ä¸è¿‡ï¼Œ"block" 很少出现,因为它åªèƒ½æ¥è‡ªå¯è§†æ¨¡å¼ï¼Œé‚£é‡Œ "g@" 䏿˜¯å¾ˆæœ‰ç”¨ã€‚ {仅当编译时加入 +eval ç‰¹æ€§æ‰æœ‰æ•ˆ} 这里是一例,<F4> æ¥è®¡ç®—空格数目: nmap <silent> <F4> :set opfunc=CountSpaces<CR>g@ 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:

Generated by vim2html on Thu Sep 20 19:25:31 UTC 2007