vim编码详细介绍

附(Vim编码详细介绍):

Vim和所有的流行文本编辑器一样,Vim 可以很好的编辑各种字符编码的文件,这当然包括 UCS-2、UTF-8 等流行的 Unicode 编码方式。

Vim 有四个跟字符编码方式有关的选项,encoding、fileencoding、fileencodings、termencoding (这些选项可能的取值请参考 Vim 在线帮助 :help encoding-names),它们的意义如下:
(1)encoding: Vim 内部使用的字符编码方式,包括 Vim 的 buffer (缓冲区)、菜单文本、消息文本等。用户手册上建议只在 .vimrc 中改变它的值,事实上似乎也只有在 .vimrc 中改变它的值才有意义。
(2)fileencoding: Vim 中当前编辑的文件的字符编码方式,Vim 保存文件时也会将文件保存为这种字符编码方式 (不管是否新文件都如此)。
(3)fileencodings: Vim 启动时会按照它所列出的字符编码方式逐一探测即将打开的文件的字符编码方式,并且将 fileencoding 设置为最终探测到的字符编码方式。因此最好将 Unicode 编码方式放到这个列表的最前面,将拉丁语系编码方式 latin1 放到最后面。
(4)ermencoding: Vim 所工作的终端 (或者 Windows 的 Console 窗口) 的字符编码方式。这个选项在 Windows 下对我们常用的 GUI 模式的 gVim 无效,而对 Console 模式的 Vim 而言就是 Windows 控制台的代码页,并且通常我们不需要改变它。

来看看 Vim 的多字符编码方式支持是如何工作的。
(1)Vim 启动,根据 .vimrc 中设置的 encoding 的值来设置 buffer、菜单文本、消息文的字符编码方式。
(2)读取需要编辑的文件,根据 fileencodings 中列出的字符编码方式逐一探测该文件编码方式。并设置 fileencoding 为探测到的,看起来是正确的 (注1) 字符编码方式。
(3)对比 fileencoding 和 encoding 的值,若不同则调用 iconv 将文件内容转换为 encoding 所描述的字符编码方式,并且把转换后的内容放到为此文件开辟的 buffer 里,此时我们就可以开始编辑这个文件了。注意,完成这一步动作需要调用外部的 iconv.dll (注2),你需要保证这个文件存在于 $VIMRUNTIME 或者其他列在 PATH 环境变量中的目录里。
(4)编辑完成后保存文件时,再次对比 fileencoding 和 encoding 的值。若不同,再次调用 iconv 将即将保存的 buffer 中的文本转换为 fileencoding 所描述的字符编码方式,并保存到指定的文件中。同样,这需要调用 iconv.dll

由于 Unicode 能够包含几乎所有的语言的字符,而且 Unicode 的 UTF-8 编码方式又是非常具有性价比的编码方式 (空间消耗比 UCS-2 小),因此建议 encoding 的值设置为 utf-8。这么做的另一个理由是 encoding 设置为 utf-8 时,Vim 自动探测文件的编码方式会更准确 (或许这个理由才是主要的 ;) 。我们在中文 Windows 里编辑的文件,为了兼顾与其他软件的兼容性,文件编码还是设置为 GB2312/GBK 比较合适,因此 fileencoding 建议设置为 chinese (chinese 是个别名,在 Unix 里表示 gb2312,在 Windows 里表示 cp936,也就是 GBK 的代码页)。 


这个问题只能说是因为我老土啦。。。 

vim 在插入模式下<BS>有几种工作方式,默认是设置成vi兼容,这样就会出现无法删除此次插入前文字的情况。改成 ":set backspace=indent,eol,start" 就好了。 
set backspace=2 


基本上在 Vim 可以使用

        set shiftwidth=4

來設定 tab 寬。

而使用

        set expandtab

來將 tab 轉成 space (實際存起來的檔案將會是以 space , not tab )

如果要將既有的 <Tab> 轉成 space 可以再 expandtab 之後輸入:

        :retab!

來做轉換。

而 tabstop 是實際上讀到檔案的 \t (Tab 字元) 時,要解譯為幾個空白

通常設定為 4

        set tabstop=4

另外 softtabstop 則是,你在編輯動作 (Backspace) 或是 (Tab) 時,對空白的解譯

譬如說:

        set noexpandtab
        set sw=4
        set tabstop=4
        set softtabstop=4

新加入的 Tab 都會是 \t , Tab 為 4 個 space ,讀取檔案的 \t 會被翻譯為 4 個
space ,在操作 BS 的時候,4 個空白會被當作一個 tab 刪除。

實際上 softabstop 比較常用在 expandtab 的模式下:

        set expandtab
        set sw=4
        set tabstop=4  " 怕檔案裡頭仍有 \t
        set softtabstop=4

如此被延展為空白的 space 也可以像是 tab 一樣被刪除固定的 space 數
 (softtabstop=4)

附帶一題,由於 tab 每個人的用法都不一樣,而且變化很多
而現在很多專案都只使用 space 而不使用 tab 了!

也就是:

        set et sw=4 ts=4 sts=4

這樣的設定通常是被建議的。



[vim编码方面的基础知识]

1,存在3个变量:
encoding----该选项使用于缓冲的文本(你正在编辑的文件),寄存器,Vim
脚本文件等等。你可以把 'encoding' 选项当作是对 Vim
内部运行机制的设定。
fileencoding----该选项是vim写入文件时采用的编码类型。
termencoding----该选项代表输出到客户终端(Term)采用的编码类型。
2,此3个变量的默认值:
encoding----与系统当前locale相同,所以编辑文件的时候要考虑当前locale,否则要设置的东西就比较多了。
fileencoding----vim打开文件时自动辨认其编码,fileencoding就为辨认的值。为空则保存文件时采用encoding的编码,如果没有修改encoding,那值就是系统当前locale了。
termencoding----默认空值,也就是输出到终端不进行编码转换。
由此可见,编辑不同编码文件需要注意的地方不仅仅是这3个变量,还有系统当前locale和、文件本身编码以及自动编码识别、客户运行vim的终端所使用的编码类型3个关键点,这3个关键点影响着3个变量的设定。
如果有人问:为什么我用vim打开中文文档的时候出现乱码?
答案是不确定的,原因上面已经讲了,不搞清楚这3个关键点和这3个变量的设定值,出现乱码是正常的,倒是不出现乱码那反倒是凑巧的。

再来看一下常见情况下这三个关键点的值以及在这种情况下这3个变量的值:
1.locale----目前大部分Linux系统已经将utf-8作为默认
locale了,不过也有可能不是,例如有些系统使用中文locale
zh_CN.GB18030。在locale为utf-8的情况下,启动vim后encoding将会设置为utf-8,这是兼容性最好的方式,因为内部
处理使用utf-8的话,无论外部存储编码为何都可以进行无缺损转换。locale决定了vim内部处理数据的编码,也就是encoding。
2.文件的编码以及自动编码识别----这方面牵扯到各种编码的规则,就不一一细讲了。但需要明白的是,文件编码类型并不是保存在文件内的,也就是说没有
任何描述性的字段来记录文档是何种编码类型的。因此我们在编辑文档的时候,要么必须知道这文档保存时是以什么编码保存的,要么通过另外的一些手段来断定编
码类型,这另外的手段,就是通过某些编码的码表特征来断定,例如每个字符占用的字节数,每个字符的ascii值是否都大于某个字段来断定这个文件属于何种
编码。这种方式vim也使用了,这就是vim的自动编码识别机制了。但这种机制由于编码各式各样,不可能每种编码都有显著的特征来辨别,所以是不可能
100%准确的。对于我们GB2312编码,由于其中文是使用了2个acsii值高于127的字符组成汉字字符的,因此不可能把gb2312编码的文件与
latin1编码区分开来,因此自动识别编码的机制对于gb2312是不成功的,它只会将文件辨识为latin1编码。此问题同样出现在gbk,big5
上等。因此我们在编辑此类文档时,需要手工设定encoding和fileencoding。如果文档编码为utf-8时,一般vim都能自动识别正确的
编码。

3.客户运行vim的终端所使用的编码类型----同第二条一样,这也是一个比较
难以断定的关键点。第二个关键点决定着从文件读取内容和写入内容到文件时使用的编码,而此关键点则决定vim输出内容到终端时使用的编码,如果此编码类型
和终端认为它收到的数据的编码类型不同,则又会产生乱码问题。在
linux本地X环境下,一般终端都认为其接收的数据的编码类型和系统locale类型相符,因此不需关心此方面是否存在问题。但如果牵涉到远程终端,例
如ssh登录服务器,则问题就有可能出现了。例如从1台locale为GB2310的系统(称作客户机)ssh到locale为utf-8的系统(称作服
务器)并开启vim编辑文档,在不加任何改动的情况下,服务器返回的数据为utf-8的,但客户机认为服务器返回的数据是gb2312的,按照
gb2312来解释数据,则肯定就是乱码了,这时就需要设置termencoding为gb2312来解决这个问题。此问题更多出现在我们的
windows
desktop机远程ssh登录服务器的情况下,这里牵扯到不同系统的编码转换问题。所以又与windows本身以及ssh客户端有很大相关性。在
windows下存在两种编码类型的软件,一种是本身就为unicode编码方式编写的软件,一种是ansi软件,也就是程序处理数据直接采用字节流,不
关心编码。前一种程序可以在任何语言的windows上正确显示多国语言,而后一种则编写在何种语言的系统上则只能在何种语言的系统上显示正确的文字。对
于这两种类型的程序,我们需要区别对待。以ssh客户端为例,我们使用的putty是unicode软件,而secure
CRT则是ansi
软件。对于前者,我们要正确处理中文,只要保证vim输出到终端的编码为utf-8即可,就是termencoding=utf-8。但对于后者,一方面
我们要确认我们的windows系统默认代码页为cp936(中文windows默认值),另一方面要确认vim设置的termencoding=
cp936。

最后来看看处理中文文档最典型的几种情况和设置方式:

1.系统locale是utf-8(很多linux系统默认的locale形
式),编辑的文档是GB2312或GBK形式的(Windows记事本默认保存形式,大部分编辑器也默认保存为这个形式,所以最常见),终端类型utf-
8(也就是假定客户端是putty类的unicode软件)
则vim打开文档后,encoding=utf-8(locale决定的),fileencoding=latin1(自动编码判断机制不准导致的),termencoding=空(默认无需转换term编码),显示文件为乱码。
解决方案1:首先要修正fileencoding为cp936或者euc-cn(二者一样的,只不过叫法不同),注意修正的方法不是:set
fileencoding=cp936,这只是将文件保存为cp936,正确的方法是重新以cp936的编码方式加载文件为:edit
++enc=cp936,可以简写为:e ++enc=cp936。
解决方案2:临时改变vim运行的locale环境,方法是以LANG=zh_CN vim
abc.txt的方式来启动vim,则此时encoding=euc-cn(locale决定的),fileencoding=空(此locale下文件
编码自动判别功能不启用,所以fileencoding为文件本身编码方式不变,也就是euc-cn),termencoding=空(默认值,为空则等
于encoding)此时还是乱码的,因为我们的ssh终端认为接受的数据为utf-8,但vim发送数据为euc-cn,所以还是不对。此时再用命令:
set
termencoding=utf-8将终端数据输出为utf-8,则显示正常。

2.情况与1基本相同,只是使用的ssh软件为secure
CRT类ansi类软件。
vim打开文档后,encoding=utf-8(locale决定的),fileencoding=latin1(自动编码判断机制不准导致的),termencoding=空(默认无需转换term编码),显示文件为乱码。
解决方案1:首先要保证运行secure
CRT的windows机器的默认代码页为CP936,这一点中文windows已经是默认设置了。其他的与上面方案1相同,只是要增加一步,:set
termencoding=cp936
解决方案2:与上面方案2类似,不过最后一步修改termencoding省略即可,在此情况下需要的修改最少,只要以locale为zh_CN开启
vim,则encoding=euc-cn,fileencoding和termencoding都为空即为encoding的值,是最理想的一种情况。
              

你可能感兴趣的:(vim编码详细介绍)