2009-07-26

VIM: 七個有效率的文本編輯習慣

今天在使用 Vi 的時候,不小心把檔案給加密了,在網路上找看有沒有解碼的方法的時候,剛好在某個人的文章中看到推薦去看一下 VIM七個有效率的文本編輯習慣,其文件在 vim6.x 說明檔的附錄2中,在 sourceforge 中有一個 vimcdoc 的專案中,有簡體中的 pdf 檔,為了方便閱讀,我就順手將內容轉成了繁體中文的格式。


下述內容來自wimcdoc vim6.x 附錄2。


七個有效的文本編輯習慣
作者Bram Moolenaar
Bram@Moolenaar.net
slimzhao@hotmail.com 翻譯整理
reic.wang@gmail.com 進行繁簡轉換(感謝 同文堂 專案)
如果你要花大量的時間鍵入文本, 寫程序或編寫HTML腳本, 你可以通過有效地使用一個好的編輯器來替你節省時間。本文將引導你如果快速地完成你的編輯工作, 並且減少你的錯誤。

本文將以開放源碼軟件Vim(Vi IMproved)為例向你展示如何進行有效的編輯, 但這裡提到的原則對其它的編輯器也是一樣, 選擇合適的編輯器是進行高效的編輯的第一步, 關於哪個編輯器最好的爭論已經數不勝數,本文不打算對此再說些什麼。如果你還不知道用什麼編輯器或者覺得你現在使用的編輯差強人意, 試一下Vim, 保你滿意。

第一部分: 編輯一個文件
1. 快速移動
文本編輯的多數時間都花費在瀏覽, 檢查錯誤或者找出你要進行編輯工作的正確位置, 輸入新的內容或改變已有的內容倒在其次。在文本中隨意漫遊是非常常見的操作。所以高效編輯的第一要義是學習如何能夠在文本中快速移動, 準確定位。

通常情況下, 你知道要查找的內容, 或者查看所有的文本行只是為了找出某個單詞或者短語。你可以使用查找命令"/pattern"查找文本, 但有幾點要注意的:

如果你已經找到了一個單詞並且想找出這個單詞還在其它哪些地方出現, 可以使用"*"命令, 它查找下一個匹配的目標。如果你設置了`incsearch'選項, Vim將會以反白顯示出第一個被找出的匹配。這能在你還在/命令下敲入關鍵字時就快速地顯示出來(類似於emacs的遞增查找功能) 如果你設置了`hlsearch'選項, Vim將會高亮顯示所有查找到的匹配, 這種策略可以讓你對要查找的內容有一個概括的瞭解, 如果你在程序代碼中使用這一功能, 它能顯示出所有引用某個變量的地方。你不需要移動光標就可以看到所有符合條件的匹配(同一屏幕上可以看到不至一個地方被匹配)。

在一些結構規範的文本中還有其它一些更方便的小技巧進行快速移動, Vim內嵌了方便C程序(以及與C語言很相像的C++和Java)的命令: 使用"%"命令可以從一個打開的括號跳轉到與它成對匹配的另一個括號處,還可以從一個預處理指令"#if"跳轉到與之匹對的"#endif"。其實"%"命令
能跳轉到好幾種文本元素的`另一半'去。這對檢查你的( ) 和{ }是否正確匹對非常方便。使用"{[{"跳轉到當前代碼塊的開頭(代碼塊是用"{ }"括起來的程序段)。

使用"gd"可以跳轉到當前光標所在的單詞(變量)的局部定義處。當然, 還有很多其它的技巧。關鍵是你要知道有這樣的命令。你也許會說你不可能學習所有的命令---共有幾百個不同的移動命令, 一些很簡單, 還有一些是智能化的---不過它可能要花費你數週的時間學習使用它們。當然, 你不必全部掌握, 只要有你自己的一套辦法, 並且能處理你所要進行的操作。

有三個步驟可以使你學到你需要的技巧:
  1. 當你編輯文件的時侯, 留意一下你經常要重複進行的操作是什麼
  2. 你花大部分時間都在幹些什麼
  3. 想一想有沒有一個編輯命令可以替你做最讓你頭痛的事情
讀在線文檔, 問一個朋友, 或者看一下別人是怎麼做的。練習使用這些命令, 直到你的手指可以不假思索地運用自如。舉個例子來說明到底怎樣做:

你在寫C程序的時侯, 你經常要花時間找到一個函數的定義。現在你使用的是"*"命令查找這個函數名都在哪些地方出現過, 但在你到達真正的目標之前, 可能還有符合你的查找條件的很多個匹配(如註釋中出現的或該函數在其它地方被調用) 騷擾你。你可能會想一定有一種捷徑可以一
步到位。

瀏覽一下參考手冊你就會發現關於tag的主題。文檔會告訴你如何使用這一功能跳轉到函數的定義處。這正是你要的東東!

你已經知道如何生成一個tags文件(ctags *.[ch]或etags *.[ch]),使用ctags 程序就可生成Vim所要的tags文件。接下來你練習使用CTRL-]命令。為了更方便地使用這一功能, 你還可以往你的makefile文件裡加入自動生成tags文件的命令。當你使用這面的三個原則時要當心:

"我想使用這些命令, 但我沒時間去看文檔中的一些新命令"。如果你還這樣想, 那麼你可能還處於計算機的石器時代(就是說你比較菜啦)。有些人做什麼都用notepad, 他們可能覺得別人用更短的時間完成相同的工作是不可思議的事。

不要重複做相同的事。如果你經常要去找一個你常用的命令, 你就沒時間專注於你手頭上的事的。只要找到耗費你太多時間的操作, 練習使用這些操作對應的快捷命令, 直到你可以不假思索地使用它們。這樣你才可能把精力集中在你要編輯的文本上面。

下面是一些多數人都會遇到的常見問題的解決方案的建議。你可以以此為例, 學習使用上面的三個原則。

2. 不要兩次鍵入同樣的東西
我們鍵入的文本都是一個有限的集合。甚至使用了有限的短語和句子。尤其是計算機程序。顯然, 你不必兩次鍵入這些相同的東西。

最常見的事是你要把一個詞改為另一個, 如果你要將整個文件裡所有地方出現的這個詞都換為另一個, 你可以考慮使用":s"命令, 如果你要有選擇地進行更改, 而且最好在看了上下文之後再決定, 你可以使用"*" 命令查找這個詞的另一個匹配, 如果你決定要改, 那麼使用"cw"使用改變這
些詞, 然後再用"n"命令到下一個匹配處使用"."重複上一個命令。"."命令重複上一次改變。一個改變, 是指插入或刪除或替換一些文本。可以對這些操作進行重複是一種功能強大的機制。如果你用它來組織你的編輯操作, 很多以往必需手工做的修改就只需要簡單地使用"."命令。要特別注意在重複上一次修改操作之前你有沒有做其它事, 夾在中間的有些操作可能會改變"."命令實際重複的內容。使用"m"命令標註文本的一個位置地很有用。它可以讓你在作了重複的修改之後回到你上次停留的地方。

一些函數名和變量名很難正確地鍵入, 比如"XpmCreatePixmapFromData",沒有一個樣本看著或不看它的幫助是很難的(至少是很煩的)。Vim有一個補全機制可以讓這種事變成小菜一碟。它會在文件裡查找你要鍵入的文本, 找到相近的匹配就直接插入, 而且, 它還在你的include文件
裡遞歸查找。你可以鍵入"XpmCr", 接著按下CTRL-N鍵, Vim會把它擴充為"XpmCreatePixmapFromData", 這樣的功能還來的不光是為你節省了時間, 它還減少了你手工鍵入時出錯的機會, 而且, 你的編譯器也不會產生那麼的警告錯誤了。

如果你要重複鍵入一個短語或一個句子, 也有一種快捷的方法。Vim有一種記錄宏的機制。你鍵入"qa"開始把一段宏記錄入寄存器變量`a'中。按下來你可以像平常一樣鍵入你要的操作, 只是這些操作都會被Vim記錄進它命名為`a'的內容中, 再次再下"q"鍵, 就結束了`a'的錄製。當你要
重複執行你剛才記錄的那些操作時只要使用"@a"命令。共有26個可用的寄存器供你記錄。

使用宏你可以重複多個不同的操作。而不僅僅是插入文本了。如果你要進行某種重複的操作, 記著要用這一招呀。

使用宏要注意宏只是機械地重複你剛才鍵入的動作, 當你在文件裡移動時要小心。你用宏重複時和你當初錄製時要操作的文本對象可能不一樣。你錄製宏時向右移4 個字符可能對它當前的環境來說是正常工作。但當你回放這些宏時, 它工作的文本環境可能需要移動5個字符。

當你要錄製的操作比較複雜時, 要想一次就全部通過也不是一件容易的事, 此時你可以寫一段宏或腳本。這對於使你的程序模板化非常有用。比如, 一個函數頭, 你可以把這項功能定製得如你所願的智能化。

3. 錯誤修復
打字時出現錯誤是在所難免的事, 辦法只有一個, 就是盡快糾正它。編輯器可以幫你自動做這一工作。但是你要事先告訴它怎麼才算錯, 正確的又是什麼。

對常人來說, 常犯的錯誤都是同一個錯誤。你的手指就是不聽使喚。這可以通過縮寫功能來糾正。一些例子是:
 :abbr Lnuix Linux
 :abbr accross across
 :abbr hte the

你一鍵入完錯誤的詞編輯器就會用正確的詞來替代它。

同樣的機制也可被用來以少數幾個字符代替鍵入一個長的詞。特別是一些你很難正確拼寫出來的詞。這樣也避免了你犯錯誤的機會。例:
:abbr pn pinguin
:abbr MS Mandrake Software

不過, 副作用就是編輯器總是試圖把它所知道的縮寫擴展為整個單詞, 如果你真想鍵入MS, 反倒成了一個難題。所以儘量使用沒有歧義的縮寫。

Vim有一套優秀的語法高亮機制找到你的文本中存在的錯誤。程序員尤其是這一功能的最大受益人。

語法高亮用特殊的顏色來顯示註釋。這聽起來好像沒什麼, 但一旦你使用了這項功能你就會發現好處多多。你可以快速發現哪些部分應該是一個註釋。但是並沒有被語法高亮指出來。對程序員來說, 忘記註釋的結束標記*/是很正常的事。這在只有黑白兩色的文本中可不是一件省油的事。

沒有正確匹對的括號也可被語法高亮指出。一個沒有被正確匹對的括號")"會被一個亮紅色的背景特別指出。你可以使用"%"命令看一看它應該跟誰匹配, 然後在正確的位置補上一個"("或")"

其它的一些常見錯誤也可被語法高亮功能協助你檢查出來, 如#included<stdio.h>。在黑與白的世界中它們對錯難分。但語法高亮可以幫你快速分辨出雌雄真假。

一個更複雜的例子: 對於英語文本來說, 可以有一個長長的可用單詞的列表, 不包括在其中的單詞都被視為一個錯誤, 使用一個語法文件,你可以把所有沒有出現在該文件列表中的單詞用語法高亮功能標出來。用一個特殊的宏你就可以往這個單詞清單裡加入新的生詞。加入後它們就
不再被視為一個錯誤了。這種功能以往只能在單詞分析器中。在Vim中使用簡單的腳本就可實現, 而且, 你可以按自己的需要來定製這一功能。比如, 你可以只檢查程序中的註釋。

第二部分: 編輯多個文件
4. 經常需要編輯不止一個文件
人們往往都不是只編輯一個文件。通常有多個相關的文件。可能要在單個地編輯文件後一次編輯幾個文件。或者同時編輯幾個文件。要進行高效的編輯就要充分利用編輯器一次編輯多個文件的功能。

前面提到的tag機制可被用於在多個文件間跳轉。通常的方法是為你正在做的項目生成一個tag文件。之後就可以在這個項目的多個文件之間自由跳轉, 發現函數定義, 結構, 類型定義typedef, 等等。比起你單個地搜索這些文件, 可以大大節省你的時間; 瀏覽一個項目之前第一要作的事就是為它創建一個tags文件。

另一個強大的機制是在一個項目中找出一個名字在多個文件中的不同地方, 使用":grep"命令。Vim產生所有匹配的清單, 並且跳轉到第一個匹配處。"cn"命令可以使你跳轉到它的下一個匹配處。這對於你要改變一個函數的參數來說非常有用。

可以處理#include所包含的文件。並且可以在其中查找你要找的東西。經常的需求是查看一個函數的原型。將光標定位在你要查看其原型的函數名上, 然後按下"[I"命令, Vim將會顯示include文件中匹配這個函數名的一個清單。如果你要看它的上下文信息, 可以跳轉到它的聲明處。一個簡單的命令可以用來檢查你是否包含了正確的頭文件。

Vim中可以把一個文本區分為幾個不同的部分, 然後分別編輯各個部分, 編輯完成後你可以比較兩個或多個文件的內容, 或在它們之間copy/paste文本內容。有很多命令可以打開或關閉窗口, 或在它們之間跳轉。臨時地隱藏文件。等等。再用上面的三個法則來練習你要掌握的新的命令。

多個窗口有多種用途。預覽標籤機制是一個很好的例證。它會打開一個特殊的預覽窗口, 並且使光標仍然停留在你當前所在的位置。在預覽窗口中的文本列出了當前光標所在處的函數的聲明(有些可能不是聲明) 將當前光標移動到另一個函數名上, 停留幾秒鐘, 預覽窗口中的內容就會變成是關於新函數名的聲明。

5. 協同作業
編輯器是用來編輯文本的, e-mail程序是用來收發email的, 操作系統是用來運行用戶程序的。每個程序都有它自己的業務範圍。將這些程序的功能組合起來就可產生強大的處理能力。

一個簡例: 在一個清單中選擇一些結構化的文本並且將它排序"!sort"。外部程序"sort"處理真正的排序工作。就這麼簡單, 排序功能可以被集成進一個編輯器中。但是, 如果你看一個"man sort", 你就會發現它有眾多可用的選項。它有一個高度優化的算法來執行排序工作。你難道要在你的編輯器裡寫一個同樣強大的排序程序嗎? 或者其它的流過濾程序? 那將會使你的編輯器變得十分臃腫。

Unix的哲學是使用獨立的小程序, 每個小程序做一項專門的任務,並且把它作好, 將它們的工作整合到一起來完成一個複雜的任務。不幸的是, 多數編輯器並不能與其它程序一起協同工作, 比如你不能替換Netscape裡的e-mail編輯器。另一種做法是把所有的功能都包括到一個程序中去。在編輯器領域, emacs是這方面的一個典範(有人甚至說它是一個能編輯文本的操作系統)

Vim的做法是將這些分散的小程序整合起來, 但這樣做也並不容易,目前來說可以在MS的Developer Studio和Sniff中使用Vim編輯器, 一些e-mail程序也支持外掛的編輯器, 象Mutt, 就可以使用Vim。與Sun的Workshop集成也可以正常工作。在這方面Vim還有待在將來進一步提高。直到我們找到一個比所有這些加起來還好的系統。

6.文本是結構化的
可能你經常要打交道的文本都有一些內在的結構。只是不被當前可用的命令所支持而已, 你可能不得不要回頭建立你自己的宏和腳本來操作這些文本。這樣做顯然有些複雜。

最簡單的一件事就是加速你的編輯-編譯-修改的週期。Vim有它自己的":make" 命令, 該命令編譯你的程序項目, 捕獲編譯的錯誤/警告並允許你直接跳轉到引起這一錯誤/警告的程序行上去。如果你有一個另類的編譯器, 它輸出的錯誤信息可能對Vim來說是不可識別的。不要緊, 更改
你的`errorformat'選項, 這一選項告訴Vim你的編譯器將生成何種格式的錯誤信息, 以便於它能識別。比如如何找到出錯的文件名, 出錯的行號,既然它已經能與gcc產生的複雜的錯誤信息格式一同工作, 可以想見, 它也對付多數其它編譯器產生的錯誤信息。

有時為一種特殊格式的文件作出調整也只是設置一些選項, 寫一些宏, 如要跳轉到manual 幫助文檔, 你可以寫一個宏來獲取當前當前所在的詞, 清除當前的緩衝區並且讀入相應的幫助頁, 這對於查看交叉索引是一種簡捷有效的辦法。

使用上面的三項原則你就可以對付任何形式的結構化文本。只要想一下你要對文件做些什麼, 找出編輯命令, 練習使用它。就像聽起來一樣簡單。唯一的事就是你必須真正去做它。

第三部分
7. 養成習慣
學習駕車當然要花費心思, 但這足以成為你繼續騎自行車的理由嗎?不, 你意識到你需要投入時間學習一項技巧。文本編輯與此同理。你需要學習新的命令和技巧。

另一方面, 你也不必學習一個編輯器所提供的所有命令。那樣只會浪費你的時間。絕大多數人只需要學習其中的10-20%的命令就足以應付它們的工作了。但是對每個人來說, 適合自己的命令集各各不同, 這需要你不時地回顧以往所做的事, 看看是不是可以自動完成一些重複的工作。如果你只進行了一次某項特殊的操作, 並且沒指望將來還要進行類似的操作,就不要試著去琢磨它了。但是, 你也許能預見到在幾個小時以內你就要重復進行同樣的操作。那麼去文檔裡面搜索出你希望的"瑞士軍刀" 或者要寫一個宏來完成它。如果任務過於複雜, 比如處理特殊類型的文本, 你可以到新聞組裡看看是不是已經有人解決了與你相似的問題。

決定性的步驟是最後一步, 可能你發現了一個重複操作的解決方案,幾個星期後你卻又忘記了。那樣沒用。你要不斷地重複練習你的解決方案直到你的手指可以條件反射地自動完成, 從而達到你所期望的境界。不要一次嘗試太多的東西, 一次做一件事並多做幾次會好得多。對於不經常的操作, 最好記下你的處理步驟以備將來不時之需。不管怎樣, 只要目標明確。你就能找到讓你的編輯變得更加高效的辦法。

最後要提醒你的一點是人們往往還是會對上面提及的建議視而不見:我還是經常看到人們花費半天的時間在屏幕上用兩個手指上滾下翻。真替他們感到費勁。用十個指頭操作也並不會讓他們更快一點, 而且這樣做也最容易讓人心生厭煩。每天使用一個計算機程序一個小時, 也只需要幾個星期的時間練習這樣的操作。

結束語
本文的由來是受Stephen R.Covey的名作"The 7 habits of highly effective people"啟發。我向我知道的每個人推薦它去解決個人的或專業的問題。也許有些讀者會說這是來自於Scott Adams 的"Seven years of highly defective people"一書(同樣噴血推薦)。參見http://www.vim.org/iccf/click1.html的"rebooks and CDs"。

關於作者
Bram Moolenaar 是Vim的主要作者。他寫了Vim的核心功能並且負責甄選其它作者的代碼。他作為一名技術人員畢業於Delft技術大學, 現在他主要從事軟件業。但他也知道如何使用電烙鐵。他是荷蘭ICCF的創建者和出納。這是一個幫助烏干達孤兒的組織。他作為一個系統建構師為自由軟件工作, 但實際上他為Vim花費了大量的心血。

發表 VIM 的相關文章:

  1. VIM: Vi 中一些常用的使令
  2. VIM: vba套件的安裝與移除
  3. VIM: 製作 vimball 的 vba 安裝檔
  4. VIM: GVim 亂碼的問題
  5. VIM: Vim 中的萬能補全 (Omni Complete)
  6. VIM 七個有效率的文本編輯習慣
Related Posts Plugin for WordPress, Blogger...

沒有留言 :

張貼留言

,,