天天看點

【轉】高效使用vim

出處:http://www.cnblogs.com/hyddd/archive/2010/04/08/1706863.html

英文出處:jmcpherson.org/editing.html

翻譯引用: tingsaode.spaces.live.com/blog/cns!FE95D0EE01558610!780.entry

原文位址: http://hi.baidu.com/gone1210/blog/item/41c0e60b000230c33ac76328.html

之于我, vi即禅.

用vi如修禅,

vi指令如禅之心印.

用者不可窺其堂奧,

門外漢視其晦澀如天書.

常用之, 實可知其道.

高效移動

珍愛生命, 遠離插入模式

      一般情況下, 你應該盡量少把時間花在插入模式, 因為在這種模式下vi和其它sb編輯器差別不大. 這也是大部分vim新手把大部分時間花在插入模式的原因 -- 插入模式很易用. 但是vim真正的優勢在指令模式. 你會發現越了解vim, 你花在插入模式的時間越少.

使用h,j,k, l

      高效率用vim編輯的第一步是絕了你用方向鍵(上下左右)的念頭. vim設計出"模式"操作方式的一大優勢就是可以讓你不需要老是把手從方向鍵和字母鍵之間移來移去. 當你在指令模式下, 用字母h, j, k, l對應方向左, 下, 上, 右. 這個需要練習一下才能習慣, 但是你會發現一旦你習慣了它們, 比用方向鍵快多了. (譯注: 這幾個移動鍵一定要動手試, 然後反複用, 靠記憶忒艱難了)

     在你編輯電子郵件或其他段落式文本的時候, 你可能注意到移動方向跳的行數比你料想的多. 這是因為你的段落對vim來說在很長的同一個行裡. 用h, j, k, l移動前輸入g可以讓移動相對于螢幕看上去的行數而不是vim内部的行數.

用motion在目前行移動 

(譯注: 沒想到特别合适的詞翻譯motion, 可以了解為"進階移動", 另請注意, motion僅在目前行移動)

    大部分編輯器隻有簡單的光标移動功能(上下左右, 行首行尾等等). vim有非常進階的光标移動指令, 這些指令叫做Motion. 當用motion把光标從文本中的一個點移動到另一個點的時候, 兩點間的文本(包括兩個點本身)被motion"掠過". (這個概念在接下來的教程中非常重要.) (譯注: 舉例說明一下"掠過"概念, 比如你有一行文本, 内容是abcdefg, 目前光标在c上, 如果你用motion $, 光标移動到了g上, 那麼從c到g這段文本就被motion $"掠過"了).

以下是一些有用的motion:

fx 在目前行向前移動光标到下一個字元x (很明顯, x可以是任意你想要移動到的字元). 這是一個超級有用的指令. 你可以輸入;來重複前一個f指令.
tx 和上面的指令基本相同, 除了移動光标到字元x之前而不是x字元本身. (這個真的很有用)
Fx 在目前行向後移動光标到上一個字元x.
w 将光标向前移動一個詞.
b 将光标向後移動一個詞.
将光标移動到目前行首.
^ 将光标移動到目前行的第一個字元. (譯注: 第一個字元可能不是行首, 比如行首有space, tab等不可見符号, 0會把光标停在這些符号之前, 而^會把光jk标停在這些符号之後的第一個可見字元.)
$ 将光标移動到目前行尾.
) 将光标移動到下一個句子. (寫電子郵件或者文本文檔的時候很有用.)
( 将光标移動到上一個句子.

在檔案中高效移動

      vim有很多指令可以讓你在檔案中任意移動光标 -- 很少需要手工一頁一頁滾動. 以下按鍵技術上說不算motion, 因為它們是在檔案中移動, 而不是在某一特定的行.

<C-F> 将光标向前(下)移動一頁(螢幕).
<C-B> 将光标向後(上)移動一頁.
G 移動到檔案尾
numG 将光标移動到某一行. (例如, 10G是把光标移動到第10行.)
gg 将光标移動到檔案開頭
H 将光标移動到目前頁的第一行.
M 将光标移動到目前頁的中間一行.
L 将光标移動到目前頁的最後一行. (譯注: 有了HML3個指令, 可以把滑鼠撇了, 爽)
* 讀取光标下的字串, 然後移動到目前檔案中下一次出現該字串的位置. (比如說如果你的光标所在的位置的字串為"bob,", 按了*之後, 光标将移動檔案中下一個"bob"出現的位置.)
# 和*指令基本相同, 除了它移動到上一次出現字串的位置.
/text    從目前光标位置開始, 查找下一個含有text的字串并且移動到那裡. 需要按回車(Enter)鍵來執行查找. 如果要重複執行查找, 輸入n(n代表next occurance). (譯注: text指你想搜尋的字串, 比如你要在檔案查找字串"abc", 就輸入/abc然後回車)
?text    和/text相似, 差別是?text進行反向查找(查找上一個字串).
ma 給目前光标所在位置設定一個名字為a的書簽. 書簽的名字可以是任何小寫字母. 你看不到書簽, 但它确實在.
`a 移動光标到書簽a. 注意`不是單引号, 大部分鍵盤上它在數字1的左面. (譯注: 本人使用的vim 7.1 windows版本用單引号也能完成同樣功能)
`. 移動到你之前編輯過的行. 這個又是"真有用". 如果你需要在檔案中"滾來滾去"檢視一些東西, 你可以用這個指令回到你之前編輯的行盡管你沒把它設成書簽.

高效輸入

使用關鍵字自動完成(補全)

     vim 有個非常好的關鍵字自動完成系統. 就是說你可以隻輸入很長的詞的一部分, 按一個鍵, vim幫你把這個詞自動補全. 比如說在你的代碼中有一個變量叫iAmALongAndAwkwardVarName, 你可能不願意每次用這個變量都把整個詞打一遍, 這時候就可以用自動完成功能.

       要使用關鍵字自動完成, 隻要輸入一個字串的前幾個字母 (比如 iAmAL) 然後按 <C-N> (按住Ctrl然後按N>)或者<C-P>. 如果vim沒有選擇你需要的字串, 繼續按<C-N>或<C-P> -- vim會周遊所有和你輸入的前幾個字母比對的字串.

用點腦子開始插入模式

     大部分新使用者輸入i來進入插入模式. 這種方法有時候相當低效, vi有一堆可以高效進入插入模式的指令. 這裡是最常用的一些:

i 在目前字元的左側開始插入.
I 在目前行行首開始插入.
a 在目前字元的右側開始插入.
A 在目前行行尾開始插入.
o 在目前行的下一行開始新的一行并在那插入. (譯注, 寫code用這個很爽)
O 在目前行的上一行開始新的一行并在那插入.
c{motion} 删除(change)motion"掠過"的文本然後插入新文本代替它. 比如說, c$會删除目前光标位置到目前行尾的文本并開始插入模式. ct!會删除目前光标位置到下一個!出現位置(不包括!本身)之間的文本并進入插入模式. 删除的文本會被複制到剪切闆可以被粘貼使用. (譯注: 可以到前面複習一下"掠過"的概念, 參考例子. 輸入c{motion}指令的時候, 不需要輸入花括号)
d{motion}  删除motion"掠過"的文本 -- 和c{motion}相似, 但是不進入插入模式.

高效移動成塊的的文本

用可視化選擇, 用合适的選中模式

      和最早的vi不同, vim可以讓你把文本置為高亮然後對高亮的文本操作. 以下是主要的3個可視化選中模式 (即文本高亮模式).

v 字元選中模式. 大部分人習慣用這個, 是以玩其他模式之前先把這個練熟.
V 行選中模式. 選中整行. 當你需要複制或移動幾行的時候, 這個比字元選中模式要好.
<C-V> 塊選中模式. 超級nb而且很少有其他的編輯器支援(譯注: 還是有一些支援的, 比如ultraedit, 但是得付錢...). 你可以在任何文本中選擇一個矩形塊來操作. (譯注: 在windows版本的vim中<C-V>預設被映射為粘貼, 可以通過更改鍵盤映射或者使用<C-Q>來進行塊操作)

     所有常用的光标移動鍵都可以在可視模式使用, 比如vwww會進入字元選中模式并且選中光标之後的3個詞. Vjj将會進入行選中模式并且選中目前行及之後的兩行.

在可視化選中模式下進行剪切和複制

     一旦你有了高亮選擇, 你可能想要幹點啥. 以下是對選中的高亮文本最有用的指令:

d 剪切(删除)高亮選中的文本到剪切闆. (譯注: 據本人所知, vim所有的删除其實都是剪切)
y 複制 (或者說"拽"(yank), vim用"拽"來表示複制...)高亮選中的文本到剪切闆.
c 剪切高亮選中的文本到剪切闆. 和d很相似, 隻是c會進入插入模式.

在非可視化選擇模式進行剪切和複制

   如果你确知你想要複制或者剪切什麼, 你可以不進入可視化選擇模式就完成這些操作. 這樣速度更快.

d{motion} 把由motion"掠過"的文本剪切到剪切闆. 比如dw把目前光标開始的一個詞剪切到剪切闆, 而dfS把從目前行從光标是到下一個S之間的文本剪切到剪切闆.
y{motion}  把motion"掠過"的文本複制到剪切闆.
c{motion}  把motion"掠過"的文本剪切到剪切闆并且進入插入模式.
dd  剪切目前行到剪切闆.
yy 複制目前行到剪切闆.
cc 剪切目前行到剪切闆并且進入插入模式.
D 剪切光标目前位置到行尾的文本到剪切闆.
Y 複制整行到剪切闆, 和yy相似. (yes, 這個指令和指令D的操作方式沒保持一緻, 你可以用y$完成類似D的操作)
C 剪切光标目前位置到行尾的文本到剪切闆并進入插入模式.
x 剪切目前字元. (類似于指令模式的倒退(backspace)鍵)
s 剪切目前字元并進入插入模式.

粘貼

  粘貼很簡單. 把光标移動到你想要粘貼的位置輸入p. (譯注: 粘貼操作需要在指令模式下, 另外P(大寫)指令把剪切闆的内容粘貼到光标目前位置之前, 對用慣其它編輯器的人來說, P指令可能更符合習慣)

使用多個剪切闆

       大部分編輯器隻有一個剪切闆. (譯注: 貌似不算太'大部分') vim有多個. 在vim裡剪切闆叫做寄存器(regiseter). 你可以輸入:reg列出所有目前定義過的寄存器和它們的内容. 大多數情況下你會使用以小寫字母命名寄存器, 其他的有各自不同的vim内部用途, 偶爾可能會有用.

      要使用指定的某個寄存器來完成複制和粘貼, 很簡單, 在複制粘貼操作之前輸入"a, a表示你希望用的寄存器.

      舉個例子, 複制目前行到寄存器k, 輸入"kyy. (也可以用V"ky. 想想為啥這個也成). 那一行就會被存放在寄存器k裡, 直到有其他的東西被複制到到寄存器k覆寫它. 複制之後可以用"kp來把寄存器k裡存放的内容粘貼到到文本中.

不幹機械勞動

給你驚喜的.指令

      在vi中, 輸入.(英文的句号)可以重複上一個你執行過的指令. 比如你上一個指令是dw, 當你輸入.指令, vi會删除下一個詞.

使用計數器執行重複操作

      計數器是vim最nb的提速功能. 任何指令之前都可以加一個數. 這個數告訴vim你想把指令執行多少次. 例如:

3j會把光标向下移動3行.

10dd會删除10行文本.

y3"在目前行, 把光标目前位置到第三個雙引号之間的文本複制到剪切闆. 這種計數器用法可以大大擴充motion的操作範圍. (譯注: 本人認為y3"不能完成這樣的功能, 對應的指令應該是y3f", 可能原作者漏寫了f指令, 有空的時候問問原作者)

錄制宏

      你可能偶然會發現你對一個文檔中的某塊文本反反複複的進行相同的操作. vim可以錄制一個特定的宏來完成這些操作.

qregister  開始錄制一個宏并儲存在某個有名字的寄存器. 比如qa開始錄制一個宏并把這個宏存放在寄存器a中.
q 結束錄制
@register 回放存放在某個寄存器的宏. 比如@a播放寄存器a中的宏.

      請注意宏隻是記錄你的按鍵并且回放; 不是神奇的魔法. 因為在vim中可以用多個指令執行某個任務, 錄制宏幾乎成了一種藝術形式, 你必須非常小心的選擇要用的指令才能用宏達到你想要的效果.

用vim寫程式代碼

    vim是優秀的源代碼編輯器, 有很多的功能是專門為寫程式設計的. 這裡是一些常用的:

]p 和p相似, 但是它可以自動調整粘貼的代碼和已有的代碼縮進. 試試吧.
% 把光标放在某個花括号{}, 中括号[]或者圓括号()上, 按%會把光标移動到與之對應的花括号, 中括号或者圓括号上. 對于修正多層嵌套邏輯代碼塊的括号解析問題來說, 這個功能堪稱救人于水火之中.
>> 縮進高亮選中的代碼. (對高亮選中請檢視前面章節, 如果沒有文本被高亮選中, 則将目前行縮進)
<< 和>>類似, 但是反方向(譯注: 縮進是向右移動行, 反方向既向左移動).
gd 把光标移動到目前光标所在位置的函數或者變量的定義(definition)(或聲明(declaration)).
K 打開目前光标所在詞對應的手冊頁(man page). (比如你的光标目前在sleep這個詞上, vim會顯示sleep的手冊頁) (譯注: 這個功能貌似隻對vim的原生OS--unix上有用)

(譯注: 結合ctags, cscope之類的輔助工具, vim可以提供更強大的程式代碼編寫功能)