VIM如何执行字符集转换?

时间:2019-02-07 10:19:04

标签: vim

我在vim文档中看到以下段落,介绍了字符集转换:

Vim will automatically convert from one to another encoding in several places:
- When reading a file and 'fileencoding' is different from 'encoding'
- When writing a file and 'fileencoding' is different from 'encoding'
- When displaying characters and 'termencoding' is different from 'encoding'
- When reading input and 'termencoding' is different from 'encoding'
- When displaying messages and the encoding used for LC_MESSAGES differs from
  'encoding' (requires a gettext version that supports this).
- When reading a Vim script where |:scriptencoding| is different from
  'encoding'.
- When reading or writing a |viminfo| file.

我想知道谁在向谁转换?例如:

"When reading a file and 'fileencoding' is different from 'encoding'"

“文件编码”是否已转换为“编码”?还是将“编码”转换为“文件编码”?

文件的实际字符集与文件编码和编码之间是什么关系?

如果文件的实际字符集和fileencoding的值不相等,上述转换操作是否会破坏文件的内容?

更新:

例如:encoding的值为:utf-8,vim打开一个文件:foo,并且基于fileencodings匹配一个fileencoding值:sjis(假设我不知道该文件的实际编码。),我编辑foo,并使用“:wq”保存并关闭vim窗口。如果再次打开foo文件,该文件的实际编码是文件编码指定的sjis还是上次编辑时编码指定的utf-8?

1 个答案:

答案 0 :(得分:1)

'encoding'是Vim内部任何缓冲区文本的内部表示形式。这就是Vim正在进行的工作。当您处理不同的字符集时(或者如果您不在意并在现代操作系统上工作),强烈建议将其设置为utf-8,因为Unicode编码可确保 any < / em>字符可以表示,并且不会丢失任何信息。 (而且UTF-8是Vim内部支持的唯一Unicode表示形式;即,您不能使其使用UTF-16之类的双字节编码。)

在Vim中打开文件时,将考虑'fileencodings'(注意复数!)中可能的编码列表:

  

这是开始编辑时考虑的字符编码列表   现有文件。读取文件时,Vim尝试使用第一个文件。   提到的字符编码。如果检测到错误,则下一个   在列表中尝试。找到有效的编码后,   设置为“ fileencoding”。

因此,如果文件看起来不正确,则可以进行调整;或者,您可以通过++enc参数来显式覆盖检测,例如

:edit ++enc=sjis japanese.txt

现在,Vim具有文件的源编码(以(单个!)'fileencoding'保留;将其写回原始编码时需要此编码),并将字符集(如果不同)转换为内部{ {1}}。所有的Vim命令都以此为基础进行操作,并且在'encoding'上,转换是反向进行的(或可选地由:write覆盖)。

结论

  • 只要检测到的/传递的编码正确,就假设内部:w ++enc=...能够表示所有读取的字符(由'encoding'保证),没有数据丢失。
  • 同样,由于原始编码存储在utf-8中,因此文件的写入将透明地转换回去。现在,可能已经发生了编辑引入了无法在文件编码中表示的字符的情况(但是由于Vim的内部Unicode编码,您可以对其进行编辑)。然后,Vim将在书写时打印'fileencoding',您必须手动更改字符,或选择其他目标文件编码。

示例

具有这些汉字字符E513: write error, conversion failed的文件以SJIS编码表示如下:

日本

每个汉字存储在两个字节中,然后在末尾有一个字节的换行符(LF)。

93fa 967b 0a 中,内部表示为(g8可以告诉您):

:set encoding=utf-8

在UTF-8中,每个汉字存储在三个字节中,第一个汉字为e697 a5e6 9cac 0a

现在,如果我编辑文本,例如加上(ASCII)括号和e6 97 a5,我得到了:

:write

恢复了原始的SJIS编码,每个汉字又是两个字节,现在在其周围加上了括号2893 fa96 7b29 0a 28

如果我尝试用29字符进行编辑,则ä会因:write错误而失败,因为该字符无法用SJIS表示。