-
Notifications
You must be signed in to change notification settings - Fork 28
/
learn-vi-21-MultiEncodings.html
57 lines (53 loc) · 7.58 KB
/
learn-vi-21-MultiEncodings.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh" xml:lang="zh">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="learn-vi.css" />
<title>VIM学习笔记 多编码处理 (Multi-Encodings)</title>
</head>
<body>
<p>在Vim中有四个与编码有关的选项:“fileencodings (fencs)”、“fileencoding (fenc)”、“encoding (enc)”和“termencoding (tenc)”,任何一个选项出现错误,都会导致出现乱码。</p>
<p style="font-weight:bold; border-bottom:1px solid lightgray; border-left:6px solid lightgray; padding:0 0 3px 5px">encoding</p>
<p>encoding是Vim内部使用的字符编码方式。Vim内部所有的buffer、寄存器、脚本中的字符串等,都会使用encoding设置的编码。如果编码方式与Vim的内部编码不一致,那么会先把编码转换成内部编码。如果编码中含有无法转换为内部编码的字符,那么这些字符就会丢失。因此,在选择Vim内部编码时,一定要使用一种包容力足够强的编码。由于encoding选项涉及到Vim中所有字符的内部表示,因此只能在Vim启动的时候设置一次。在Vim工作过程中修改encoding会造成非常多的问题。</p>
<p>建议将encoding设置为utf-8,同时设置以下选项,以避免在非UTF-8系统(如Windows)下,菜单和系统提示出现乱码:</p>
<p style="margin:0 2em"><code class="inset">
set encoding=utf-8<br />
set langmenu=zh_CN.UTF-8<br />
language message zh_CN.UTF-8<br />
</code></p>
<p>当然,你也可以设置菜单和信息都显示为英文,这样也可以避免Vim程序界面乱码的问题:</p>
<p style="margin:0 2em;"><code class="inset">
set langmenu=en_US<br />
let $LANG = 'en_US'<br />
source $VIMRUNTIME/delmenu.vim<br />
source $VIMRUNTIME/menu.vim<br />
</code></p>
<p style="font-weight:bold; border-bottom:1px solid lightgray; border-left:6px solid lightgray; padding:0 0 3px 5px">termencoding</p>
<p>termencoding是Vim用于屏幕显示的编码。Vim会把内部编码转换为屏幕编码,再用于输出。内部编码中含有无法转换为屏幕编码的字符时,该字符会变成问号,但不会影响对它的编辑操作。如果termencoding没有设置,则直接使用encoding而不进行转换。</p>
<p>例如,你在Windows下通过telnet登录Linux工作站时,由于Windows的telnet是GBK编码的,而Linux则使用UTF-8编码,因此telnet下的Vim中就会乱码。此时有两种消除乱码的方式:你可以将Vim的encoding改为gbk,或者保持encoding为utf-8,而将termencoding改为gbk。显然,使用前一种方法时,如果编辑的文件中含有GBK无法表示的字符时,这些字符就会丢失。但如果使用后一种方法,虽然由于终端所限,这些字符无法显示,但在编辑过程中这些字符并不会丢失。</p>
<p>你可以利用以下命令设置termencoding:</p>
<p style="text-indent:2em"><code class="inset">set termencoding=utf-8</code></p>
<p>对于图形界面下的GVim,它的显示不依赖TERM,因此termencoding对于它没有意义。在GTK2下的GVim中,termencoding永远是utf-8,并且不能修改。而Windows下的GVim则忽略termencoding的存在。</p>
<p style="font-weight:bold; border-bottom:1px solid lightgray; border-left:6px solid lightgray; padding:0 0 3px 5px">fileencoding</p>
<p>当Vim从磁盘上读取文件时,会对文件编码进行探测。如果文件的编码方式和Vim的内部编码方式不同,Vim就会对编码进行转换。转换完毕后,Vim会将fileencoding选项设置为文件的编码。当Vim存盘时,如果encoding和fileencoding不一致,Vim就会进行编码转换。因此,通过打开文件后设置fileencoding,可以将文件由一种编码转换为另一种编码。</p>
<p style="text-indent:2em"><code class="inset">set fileencoding=utf-8</code></p>
<p>注意:因为Vim是在打开文件时,自动探测和设置fileencoding的,所以,如果出现乱码,就无法通过在打开文件后重新设置fileencoding来纠正乱码。</p>
<p style="font-weight:bold; border-bottom:1px solid lightgray; border-left:6px solid lightgray; padding:0 0 3px 5px">fileencodings</p>
<p>编码的自动识别,是通过设置fileencodings实现的。fileencodings是一个用逗号分隔的列表,列表中的每一项是一种编码的名称。当我们打开文件时,Vim按顺序使用fileencodings中的编码进行尝试解码,如果成功的话,就使用该编码方式进行解码,并将fileencoding设置为这个值;如果失败的话,就继续检验下一个编码。因此,我们在设置fileencodings时,一定要把严格的编码方式放在前面,把宽松的编码方式放在后面。例如,latin1是一种非常宽松的编码方式,任何一种编码方式得到的文本,用latin1进行解码,都不会发生解码失败。当然,解码得到的结果也很可能会是乱码。因此,如果你把latin1放到fileencodings的第一位,那么打开任何中文文件都会显示乱码了。推荐使用以下fileencodings设置:</p>
<p style="text-indent:2em"><code class="inset">set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,latin1</code></p>
<p>其中, <span style="font-style:italic">ucs-bom</span> 是一种非常严格的编码,非该编码的文件几乎没有可能被误判为ucs-bom,因此放在第一位。<span style="font-style:italic">utf-8</span> 也相当严格,除了很短的文件之外也是几乎不可能被误判的,因此放在第二位。接下来是 <span style="font-style:italic">cp936</span>、<span style="font-style:italic">gb18030</span>、<span style="font-style:italic">big5</span> 这些编码相对宽松的编码。 而最为宽松的 <span style="font-style:italic">latin1</span> 编码,则放在列表的最后。</p>
<p>如果编码被误判了,解码后的结果就会显示为无法识别的乱码了。此时,如果你知道这个文件的正确编码,可以把fileencodings改成只有这一种编码,阻止任何 fall-back 发生,然后重新打开这个文件。</p>
<p style="font-weight:bold; border-bottom:1px solid lightgray; border-left:6px solid lightgray; padding:0 0 3px 5px">编码转换</p>
<p>当我们看到类似“&#24573;&#28982;”的编码时,可以通过以下命令将&#后的数字,经由函数nr2char()转换为可读的文字:</p>
<p style="text-indent:2em"><code class="inset">:%s/&#\([0-9]\+\);/\=nr2char(submatch(1))/g</code></p>
<table summary="Commands" border="2" frame="hsides" rules="all" cellspacing="0" cellpadding="3">
<caption>命令小结</caption>
<tr><td><code class="inset">set encoding</code></td><td>设置Vim的内部编码方式</td></tr>
<tr><td><code class="inset">set termencoding</code></td><td>设置Vim的屏幕显示编码</td></tr>
<tr><td><code class="inset">set fileencoding</code></td><td>设置文件的编码方式</td></tr>
<tr><td><code class="inset">set fileencodings</code></td><td>设置Vim的解码列表</td></tr>
</table>
<p style="border-top:1px solid lightgray"><span style="float:right">Ver: 1.0</span><span><<a title="宏(Macro)" href="http://yyq123.blogspot.com/2011/03/vim-macro.html">上一篇</a> |<a title="笔记列表" href="http://yyq123.github.com/learn-vim/learn-vi-00-List.html"> 目录 </a>| <a title="加密 (Encyption)" href="http://yyq123.blogspot.com/2011/01/vim-encyption.html">下一篇</a>></span></p>
</body>
</html>