Emacs 缓冲区和字符串支持来自众多不同书写体系的大量字符, 允许用户输入和显示几乎所有已知书面语言的文本。
为支持如此丰富的字符与书写体系,Emacs 严格遵循 Unicode 标准。
Unicode 标准为每个字符分配一个唯一编号,称为 码点(codepoint)。
Unicode 定义的码点范围(即 Unicode 编码空间(codespace))为
0..#x10FFFF(十六进制表示),包含两端点。
Emacs 将该范围扩展至 #x110000..#x3FFFFF,
用于表示未与 Unicode 统一的字符,以及无法解释为字符的 原始 8 位字节。
因此,Emacs 中的字符码点是一个 22 位整数。
为节省内存,Emacs 在缓冲区和字符串中并不以固定长度的 22 位数字 存储文本字符的码点。相反,Emacs 采用变长的内部字符表示方式, 根据字符码点的大小,将每个字符存储为 1 到 5 个 8 位字节的序列25。 例如,任意 ASCII 字符仅占用 1 字节,Latin-1 字符占用 2 字节,依此类推。 我们将这种文本表示方式称为 多字节(multibyte) 表示。
在 Emacs 外部,字符可以使用多种不同编码表示, 例如 ISO-8859-1、GB-2312、Big-5 等。 Emacs 在将文本读入缓冲区或字符串,或将文本写入磁盘文件 或传递给其他进程时,会根据需要在这些外部编码与内部表示之间进行转换。
有时,Emacs 需要在缓冲区或字符串中保存和处理已编码的文本 或二进制非文本数据。例如,Emacs 访问文件时, 会先将文件文本原样读入缓冲区,之后再转换为内部表示。 转换之前,缓冲区中保存的是编码后的文本。
在 Emacs 看来,已编码文本并非真正意义上的文本,
而是原始 8 位字节序列。我们将保存编码文本的缓冲区和字符串
称为 单字节(unibyte) 缓冲区和字符串,因为 Emacs 将它们视为单个字节的序列。
通常,Emacs 会以八进制码(如 \237)显示单字节缓冲区和字符串。
我们建议你仅在处理编码文本或二进制非文本数据时使用单字节缓冲区和字符串。
在缓冲区中,缓冲区局部变量 enable-multibyte-characters
指定所使用的表示方式。字符串的表示方式在字符串创建时确定并记录其中。
该变量指定当前缓冲区的文本表示方式。
若为非 nil,缓冲区包含多字节文本;
否则包含单字节编码文本或二进制非文本数据。
你不能直接设置该变量;应使用函数 set-buffer-multibyte
更改缓冲区的表示方式。
缓冲区位置以字符为单位计量。
该函数返回当前缓冲区中对应于位置 position 的字节位置。
缓冲区起始处为 1,并按字节递增计数。
若 position 超出范围,返回值为 nil。
返回当前缓冲区中对应于给定 byte-position 的
以字符为单位的缓冲区位置。
若 byte-position 超出范围,返回值为 nil。
在多字节缓冲区中,任意 byte-position 可能不位于字符边界,
而处于表示单个字符的多字节序列内部;
此时该函数返回包含该字节位置的字符所在的缓冲区位置。
换言之,属于同一字符的所有字节位置对应的返回值相同。
当 Lisp 程序需要将缓冲区位置映射到其所访问文件中的字节偏移时, 以下两个函数十分有用。
该函数与 position-bytes 类似,
但返回的不是当前缓冲区中的字节位置,
而是缓冲区中给定字符位置 position
对应于当前缓冲区所属文件起始处的字节偏移量。
转换需要知道文本在缓冲区文件中的编码方式,
这由 coding-system 参数指定,默认值为 buffer-file-coding-system。
可选参数 quality 指定结果的精度,可取以下值之一:
exact结果必须精确。函数可能需要对缓冲区的大部分内容进行编码和解码, 开销较大且速度可能较慢。
approximate结果可以是近似值。函数可避免高开销处理并返回不精确结果。
nil若精确结果需要高开销处理,函数将返回 nil 而非近似值。
省略该参数时默认为此值。
该函数返回对应于文件位置 byte(从文件起始处开始的 0 基字节偏移)
的缓冲区位置。该函数执行与 bufferpos-to-filepos 相反的转换。
可选参数 quality 和 coding-system
的含义与取值同 bufferpos-to-filepos。
若 string 为多字节字符串则返回 t,否则返回 nil。
若 string 不是字符串对象,该函数同样返回 nil。
该函数返回 string 中的字节数。
若 string 为多字节字符串,该值可能大于 (length string)。
该函数将所有参数 bytes 拼接, 并将结果构造为单字节字符串。
该内部表示基于 Unicode 标准定义的一种名为 UTF-8 的编码, 可表示任意 Unicode 码点,但 Emacs 对 UTF-8 进行了扩展, 以表示其用于原始 8 位字节和非 Unicode 统一字符的额外码点。