为什么VIM会忽略我的文件BOM?

Ren*_*ger 5 vim byte-order-mark utf-8

我需要一个文件,我想确保用utf8编码.

所以,我创建了该文件

c:\> gvim umlaute.txt
Run Code Online (Sandbox Code Playgroud)

在VIM我键入Umlaute:

äöü
Run Code Online (Sandbox Code Playgroud)

我检查编码...

:set enc
Run Code Online (Sandbox Code Playgroud)

(VIM回声encoding=latin1)

然后我检查文件编码...

:set fenc
Run Code Online (Sandbox Code Playgroud)

(VIM回声fileencoding=)

然后我写了文件

:w
Run Code Online (Sandbox Code Playgroud)

并检查硬盘上文件的大小:

!dir umlaute.txt
Run Code Online (Sandbox Code Playgroud)

(大小为5个字节)当然可以预期,文本为3个字节,\ x0a\x0d为2个字节.

好的,我现在将编码设置为

:set enc=utf8
Run Code Online (Sandbox Code Playgroud)

缓冲区很奇怪

<e4><f6><fc>
Run Code Online (Sandbox Code Playgroud)

我想这是我之前输入的ascii字符的十六进制表示.所以我重写了它们

äöü
Run Code Online (Sandbox Code Playgroud)

写作,检查大小:

:w
:$ dir umlaute.txt
Run Code Online (Sandbox Code Playgroud)

这一次,它是8个字节.我想这对于每个字符加上\ x0d\x0a是有意义的2个字节.

好的,所以我想确保下次打开文件时它会用encodiung = utf8打开.

:setb
:w

:$ dir umlaute.txt
Run Code Online (Sandbox Code Playgroud)

11个字节.这当然是BOM(ef bb bf)的8(先前)字节+ 3字节.

所以我

:quit
Run Code Online (Sandbox Code Playgroud)

vim并再次打开文件

并检查,如果设置了编码:

:set enc
Run Code Online (Sandbox Code Playgroud)

但VIM坚持认为encoding=latin1.

那么,为什么呢.我原以为BOM会告诉VIM这是一个UTF8文件.

Ben*_*oit 16

你很困惑'encoding'这是一个Vim全局设置'fileencoding',它是每个缓冲区的本地设置.

打开文件时,变量'fileencodings'(注意最后的s)确定Vim将尝试打开文件的编码.如果以它开始,ucs-bom那么如果正确解析,任何带有BOM的文件都将正确打开.

如果要更改文件的编码,则应使用:set fenc=<foo>.如果要删除应使用的BOM :set [no]bomb.然后:w用来保存.

enc打开缓冲区后避免更改,可能会搞砸事情.enc确定vim可以使用哪些字符,它与您正在使用的文件无关.

细节

c:\> gvim umlaute.txt

您正在打开vim,文件名不存在.Vim创建一个缓冲区,为其指定名称,并设置fenc为空值,因为没有与之关联的文件.

:set enc

(VIM回应编码= latin1)

这意味着Vim将缓冲区内容存储在ISO-8859-1中(可能是另一个数字).

然后我检查文件编码...

:set fenc

(VIM回应fileencoding =)

这是正常的,暂时没有文件.

然后我写了文件

:w

由于'fileencoding'是空的,它将使用内部编码将其写入磁盘latin1.

并检查硬盘上文件的大小:

!dir umlaute.txt

(大小为5个字节)当然可以预期,文本为3个字节,\ x0a\x0d为2个字节.

好的,我现在将编码设置为

:set enc=utf8

错误!你告诉vim它必须将缓冲区内容解释为UTF8内容.缓冲区包含十六进制,e4 f6 fc 0a 0d前三个字节是无效的UTF8字符序列.你应该输入:set fenc=utf-8.这会转换缓冲区.

缓冲区很奇怪

当你强迫Vim将非法的UTF-8文件解释为UTF8时会发生这种情况.

我想这是我之前输入的ascii字符的十六进制表示.所以我重写了它们

AOU

写作,检查大小:

:w :$ dir umlaute.txt

这一次,它是8个字节.我想这对于每个字符加上\ x0d\x0a是有意义的2个字节.

好的,所以我想确保下次打开文件时它会用encodiung = utf8打开.

:set bomb :w

:$ dir umlaute.txt

11个字节.这当然是BOM(ef bb bf)的8(先前)字节+ 3字节.

所以我

:quit

vim并再次打开文件

并检查,如果设置了编码:

:设置enc

但是VIM坚持认为它的编码= latin1.

您应该运行set fenc?以了解检测到的文件编码是什么.如果你希望Vim能够使用Unicode文件,你应该在你的vimrc中设置'enc'utf-8.