學習 vi 編輯器/Vim/程式設計師需要知道的實用技巧
|
學習 vi 編輯器: 熟悉 — 基本任務 — 簡化工作 — 高階任務 — 細節 — Vi 克隆 (Vim – 基本導航 – 模式 – 技巧和竅門 – 程式設計師需要知道的實用技巧 – 增強 Vim – Vim 在 Windows 上 – VimL 指令碼語言, Vile, BB vi) — vi 參考 |
程式設計師應該瞭解一些關於 vim 的知識,這些知識會讓他們的體驗更加輕鬆。程式設計師可以透過使用有效的編輯器節省數小時甚至數週的人工時間。以下是一些 vim 提供的技巧和工具。隨著你節省的時間,你可以加快工作速度,騰出時間快速進行 Quake 死亡競賽,或者最終提高你的工作效率,從而幫助你獲得更高的工資增長。
有時你輸入的單詞非常長。你不必把它們全部輸入出來。如果它們在你的字典或當前檔案中,你可以使用 <Ctrl-P> 和 <Ctrl-N> 節省大量時間。讓我們仔細看看它是如何工作的
- 單詞/變數/函式名補全
通常,當前檔案或同一 vim 例項中你正在編輯的其他任何檔案(緩衝區)中的任何單詞都將匹配補全。這意味著,一旦你輸入一次,下次你就可以輸入前幾個字母,然後按 Ctrl-N(如果你需要迴圈瀏覽多個選項,可以按多次),直到找到你想要的單詞。
從技術上講,情況並非如此。你可以在 complete 函式中告訴 vim 在哪裡查詢單詞。在 Vim 7 中,complete 函式通常會設定為找出你正在輸入的內容的大量資訊——從函式庫中獲取資訊(截至本書的上次更新,作者知道 C 和 C++ 預設情況下受支援)。從 Vim 7 開始,關鍵字補全還會顯示一個彈出選單。
你也可以為自己定義一個字典來進行補全。有關更多詳細資訊,你可能需要參考 vim 幫助系統“:help complete”、“:help complete-functions”等等。
示例 1
例如,你可能會編輯一個 C 程式檔案“blah.c”。你想要一個以“str”開頭的函式,但你不記得它是什麼。你首先輸入“str”。它仍然是普通文字,直到你按下 <Ctrl-P> 或 <Ctrl-N>。在 vim 7 中,你會看到一個選單出現,如下所示
你可以使用 <Ctrl-N> 和 <Ctrl-P> 迴圈瀏覽顯示的條目。在 Vim 7 及更高版本中,你實際上可以使用箭頭鍵迴圈瀏覽選單中的條目。螢幕上一次可能顯示的條目太多(你會注意到右側的黑色方框代表灰色條上的滾動位置——在本例中,並非所有選項都顯示在螢幕上)。將顯示提取選項的檔案,以幫助你決定是否是你想要的。
(你還會在本例中注意到,來自作者最近編輯的檔案的單詞也顯示出來了,例如來自“cgi-bin/ftplist.pl”的“strict”——我們當然不希望這樣。)
示例 2
現在,假設你需要正弦函式,但你知道它的名字很奇怪。你輸入 sin 並按下 <Ctrl-P>,但它沒有顯示出來
你沒有失敗,只是還沒有包含數學庫。你只需要新增一行
#include <math.h>
然後重試。這次你會看到你想要的函式名(因為它的名字很奇怪,所以不太容易記住)
- 行補全
如果你需要,你可以補全整行,雖然這種情況不太可能發生。 <Ctrl-X>,<Ctrl-L> 會將匹配的行(空格很重要!)載入到選單中,然後你就可以使用箭頭或 <Ctrl-P> 和 <Ctrl-N>(用於 Previous 和 Next)向前或向後移動。
Vim 可以找出如何縮排大多數常見的檔案型別。
對於大多數流行的程式語言,vim 可以透過檔名副檔名檢測檔案型別,並據此決定如何縮排你的檔案。如果你沒有看到它自動為你建立正確的縮排,請嘗試
:filetype indent plugin on
在 GUI 版本中,你可能可以在為該檔案開啟語法高亮的同時開啟它。選擇語法 -> 為此檔案開啟/關閉,或語法 -> 在選單中顯示檔案型別,然後返回語法選單並從列表中選擇適當的檔案型別。
你可能希望將上面提到的“:filetype …”行放在你的 vimrc 檔案(前面已經討論過)中,然後再次開啟你的程式檔案,雖然這實際上應該沒有必要。
如果你仍然遇到問題,你可能需要檢查你的 runtimepath 變數是否設定正確(:help runtimepath)。也有可能(雖然不太可能)你的程式語言很罕見,以至於還沒有人為此編寫縮排外掛。vim 的官方網站 vim.org 可能有一個滿足你需求的縮排外掛檔案,即使它沒有包含在你預設的 vim 安裝中。
當你貼上了一些文字,並且縮排不正確時(你的縮排外掛必須載入),你可以使用 = 命令。最簡單的方法可能是輸入“10=”重新縮排接下來的十行,或者使用可視模式並按下 <=>。
如果你願意,可以使用“>>”縮排行,使用“<<”取消縮排行。
如果你處於插入模式,請使用 <Ctrl-D> 和 <Ctrl-T> 更改行的縮排(<Ctrl-D> 將縮排減少一級,Ctrl-T 將縮排增加一級)。
如果你無法使特定於檔案型別的縮排正常工作,你可能嘗試設定以下一個或多個選項:smartindent、autoindent、cindent 和 copyindent。這些選項可能無法完全正常工作,因此 <Ctrl-D> 和 <Ctrl-T> 會更加重要。要開啟 autoindent,請鍵入 :set autoindent。要關閉 autoindent,請鍵入 :set noautoindent
如果你對 vim 感到滿意,你可能會將你的按鍵記錄到一個不可見的暫存器,並在以後重複它們。編寫 vim 指令碼,甚至使用另一個程式(例如 perl 指令碼)過濾你的檔案可能更容易,以執行更復雜的動作。
也就是說,有時記錄命令並重復使用它,甚至在任何匹配的行上執行它確實更容易。對於更高階的執行模式(例如,在整個檔案中執行一個命令),請參見下文。你也可以考慮建立對映(在下面討論)或執行 :global 命令(也在下面討論)。
假設我想在幾行末尾加上一個分號,而我忘記了
cout << "Hello world\n" i = j + k cout << "i is " << i << endl
在第一行,我輸入A;,然後按ESC鍵。我移動到下一行並按下.(句號告訴vim重複最後一個命令——不用擔心,它不會重複移動命令)。
Vim 擁有強大的命令重複功能,可以透過宏來實現。使用者可以將一系列命令錄製到暫存器中,然後將該暫存器執行為宏。宏可以錄製到 26 個暫存器中的任何一個(a 到 z)。
要開始錄製宏,請按q,然後按一個暫存器名稱(任何字母a到z——暫存器只由一個字母定義,所以只能使用一個字元作為儲存緩衝區)。在執行一系列命令後,按q再次結束錄製命令宏。例如,要開始錄製到暫存器 z,請按qz,然後再次按q結束錄製。
要從暫存器執行宏,請使用@x,其中x是包含所需宏錄製的暫存器。暫存器q是宏錄製的預設暫存器,因此,如果您已錄製到暫存器q,則只需鍵入@@即可執行宏。
(注意:請記住,指令碼或對映有時可能會使用任意暫存器——因此,如果您遇到衝突,尤其是在第三方指令碼或對映中,您應該考慮錄製到其他暫存器。您可以使用:registers命令檢視暫存器的內容。)
作為一個簡單的例子,假設您在緩衝區中有以下幾行,並且您希望每行重複該行的最後一個單詞。最初,緩衝區看起來像這樣
The quick brown fox jumps over the lazy dog The sly gray fox circles around the unsuspecting rabbit The slow gray fox crawls under the rotting fence
您希望緩衝區看起來像這樣:(其中新增內容以粗體突出顯示)
The quick brown fox jumps over the lazy dog dog The sly gray fox circles around the unsuspecting rabbit rabbit The slow gray fox crawls under the rotting fence fence
要做到這一點,請使用qq開始錄製到預設暫存器中,然後使用A追加該行,鍵入空格,然後按Ctrl-P,最後按ESC鍵。要結束錄製,請再次按q。現在,宏已錄製到暫存器q中。要重複該命令,請向下移動一行,並透過鍵入@@或@q重複該命令。您可以使用@@執行此宏,因為 q 是宏的預設暫存器。
在另一個例子中,假設您在暫存器中擁有以下幾行
The quick brown fox jumps over the lazy dog dog The sly gray fox circles around the unsuspecting rabbit rabbit The slow gray fox crawls under the rotting fence fence
您希望在動物名稱(fox、dog 和 rabbit)周圍新增 HTML 標籤,使它們變為粗體(例如,fox 需要變為<b>fox </b>)。假設您希望使用暫存器a來存放宏。
要開始,請將游標移動到第一個動物名稱——fox 上。將游標放在單詞的某個位置,例如 fox 中的 'o' 上。透過鍵入qa開始錄製。接下來,使用"bdaw將單詞刪除到暫存器b中(有關此命令的解釋,請參見:help aw和:help d以及:help ")。接下來,透過鍵入i進入插入模式,然後鍵入<b>,然後按Ctrl-O,然後按"bP(有關此命令的解釋,請參見:help i_CTRL-o)。接下來,鍵入</b>,然後按 ESC。最後,透過鍵入q停止錄製。要重複該命令,請將游標移到您希望用 HTML 標籤包圍的下一個單詞上,然後透過鍵入@a執行宏。您可以透過檢查暫存器來檢視宏的結構。為此,您可以執行命令:registers a。在這種情況下,vim 將顯示以下輸出
--- Registers --- "a "bdawi<b>^O"bP</b>^[
請注意,錄製會記住您的所有移動命令,因此您需要在開始錄製之前將游標放在正確的位置。
假設您在宏中犯了一個小錯誤,但宏相當複雜,您不想再次重複所有這些命令。我們希望修改暫存器的內容。為此,我們使用在轉義模式下鍵入"x會使用暫存器x的內容進行下一次刪除、貼上或放置的功能。
假設我們使用暫存器a,
- 建立一個新行(此行將最終被刪除),並在轉義模式下使用
"ap將暫存器的內容放在該行上。此命令將(注意命令中的 p)將暫存器 a(透過 "a)的內容貼上到該行中。 - 根據需要進行修改,然後
- 將修改後的行放回暫存器a中,方法是移動到該行的開頭(使用
|),並在轉義模式下鍵入"ad$。(不要使用"aD,因為 D 也會捕獲緩衝區中的換行符。) - 測試宏以確保它正常工作,然後根據需要使用它。
要執行儲存在暫存器q中的宏一次,您可以按@q。但是,您通常不會編寫只執行一次的宏,而 Vim 的強大功能就在這裡發揮作用。
要將命令應用於第 23 行到第 42 行,請使用:23,42norm! @q,要將命令應用於文件中的所有行,可以使用:%norm! @q。
同樣的方法也適用於您可以使用點訪問的單個命令。如果您在文件中的一些行上忘記了分號,您只需執行A;,然後按ESC鍵。然後,命令:23,42norm! .會將相同的操作應用於第 23 行到第 42 行,並在每行的末尾插入分號。
對映新命令的優勢之一是,您可以將對映放入您的 vimrc 檔案中以供以後使用。我有以下對映
map <C-k> :!%:p<C-m>
這樣做就是將normal命令 Ctrl-K 對映為運行當前檔案作為指令碼。您也可以使用此對映執行上面的第二個“錄製命令”練習(將單詞放在粗體標籤中)
map <C-x>b "bdawi<b><C-o>"bp</b><ESC>
請注意,在這種情況下,我可以使用"<b>",因為它不匹配任何特殊字元名稱。但是,如果我需要避免衝突(如果我想對映"<ESC>"的插入),我會對小於號和大於號使用<lt>和<gt>。(請參見 ":help key-codes")
如果您希望為插入模式對映命令,請使用 imap 而不是 map。
如果您希望阻止對映定義中的任何命令在其他對映中被解釋,請使用 noremap(或在插入模式下使用 inoremap inoremap 代表insert mode no re-map)
|
學習 vi 編輯器: 熟悉 — 基本任務 — 簡化工作 — 高階任務 — 細節 — Vi 克隆 (Vim – 基本導航 – 模式 – 技巧和竅門 – 程式設計師需要知道的實用技巧 – 增強 Vim – Vim 在 Windows 上 – VimL 指令碼語言, Vile, BB vi) — vi 參考 |


