VIM顯示utf-8文檔亂碼解決方法



1.相關基礎知識介紹


        在Vim中。有四個與編碼有關的選項,它們是:fileencodings、fileencoding、encoding和termencoding。

在實際使用中。不論什么一個選項出現錯誤。都會導致出現亂碼。

因此,每個Vim用戶都應該明白這四個選項的含義。以下,我們具體介紹一下這四個選項的含義和作用。

        (1)encoding
        encoding是Vim內部使用的字符編碼方式。當我們設置了encoding之后。Vim內部全部的buffer、寄存器、腳本中的字符串等,全都使用這個編碼。Vim 在工作的時候。假設編碼方式與它的內部編碼不一致,它會先把編碼轉換成內部編碼。假設工作用的編碼中含有無法轉換為內部編碼的字符,在這些字符就會丟失。因此,在選擇 Vim 的內部編碼的時候,一定要使用一種表現能力足夠強的編碼,以免影響正常工作。
        因為encoding選項涉及到Vim中全部字符的內部表示,因此僅僅能在Vim啟動的時候設置一次。

在Vim工作過程中改動encoding會造成許多的問題。用戶手冊上建議僅僅在 .vimrc中改變它的值,其實似乎也僅僅有在 .vimrc中改變它的值才有意義。

假設沒有特別的理由,請始終將encoding設置為utf-8。為了避免在非UTF-8的系統如Windows下,菜單和系統提示出現亂碼。可同一時候做這幾項設置:
        set encoding=utf-8
        set langmenu=zh_CN.UTF-8
        language message zh_CN.UTF-8

        (2)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,讓Vim在顯示的時候轉碼。顯然。使用前一種方法時,假設遇到編輯的文件里含有GBK無法表示的字符時,這些字符就會丟失。

但假設使用后一種方法。盡管因為終端所限,這些字符無法顯示,但在編輯過程中這些字符是不會丟失的。
        對於圖形界面下的GVim,它的顯示不依賴TERM,因此termencoding對於它沒有意義。在GTK2下的GVim 中,termencoding永遠是utf-8,而且不能改動。

而Windows下的GVim則忽略termencoding的存在。

        (3)fileencoding
        當Vim從磁盤上讀取文件的時候。會對文件的編碼進行探測。假設文件的編碼方式和Vim的內部編碼方式不同,Vim就會對編碼進行轉換。轉換完成后,Vim會將fileencoding選項設置為文件的編碼。

當Vim存盤的時候。假設encoding和fileencoding不一樣,Vim就會進行編碼轉換。因此。通過打開文件后設置fileencoding。我們能夠將文件由一種編碼轉換為還有一種編碼。

可是,由前面的介紹能夠看出,fileencoding是在打開文件的時候。由Vim進行探測后自己主動設置的。

因此。假設出現亂碼,我們無法通過在打開文件后又一次設置fileencoding來糾正亂碼。


        簡而言之,fileencoding是Vim中當前編輯的文件的字符編碼方式,Vim保存文件時也會將文件保存為這樣的字符編碼方式 (無論是否新文件都如此)。

        (4)fileencodings
        編碼的自己主動識別是通過設置fileencodings實現的,注意是復數形式。fileencodings是一個用逗號分隔的列表。列表中的每一項是一種編碼的名稱。

當我們打開文件的時候,VIM按順序使用fileencodings中的編碼進行嘗試解碼。假設成功的話,就使用該編碼方式進行解碼。並將fileencoding設置為這個值,假設失敗的話,就繼續試驗下一個編碼。


        因此。我們在設置fileencodings的時候,一定要把要求嚴格的、當文件不是這個編碼的時候更easy出現解碼失敗的編碼方式放在前面,把寬松的編碼方式放在后面。比如。latin1是一種很寬松的編碼方式,不論什么一種編碼方式得到的文本,用latin1進行解碼。都不會發生解碼失敗——當然,解碼得到的結果自然也就是理所當然的“亂碼”。因此,假設你把latin1放到了fileencodings的第一位的話,打開不論什么中文文件都是亂碼也就是理所當然的了。


        下面是網上推薦的一個fileencodings設置:

        set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,euc-kr,latin1
        當中,ucs-bom是一種很嚴格的編碼,非該編碼的文件差點兒沒有可能被誤判為ucs-bom,因此放在第一位。


        utf-8也相當嚴格,除了非常短的文件外(比如很多人津津樂道的GBK編碼的“聯通”被誤判為UTF-8編碼的經典錯誤),現實生活中一般文件是差點兒不可能被誤判的,因此放在第二位。


        接下來是cp936和gb18030。這兩種編碼相對寬松。假設放前面的話,會出現大量誤判。所以就讓它們靠后一些。cp936的編碼空間比gb18030小,所以把cp936放在gb18030前面。
        至於big5、euc-jp和euc-kr,它們的嚴格程度和cp936差點兒相同,把它們放在后面,在編輯這些編碼的文件的時候必定出現大量誤判,但這是Vim內置編碼探測機制沒有辦法解決的事。因為中國用戶非常少有機會編輯這些編碼的文件。因此我們還是決定把cp936和gb18030放在前面以保證這些編碼的識別。
        最后就是latin1了。它是一種極其寬松的編碼,以至於我們不得不把它放在最后一位。只是可惜的是。當你碰到一個真的latin1編碼的文件時,絕大部分情況下,它沒有機會fall-back到latin1。往往在前面的編碼中就被誤判了。只是,正如前面所說的,中國用戶沒有太多機會接觸這種文件。
        假設編碼被誤判了。解碼后的結果就無法被人類識別。於是我們就說,這個文件亂碼了。

此時。假設你知道這個文件的正確編碼的話,能夠在打開文件的時候使用 ++enc=encoding 的方式來打開文件。如:
        :e ++enc=utf-8 myfile.txt

2.Vim的工作原理

        好了,解釋完了這一堆easy讓新手犯糊塗的參數,我們來看看Vim的多字符編碼方式支持是怎樣工作的。


        (1)Vim啟動,依據 .vimrc中設置的encoding的值來設置buffer、菜單文本、消息文的字符編碼方式。
        (2)讀取須要編輯的文件,依據fileencodings中列出的字符編碼方式逐一探測該文件編碼方式。

並設置fileencoding為探測到的,看起來是正確的字符編碼方式。

其實,Vim 的探測精確度並不高,尤其是在encoding沒有設置為utf-8時。

因此強烈建議將encoding設置為utf-8,盡管假設你想Vim顯示中文菜單和提示消息的話這樣會帶來還有一個小問題。
        (3)對照fileencoding和encoding的值,若不同則調用iconv將文件內容轉換為encoding所描寫敘述的字符編碼方式,而且把轉換后的內容放到為此文件開辟的buffer里,此時我們就能夠開始編輯這個文件了。注意。完畢這一步動作須要調用外部的iconv.dll(注2)。你須要保證這個文件存在於$VIMRUNTIME或者其它列在PATH環境變量中的文件夾里。
        (4)編輯完畢后保存文件時。再次對照fileencoding和encoding的值。若不同,再次調用iconv將即將保存的buffer中的文本轉換為fileencoding所描寫敘述的字符編碼方式,並保存到指定的文件里。相同,這須要調用iconv.dll

3.解決的方法演示樣例

        (1)方法一:設定.vimrc文件:
        在/home/username/.vimrc或者/root/.vimrc下添加兩句話:
        let &termencoding=&encoding
        set fileencodings=utf-8,gbk,ucs-bom,cp936
        這樣的辦法能夠實現編輯UTF-8文件

        (2)方法而二:打開文件后,在vi編輯器中設定:
        :set encoding=utf-8 termencoding=gbk fileencoding=utf-8

        (3)方法三:新建UTF-8文件,在vi編輯器設定:
        :set fenc=utf-8
        :set enc=GB2312
        這樣在編輯器里輸入中文,保存的文件是UTF-8。

        (4)方法四:一個推薦的~/.vimrc文件配置:
        set encoding=utf-8
        set fileencodings=ucs-bom,utf-8,cp936,gb18030,latin1
        set termencoding=gb18030
        set expandtab
        set ts=4
        set shiftwidth=4
        set nu
        syntax on

        if has('mouse')
        set mouse-=a
        endif


        后記:本文依據網絡上相關資料整理。因為來源較多,未能一一標明出處,敬請各位原創作者見諒。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM