Vim 编码问题详解

Vim 编码问题详解

vim 中有 4 个与编码相关的配置,分别是 encodingtermencodingfileencodingfileencodings。在实际使用中任何一个配置有问题都可能会导致乱码,因此我们应该清楚每个配置的含义。

1. encoding

encoding 是 vim 内部使用的字符编码格式。vim 内部所有的 buffer寄存器脚本中的字符串等,都使用的是该配置的编码格式。如果文件的编码格式与内部编码格式不一致,则会先转为内部的编码格式,如果无法转换,则无法转换的字符会丢失。因此在设置内部编码时应该选择一种表现力足够的编码,即编码范围大的格式,比如 UTF-8。

由于 encoding 配置涉及 vim 中所有的字符的内部编码方式,因此,只能在 vim 启动的时候进行设置。如果没有特殊需求,请始终将 encoding 设置为 UTF-8

为了避免在非 UTF-8 的系统下(比如 Windows)菜单和系统提示出现乱码,可以进行如下配置:

set encoding=utf-8
set langmenu=zh_CN.UTF-8
language message zh_CN.UTF-8

2. termencoding

termencoding 是 Vim 用于屏幕时的编码格式,在显示的时候,vim 会把内部编码(encoding)转换为屏幕编码格式,然后再输出到屏幕。如果内部编码中含有无法转换为屏幕编码的字符,那么该字符就会变成问号,但是不会影响编辑操作。

比如,当在 Windows 中使用模拟终端远程连接服务器时,由于 Windows 中的模拟终端编码设置为 GBK 格式,而 Linux 中使用 UTF-8 编码,那么终端中的字符就会乱码,此时有两种方式可以解决此类乱码问题:

  1. 把 vim 的 encoding 改为 GBK,此时其内部的编码格式(buffer 中的编码格式)与终端的格式就一致了。
  2. 更改 termencoding 编码格式为 GBK,让 vim 将 buffer 中的字符在显示的时候转换为 GBK 编码,这样终端就可以正常显示了。

对于第一种解决方式,如果遇到编辑的文件中含有 GBK 无法表示的字符时,这些字符就会丢失。使用第二种方式的时候,虽然无法正常显示,但是仍然可以正常编辑(不会影响 buffer 中的内容)。故推荐使用第二种方式

对于图形界面的下的 Gvim,它的显示不依赖于终端,因此 termencoding 配置无意义。在 GTK2 下的 Gvim 中,termencoding 始终是 utf-8,不能修改。Windows 下的 Gvim 则忽略 termencoding 的配置。

3. fileencoding

当 Vim 从磁盘中读取文件时,会对文件编码格式进行检测,如果文件的编码方式和内部编码方式(encoding)不同,就会将其转换为内部编码格式。转换完毕后,Vim 会将 fileencoding 设置为文件的编码(检测过程中识别出的编码)。
当 vim 对文件进行保存时,如果 encoding(内部使用的编码) 和 fileencoding(文件编码) 不一致,就会进行编码转换,将 buffer 中的数据由 encoding 格式转换成 fileencoding 格式(即原本的文件格式)。

因此,我们可以通过打开文件后重新设置 fileencoding 来进行文件格式的转换,但是这有一个前提:就是 vim 可以正确识别出文件的编码格式,如果格式识别错误是无法通过更改 fileencoding 来进行转换的。

4. fileencodings

上面提到的文件编码检测是通过设置 fileencodings 实现的(注意是复数)。fileencodings 是一个逗号分割的列表,列表中的元素为编码格式名称。
当我们使用 vim 打开文件时,vim 会按顺序使用 fileencodings 中指定的编码尝试解码,如果成功,则使用该编码格式进行转码(由文件编码格式转换为内部编码格式 encoding),并设置 fileencoding 为该编码格式,如果失败就使用下一种方式尝试解码。

因此,我们在设置 fileencodings 的时候,一定要将编码严格的、解码不正确更容易失败的格式放在列表的前面,将宽松的,包容性好的格式放在后面。

例如,Latin1 是一种非常宽松的编码方式,任何一种编码方式的文本都可以使用它进行解码,不会解码失败,但是,会出现乱码(注意:解码失败 != 乱码)。因此,如果把 latin1 放到了列表的第一个,那么打开文件自动识别的 fileencoding 都是 latin1,都有可能出现乱码的情况。

以下推荐配置:

set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,euc-kr,latin1

如果 vim 自动检测的编码格式不正确,但是我们知道正确的编码格式,可以使用 ++enc=encoding_type 来打开文件::e ++enc=utf-8 filename

下面是对该配置的说明:

ucs-bom 是一种非常严格的编码,非该编码的文件几乎没有可能被误判为 ucs-bom,因此放在第一位。

utf-8 也相当严格,除了很短的文件外(例如许多人津津乐道的 GBK 编码的“联通”被误判为 UTF-8 编码的经典错误),现实生活中一般文件是几乎不可能被误判的,因此放在第二位。

接下来是 cp936 和 gb18030,这两种编码相对宽松,如果放前面的话,会出现大量误判,所以就让它们靠后一些。cp936 的编码空间比 gb18030 小,所以把 cp936 放在 gb18030 前面。

至于 big5、euc-jp 和 euc-kr,它们的严格程度和 cp936 差不多,把它们放在后面,在编辑这些编码的文件的时候必然出现大量误判,但这是 Vim 内置编码探测机制没有办法解决的事。由于中国用户很少有机会编辑这些编码的文件,因此还是要把 cp936 和 gb18030 提前以保证这些编码的识别。

最后是 latin1,它是一种极其宽松的编码,以至于我们不得不把它放在最后一位。不过可惜的是,当你碰到一个真的 latin1 编码的文件时,绝大部分情况下,它没有机会 fall-back 到 latin1,往往在前面的编码中就被误判了。不过,正如前面所说的,中国用户没有太多机会接触这样的文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/557369.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

@Autowired作用在普通方法上

Autowired作用在普通方法上 Autowired作用在普通方法上,会在注入的时候调用一次该方法,如果方法中有实体参数,会对方法里面的参数进行装配,并调用一次该方法。这个可以用来在自动注入的时候做一些初始化操作。

@Autowired注解作用在方法上

Autowired注解作用在方法上 Autowired注解作用在方法上 (1)该方法如果有参数,会使用autowired的方式在容器中查找是否有该参数 (2)会执行该方法

spring定时任务的几种实现方式

spring定时任务的几种实现方式 一.分类 从实现的技术上来分类,目前主要有三种技术(或者说有三种产品): Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让…

Spring定时任务

Spring定时任务(一):SpringTask使用 背景:在日常开发中,经常会用到任务调度这类程序。实现方法常用的有:A. 通过java.util.Timer、TimerTask实现。 B.通过Spring自带的SpringTask。 C. 通过Spring结合Quartz实现。本文我们将讲述…

关于Spring 任务调度之task:scheduler与task:executor配置的详解

关于Spring 任务调度之task:scheduler与task:executor配置的详解 其实就是Spring定时器中配置文件中一些配置信息,由于笔者自己是头一次使用,有些配置详细不太明白,随即研究了一番,于是想记录一下,有需要的小伙伴可以…

Spring的任务调度@Scheduled注解——task:scheduler和task:executor的解析

Spring的任务调度Scheduled注解——task:scheduler和task:executor的解析 applicationContext 的配置如下: <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:context"…

CAP 理论、BASE 理论、FLP 理论

CAP 理论、BASE 理论、FLP 理论 CAP 理论、BASE 理论、FLP 理论 1.CAP 理论 C(Consistency) 一致性: 在写操作之后的所有读操作&#xff0c;必须要返回写入的值。 A(Availability) 可用性&#xff1a; 只要收到用户的请求&#xff0c;服务端就必须给出回应。 P(Partitio…

Spring的@Scheduled注解实现定时任务

Spring的Scheduled注解实现定时任务 【简介篇】 项目经常会用到定时任务&#xff0c;实现定时任务的方式有很多种。在Spring框架中&#xff0c;实现定时任务很简单&#xff0c;常用的实现方式是使用注解Scheduled。 Scheduled 常用来实现简单的定时任务。例如凌晨1点跑批&am…

接口测试如何测

接口测试如何测 一.什么是接口&#xff1f; 接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点&#xff0c;定义特定的交互点&#xff0c;然后通过这些交互点来&#xff0c;通过一些特殊的规则也就是协议&#xff0c;来进行数据之间的交互。 二.接口都有哪…

CommandLineRunner 和 ApplicationRunner 的区别

CommandLineRunner 和 ApplicationRunner 概述 CommandLineRunner 和 ApplicationRunner 的作用类似, 都可以在 Spring 容器初始化之后执行某些操作。比较适用于某些复杂的 Bean 加载完成之后执行一些操作。例如 Feign 调用。 相同点 都可以获取到启动时指定的外部参数。主逻…

深入学习二叉树(一) 二叉树基础

深入学习二叉树(一) 二叉树基础 前言 树是数据结构中的重中之重&#xff0c;尤其以各类二叉树为学习的难点。一直以来&#xff0c;对于树的掌握都是模棱两可的状态&#xff0c;现在希望通过写一个关于二叉树的专题系列。在学习与总结的同时更加深入的了解掌握二叉树。本系列文…

ApplicationContext 和 BeanFactory 的区别

概述 首先解释一下两个名词: BeanFactory 是 Bean 工厂。ApplicationContext 是应用上下文。 ApplicationContext 和 BeanFactory 都是装载 Bean 的容器, 且 ApplicationContext 继承自 BeanFactory。但 ApplicationContext 较 BeanFactory 来说更高级一点。 主要区别: 是否…

深入学习二叉树(二) 线索二叉树

深入学习二叉树(二) 线索二叉树 1 前言 在上一篇简单二叉树的学习中&#xff0c;初步介绍了二叉树的一些基础知识&#xff0c;本篇文章将重点介绍二叉树的一种变形——线索二叉树。 2 线索二叉树 2.1 产生背景 现有一棵结点数目为n的二叉树&#xff0c;采用二叉链表的形式…

Java 逃逸分析

定义 分析对象动态作用域, 看别的方法或线程是否有途径能访问到这个对象。所谓逃逸分析,就是分析对象动态作用域,看别的方法或线程是否有途径能访问到这个对象,如果不能,那么编译器就可以为这个变量提供更高效的优化。 当一个对象, 能被其他方法访问到时, 这种逃逸叫做方法逃…

Java 线程调度

什么是线程调度 线程调度是指 OS 为线程分配处理器使用权的过程, 主要的调度方式有两种: 协同式线程调度。抢占式线程调度。 协同式线程调度 线程的执行时间由线程本身来控制, 线程把自己的工作执行完了之后,要主动通知 OS 切换到另一个线程上,即相当于在线程执行时间内能保…

深入学习二叉树(三) 霍夫曼树

深入学习二叉树(三) 霍夫曼树 1 前言 霍夫曼树是二叉树的一种特殊形式&#xff0c;又称为最优二叉树&#xff0c;其主要作用在于数据压缩和编码长度的优化。 2 重要概念 2.1 路径和路径长度 在一棵树中&#xff0c;从一个结点往下可以达到的孩子或孙子结点之间的通路&…

深入学习二叉树(四) 二叉排序树

深入学习二叉树(四) 二叉排序树 1 前言 数据结构中&#xff0c;线性表分为无序线性表和有序线性表。 无序线性表的数据是杂乱无序的&#xff0c;所以在插入和删除时&#xff0c;没有什么必须遵守的规则&#xff0c;可以插入在数据尾部或者删除在数据尾部。但是在查找的时候&a…

MySQL MVCC 概述

文章目录MVCC(Muti Version Concurrency Control) 的概念什么是当前读和快照读背景总结undo 日志InnoDB 中的 MVCCInnoDB 中的 MVCC 与事务隔离级别的关系InnoDB 中的 MVCC 实现原理MVCC(Muti Version Concurrency Control) 的概念 MVCC, 是一种多版本并发控制机制。通过 MVCC…

MySQL 行级锁

MySQL 行级锁的分类 按照锁定的范围不同,行级锁分为: 记录锁:用于锁定指定的某行记录间隙锁:用于锁定指定区间的记录,只有可重复读级别下才有间隙锁,间隙锁不存在冲突, 但是有可能导致死锁。临键锁:用于锁定指定左开右闭区间的记录,是记录锁与间隙锁的结合。

Redis Scan 命令

文章目录1. Scan 命令的基本用法1.1 Scan 命令的输入值1.2 Scan 命令的返回值2. Scan 命令与 Keys 命令比较2.1 Keys 命令的缺点2.2 Scan 命令的优点3. Scan 命令的限制3.1 有限保证原则3.2 返回的结果有可能会重复1. Scan 命令的基本用法 Scan 命令是一个基于游标的迭代器:Sc…