標籤:

VIM學習筆記 多編碼處理 (Multi-Encodings)

在Vim中有四個與編碼有關的選項:「fileencodings (fencs)」、「fileencoding (fenc)」、「encoding (enc)」和「termencoding (tenc)」,任何一個選項出現錯誤,都會導致出現亂碼。

encoding

encoding是Vim內部使用的字元編碼方式。Vim內部所有的buffer、寄存器、腳本中的字元串等,都會使用encoding設置的編碼。如果編碼方式與Vim的內部編碼不一致,那麼會先把編碼轉換成內部編碼。如果編碼中含有無法轉換為內部編碼的字元,那麼這些字元就會丟失。因此,在選擇Vim內部編碼時,一定要使用一種包容力足夠強的編碼。由於encoding選項涉及到Vim中所有字元的內部表示,因此只能在Vim啟動的時候設置一次。在Vim工作過程中修改encoding會造成非常多的問題。

建議將encoding設置為utf-8,同時設置以下選項,以避免在非UTF-8系統(如Windows)下,菜單和系統提示出現亂碼:

set encoding=utf-8set langmenu=zh_CN.UTF-8language message zh_CN.UTF-8

當然,你也可以設置菜單和信息都顯示為英文,這樣也可以避免Vim程序界面亂碼的問題:

set langmenu=en_USlet $LANG = en_USsource $VIMRUNTIME/delmenu.vimsource $VIMRUNTIME/menu.vim

termencoding

termencoding是Vim用於屏幕顯示的編碼。Vim會把內部編碼轉換為屏幕編碼,再用於輸出。內部編碼中含有無法轉換為屏幕編碼的字元時,該字元會變成問號,但不會影響對它的編輯操作。如果termencoding沒有設置,則直接使用encoding而不進行轉換。

例如,你在Windows下通過telnet登錄Linux工作站時,由於Windows的telnet是GBK編碼的,而Linux則使用UTF-8編碼,因此telnet下的Vim中就會亂碼。此時有兩種消除亂碼的方式:你可以將Vim的encoding改為gbk,或者保持encoding為utf-8,而將termencoding改為gbk。顯然,使用前一種方法時,如果編輯的文件中含有GBK無法表示的字元時,這些字元就會丟失。但如果使用後一種方法,雖然由於終端所限,這些字元無法顯示,但在編輯過程中這些字元並不會丟失。

你可以利用以下命令設置termencoding:

set termencoding=utf-8

對於圖形界面下的GVim,它的顯示不依賴TERM,因此termencoding對於它沒有意義。在GTK2下的GVim中,termencoding永遠是utf-8,並且不能修改。而Windows下的GVim則忽略termencoding的存在。

fileencoding

當Vim從磁碟上讀取文件時,會對文件編碼進行探測。如果文件的編碼方式和Vim的內部編碼方式不同,Vim就會對編碼進行轉換。轉換完畢後,Vim會將fileencoding選項設置為文件的編碼。當Vim存檔時,如果encoding和fileencoding不一致,Vim就會進行編碼轉換。因此,通過打開文件後設置fileencoding,可以將文件由一種編碼轉換為另一種編碼。

set fileencoding=utf-8

注意:因為Vim是在打開文件時,自動探測和設置fileencoding的,所以,如果出現亂碼,就無法通過在打開文件後重新設置fileencoding來糾正亂碼。

fileencodings

編碼的自動識別,是通過設置fileencodings實現的。fileencodings是一個用逗號分隔的列表,列表中的每一項是一種編碼的名稱。當我們打開文件時,Vim按順序使用fileencodings中的編碼進行嘗試解碼,如果成功的話,就使用該編碼方式進行解碼,並將fileencoding設置為這個值;如果失敗的話,就繼續檢驗下一個編碼。因此,我們在設置fileencodings時,一定要把嚴格的編碼方式放在前面,把寬鬆的編碼方式放在後面。例如,latin1是一種非常寬鬆的編碼方式,任何一種編碼方式得到的文本,用latin1進行解碼,都不會發生解碼失敗。當然,解碼得到的結果也很可能會是亂碼。因此,如果你把latin1放到fileencodings的第一位,那麼打開任何中文文件都會顯示亂碼了。推薦使用以下fileencodings設置:

set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,latin1

其中, ucs-bom 是一種非常嚴格的編碼,非該編碼的文件幾乎沒有可能被誤判為ucs-bom,因此放在第一位。utf-8也相當嚴格,除了很短的文件之外也是幾乎不可能被誤判的,因此放在第二位。接下來是 cp936、gb18030、big5 這些編碼相對寬鬆的編碼。 而最為寬鬆的 latin1 編碼,則放在列表的最後。

如果編碼被誤判了,解碼後的結果就會顯示為無法識別的亂碼了。此時,如果你知道這個文件的正確編碼,可以把fileencodings改成只有這一種編碼,阻止任何 fall-back 發生,然後重新打開這個文件。

編碼轉換

當我們看到類似「忽然」的編碼時,可以通過以下命令將&#後的數字,經由函數nr2char()轉換為可讀的文字:

:%s/&#([0-9]+);/=nr2char(submatch(1))/g

推薦閱讀:

VIM學習筆記 字體(Font)
如何選購 Vim 腳踏板?
如何使 Vim 下開發 Python 調試更方便?
Vim 和 Emacs 到底哪個更牛逼一點?
Vim 折騰記

TAG:Vim |