![为什么 Compose 键的行为在纯控制台和 X 下不同?](https://linux22.com/image/186919/%E4%B8%BA%E4%BB%80%E4%B9%88%20Compose%20%E9%94%AE%E7%9A%84%E8%A1%8C%E4%B8%BA%E5%9C%A8%E7%BA%AF%E6%8E%A7%E5%88%B6%E5%8F%B0%E5%92%8C%20X%20%E4%B8%8B%E4%B8%8D%E5%90%8C%EF%BC%9F.png)
我正在 Xubuntu 20.04 中设置键盘布局。
我通常希望能够使用相同的击键在纯控制台和 X 中输入各种 Unicode 字符。我知道控制台对 Unicode(512 个字形)的支持有限,所以我同意控制台仅在这个有限范围内工作。
我在 xfce4-keyboard-settings 中保持“使用系统默认值”处于打开状态,将此选项理解为“使用设置/etc/default/keyboard
”,并希望为纯控制台和 X 提供单一配置。
我已经运行sudo dpkg-reconfigure keyboard-configuration
并选择了“美国国际,带 AltGr 死键”布局变体。
我发现,在纯控制台 bash 中,进入“(arg: x)”模式会弄乱一些 AltGr 序列,在谷歌上搜索到与某些 readline 特性相关,并且暂时认为这是偏离主题的,通过以下方式排除了这种行为sh
从 bash开始最简单的。
此时,我很高兴键盘布局在控制台和 X: AltGr+2 类型下的工作方式似乎相同², AltGr+` 然后 e 输入è。
对于撰写键,我选择了 Caps Lock。
在 X 下,行为是预期的:在度数符号中编写 oo 类型,在欧元符号中编写 e = 类型,等等。
但在控制台中,几乎没有任何 Compose 序列可以工作。没有学位,没有欧元(虽然它们可以完美显示,甚至可以通过 AltGr 输入)。 Compose 键并非完全无用,因为它仍然适用于最基本的组合,例如 Compose ` e 组合è。但这比 512 个字形还要有限。
那么为什么控制台 Compose 的行为如此不同,它是否可以调整为至少支持看似简单的东西,例如度数和欧元?
答案1
控制台行为不同,因为它是由完全不同的代码处理的。/etc/default/keyboard
包含以下设置XKB,它是 X 处理键盘输入的一部分。这控制台安装包通过程序将这些设置转换为控制台能够执行的操作setupcon
(读取并解析/etc/default/keyboard
)和ckbcomp
(它将 XKB 设置转换为控制台设置)。这些工具受限于控制台的功能。
Linux 控制台在内核内部实现,仅对多字节字符集提供非常部分的支持。特别是对于 compose 键,内核中有一个硬编码限制:组成表 ( accent_table
)其硬编码大小为MAX_DIACR
除非您重新编译内核,否则它是 256。这可以解释为什么控制台设置包没有 Unicode 撰写表:只有 256 个条目,无论你做什么,都不会覆盖很多字符。据我所知,当您使用带有 Unicode 字符集的控制台设置时,您最终会得到内核的内置撰写表which 仅列出 latin1 非 ASCII 重音字母(而不列出标点符号,例如 °)。
您可以定义自己的撰写表。选取两个字符的最多 256 种组合来组合成第三个字符,并将它们列在控制台撰写映射文件中。
Compose 'o' 'o' to degree
Compose 0x6f 0x006f to 0xb0
Compose U+6F U+006f to U+00B0
上面的第一行说明了表示Compose o oinsert 的不同方式°
。当然你只需要一个。指定字符的方法有:
- 十进制数、带前导的八进制数
0
或带前导的十六进制数0x
。 - A单字节里面的人物
'
。该字符之前可以有一个反斜杠,反斜杠和单引号必须有反斜杠:'\o'
相当于'o'
,但反斜杠和单引号只能分别写成'\\'
and'\'
(或使用其他语法)。 '\ooo'
在哪里哦哦正好是 3 个八进制数字,指定的值最多为 255 (\377
)。U+hhhh
在哪里呵呵正好是 4 个十六进制数字。- 仅在右侧
to
,是字符的象征性名称。符号名称是 X11 键符号名称的子集。请参阅来源 (syms.*.h
)获取符号名称列表。
要加载您自己的撰写地图,请运行
loadkeys /path/to/my/compose.kmap
这将替换当前加载的组合表。
我找不到一种方法来告诉控制台设置加载自定义撰写地图。对于非 Unicode 编码,ckbcomp
它会加载,但对于 Unicode,它会跳过该步骤。/etc/console-setup/compose.${charmap}.inc
1数组中元素的个数kbdiacruc
struct kbdiacrsuc
是用户态可以设置的最大项目数。它可能需要设置为相同的值。
² Source:源代码(kbd
包、文件src/libkeymap/analyze.l
)src/libkeymap/parser.y
。我在文档中找不到这些详细信息。