在 Vim 中,有四个与编码有关的选项,它们是:fileencodings
、fileencoding
、encoding
和 termencoding
。在实际使用中,任何一个选项出现错误,都会致使出现乱码。所以,每个 Vim 用户都应该明确这四个选项的含义。下面,咱们详细介绍一下这四个选项的含义和做用。php
encoding
是 Vim 内部使用的字符编码方式。当咱们设置了 encoding
以后,Vim 内部全部的 buffer、寄存器、脚本中的字符串等,全都使用这个编码。Vim 在工做的时候,若是编码方式与它的内部编码不一致,它会先把编码转换成内部编码。若是工做用的编码中含有没法转换为内部编码的字符,在这些字符就会丢失。所以,在选择 Vim 的内部编码的时候,必定要使用一种表现能力足够强的编码,以避免影响正常工做。vim
因为 encoding
选项涉及到 Vim 中全部字符的内部表示,所以只能在 Vim 启动的时候设置一次。在 Vim 工做过程当中修改encoding
会形成很是多的问题。若是没有特别的理由,请始终将 encoding
设置为 utf-8
。为了不在非 UTF-8 的系统如 Windows 下,菜单和系统提示出现乱码,可同时作这几项设置:编码
set encoding=utf-8
set langmenu=zh_CN.UTF-8
language message zh_CN.UTF-8spa
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 没法表示的字符时,这些字符就会丢失。但若是使用后一种方法,虽然因为终端所限,这些字符没法显示,但在编辑过程当中这些字符是不会丢失的。code
对于图形界面下的 GVim,它的显示不依赖 TERM,所以 termencoding
对于它没有意义。在 GTK2 下的 GVim 中,termencoding
永远是 utf-8
,而且不能修改。而 Windows 下的 GVim 则忽略 termencoding
的存在。orm
当 Vim 从磁盘上读取文件的时候,会对文件的编码进行探测。若是文件的编码方式和 Vim 的内部编码方式不一样,Vim 就会对编码进行转换。转换完毕后,Vim 会将 fileencoding
选项设置为文件的编码。当 Vim 存盘的时候,若是 encoding
和fileencoding
不同,Vim 就会进行编码转换。所以,经过打开文件后设置 fileencoding
,咱们能够将文件由一种编码转换为另外一种编码。可是,由前面的介绍能够看出,fileencoding
是在打开文件的时候,由 Vim 进行探测后自动设置的。所以,若是出现乱码,咱们没法经过在打开文件后从新设置 fileencoding
来纠正乱码。ip
编码的自动识别是经过设置 fileencodings 实现的,注意是复数形式。fileencodings 是一个用逗号分隔的列表,列表中的每一项是一种编码的名称。当咱们打开文件的时候,VIM 按顺序使用 fileencodings 中的编码进行尝试解码,若是成功的话,就使用该编码方式进行解码,并将 fileencoding
设置为这个值,若是失败的话,就继续试验下一个编码。utf-8
所以,咱们在设置 fileencodings
的时候,必定要把要求严格的、当文件不是这个编码的时候更容易出现解码失败的编码方式放在前面,把宽松的编码方式放在后面。ci
例如,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 前面。
至于 big五、euc-jp 和 euc-kr,它们的严格程度和 cp936 差很少,把它们放在后面,在编辑这些编码的文件的时候必然出现大量误判,但这是 Vim 内置编码探测机制没有办法解决的事。因为中国用户不多有机会编辑这些编码的文件,所以咱们仍是决定把 cp936 和 gb18030 前提以保证这些编码的识别。
最后就是 latin1 了。它是一种极其宽松的编码,以致于咱们不得不把它放在最后一位。不过惋惜的是,当你碰到一个真的 latin1 编码的文件时,绝大部分状况下,它没有机会 fall-back 到 latin1,每每在前面的编码中就被误判了。不过,正如前面所说的,中国用户没有太多机会接触这样的文件。
若是编码被误判了,解码后的结果就没法被人类识别,因而咱们就说,这个文件乱码了。此时,若是你知道这个文件的正确编码的话,能够在打开文件的时候使用 ++enc=encoding
的方式来打开文件,如:
:e ++enc=utf-8 myfile.txt
根据前面的介绍,咱们知道,经过 Vim 内置的编码识别机制,识别率是很低的,尤为是对于简体中文 (GBK/GB18030)、繁体中文 (Big5)、日文 (euc-jp) 和韩文 (euc-kr) 之间的识别。而对于普通用户而言,肉眼看出一个文件的编码方式也是很不现实的事情。所以,滇狐强烈推荐水木社区的 mbbill 开发的 fencview 插件。该插件使用词频统计的方式识别编码,正确率很是高。点击这里 下载。