一致的键盘配置

作者:John F. Bunch

Linux 的一个便利功能是键盘可以完全重新配置以适应个人喜好。当按键在所有应用程序中执行的操作不一致时,此功能可能既是福音也是诅咒,但稍加努力,您就可以对任何按键进行编程以执行几乎任何任务。可以消除不一致的键盘行为,并且可以根据需要自定义应用程序。

在本文中,您将学习如何为 BACKSPACEDELETEALT 键实现一致的行为。Caps Lock 键与左 CTRL 键互换,以使控制字符的输入更容易。编辑小键盘的按键被配置为按标签执行操作。功能键和数字小键盘上的某些按键被编程为执行任意任务。还配置了一个关机键。

键盘配置技术将通过各种示例逐个程序地进行演示。在可行的情况下,这些技术将针对 bash、less、Netscape、minicom 和 Emacs 进行演示。此外,无论应用程序是在 xterm 窗口、虚拟控制台还是 X11 窗口管理器中运行,键盘都将按预期工作。但是,假设用户使用的是 IBM PC 兼容键盘。

定义

IBM PC 兼容键盘分为五个按键块。字母键和它们周围的按键构成主键盘。主键盘的右侧紧邻着两组小按键。上面的六个按键是编辑键;下面的四个按键是箭头键,也称为光标控制键。最右边是数字小键盘。最后,功能键以单行横跨键盘顶部。

当按下功能键或箭头键时,按键通常会传输一个转义序列。转义序列是由几个字符组成的字符串,第一个字符是 ESCAPE 控制码。字符串的其余部分用于区分不同的按键。

VT100 系列是由数字设备公司 (Digital Equipment Corporation) 曾经制造的一系列纯文本显示终端。VT100 已成为 ASCII 终端的事实标准。它的后继产品 VT200 与 VT100 系列兼容。但是,VT200 也有一排二十个功能键和六个 VT100 没有的编辑键。VT200 键盘在某种程度上类似于现在常用的 IBM PC 风格键盘。

按键事件

当用户按下键盘上的任何按键时,就会发生按键事件。事件会通过各种软件程序,最终产生某种操作(参见图 1)。理想情况下,相同的按键操作会在所有程序中产生类似的操作,从而减少用户的困惑。

例如,假设用户在 X Window 系统下的 xterm 中运行 Emacs,并按下向上箭头键。再次参考图 1,按下向上箭头,导致生成事件键码 98,该键码唯一标识该按键。X Window 系统将此键码转换为 “Up” 键符,xterm 接收到该键符。然后,xterm 将 “Up” 键符转换为三字符转义序列 “\\eOA”(“\\e” 代表 ASCII ESCAPE 控制码)。Emacs 接收 “\\eOA” 作为一系列三个输入事件,然后由 function-key-map 将其转换为向量 [up]。向量 [up] 通过 key-translation-map 时保持不变。最后,global-map 将 [up] 映射到 previous-line 命令,该命令将光标在缓冲区中向上移动一行。

图 1. 按键事件流程图

BACKSPACEDELETEALT

配置 BACKSPACEDELETE 键的一种方法是让它们像在 DOS 和 MS Windows 中一样工作。也就是说,BACKSPACE 删除光标左侧的字符,而 DELETE 删除光标下的字符。这是一个非常方便的安排。

决定按下这些按键时应传输哪些控制码也是一个好主意。根据按键标签,让 BACKSPACE 键传输一个 BACKSPACE(ASCII 码 8,八进制 010,十六进制 0x08,CTRL-H),让 DELETE 键传输一个 DELETE(ASCII 码 127,八进制 177,十六进制 7F)。简单的解决方案通常是最好的。

ALT 键的作用有点像 Shift 键,可以通过两种方式配置。它可以设置与其一起按下的按键的第八位,也可以在与其一起按下的按键之前发送一个 ESCAPE。这两种方法将在不同的时间使用。有时,将 ALT 键配置为传输 ESCAPE 更简单。例如,按住 ALT 的同时按下 A 将导致传输字符串 “\\eA”。但是,在其他时候,它将被配置为设置所按下字符的第八位,从而将 128 添加到该字符的 ASCII 码中。Meta 是 ALT 的同义词。

Linux 内核

首先,将重新定义内核的键盘转换表。由于 X Window 系统不直接使用这些表,因此请使用虚拟控制台之一,而不是窗口管理器。以 root 用户身份登录或使用 su。Linux 的不同发行版可能会以不同的方式加载转换表。要确定正在使用哪个键盘转换表,请键入

# find /etc -type f | xargs grep loadkeys

您应该看到类似以下的输出

/etc/init.d/boot:  loadkeys \
        /usr/lib/kbd/keytables/us.map
这将表明正在使用美国转换表。

假设正在使用美国转换表,请输入以下命令来复制它

# cd /usr/lib/kbd/keytables
# cp us.map custom.map

键盘表文件的格式在 keytables(5) 中给出。

现在使用任何文本编辑器编辑 custom.map。找到以下行

keycode 14 = Delete           Delete
        alt     keycode  14 = Meta_Delete

这些行指定当按下 键号 14(BACKSPACE 键)时,向系统发送一个 DELETE,当按下 ALT-BACKSPACE 时,发送一个 Meta_DELETE。要查找任何按键的键号,请使用 showkey 命令。

为了使 BACKSPACE 键符合设计决策,请将这些行更改为读取

keycode  14 = BackSpace        BackSpace
         alt     keycode  14 = Meta_BackSpace

但是,还需要一个 delete 键,因此请替换以下行

keycode 111 = Remove
替换为以下两行
keycode 111 = Delete           Delete
        alt             keycode 111 = Meta_Delete
键号 111 是编辑小键盘上的 DELETE 键,就在 INSERT 键下方。

现在,要将 Caps_Lock 与左 CTRL 键交换,请按如下方式重新定义键码 29 和 58

keycode  29 = Caps_Lock    # Left Control key.
keycode  58 = Control      # Caps Lock key.

配置数字小键盘提出了一个特殊的挑战。在 us.map 中,几个按键传输的转义序列与编辑键相同。例如,这使得程序无法区分编辑小键盘上的 PAGE UP 键和数字小键盘上的 9/Pg Up 键。此外,NUM LOCK、/、*、- 和 + 键甚至不传输转义序列。

为了缓解这些问题,虚拟控制台的数字小键盘将被配置得有点像 VT100 数字小键盘。由于 xterm 已经模拟了 VT102,这将通过使虚拟控制台与 xterm 更兼容来节省工作。请注意,此技术可能会导致与期望按键按照 us.map 定义的方式工作的软件程序不兼容。如果这成为问题,可以随时将按键切换回去。

为了能够独立配置数字小键盘的按键,必须将它们更改为功能键。由于内核最多支持 246 个功能键,F1 到 F246,这不是问题。按如下所示重新定义以下键码

keycode  55 = F112    # Numeric keypad *.
keycode  69 = F110    # NumLock.
keycode  71 = F107    # Numeric keypad 7.
keycode  72 = F108    # Numeric keypad 8.
keycode  73 = F109    # Numeric keypad 9.
keycode  74 = F113    # Numeric keypad -.
keycode  75 = F104    # Numeric keypad 4.
keycode  76 = F105    # Numeric keypad 5.
keycode  77 = F106    # Numeric keypad 6.
keycode  78 = F114    # Numeric keypad +.
keycode  79 = F101    # Numeric keypad 1.
keycode  80 = F102    # Numeric keypad 2.
keycode  81 = F103    # Numeric keypad 3.
keycode  82 = F100    # Numeric keypad 0.
keycode  83 = F116    # Numeric keypad ..
keycode  96 = F115    # Numeric keypad Enter.
keycode  98 = F111    # Numeric keypad /.

此外,有必要定义这些按键传输的转义序列,因此将这些行添加到文件末尾

string F100 = "\\033Op"
string F101 = "\\033Oq"
string F102 = "\\033Or"
string F103 = "\\033Os"
string F104 = "\\033Ot"
string F105 = "\\033Ou"
string F106 = "\\033Ov"
string F107 = "\\033Ow"
string F108 = "\\033Ox"
string F109 = "\\033Oy"
string F110 = "\\033OP"
string F111 = "\\033Oo"
string F112 = "\\033Oj"
string F113 = "\\033Om"
string F114 = "\\033Ok"
string F115 = "\\033OM"
string F116 = "\\033On"
"\\033"ESCAPE 的八进制表示形式。这些是当运行 xterm 时,在执行剩余步骤后,这些按键将传输的相同转义序列。

尽管功能键 F6 到 F12 与 xterm 兼容,但 F1 到 F5 不兼容。要修复此问题,请添加以下行

string F1 = "\\033[11~"
string F2 = "\\033[12~"
string F3 = "\\033[13~"
string F4 = "\\033[14~"
string F5 = "\\033[15~"

建议定义以下键码,以便键符(等号后面的名称)与键帽匹配。但是,这不会更改传输的转义序列,因为这些键符只是原始键符的同义词

keycode 102 = Home      # Was Find.
keycode 104 = PageUp    # Was Prior.
keycode 107 = Enc       # Was Select.
keycode 109 = PageDown  # Was Next.
一个非常好的功能是能够在 Emacs 中使用箭头键平移时按住 ALT 键。由于 ALT-左箭头和 ALT-右箭头以前用于切换虚拟控制台,因此这些功能将被重新映射到 CTRL-左箭头和 CTRL-右箭头。

按所示更改以下两行

# Ctrl-Left (was Alt)
control keycode 105 = Decr_Console
# Ctrl-Right (was Alt)
control keycode 106 = Incr_Console

并添加以下行

alt     keycode 103 = F117   # Left Alt-Up Arrow
altgr   keycode 103 = F117   # Right Alt-Up Arrow
alt     keycode 105 = F120   # Left Alt-Left Arrow
altgr   keycode 105 = F120   # Right Alt-Left Arrow
alt     keycode 106 = F119   # Left Alt-Right Arrow
altgr   keycode 106 = F119   # Right Alt-Right Arrow
alt     keycode 108 = F118   # Left Alt-Down Arrow
altgr   keycode 108 = F118   # Right Alt-Down Arrow
string F117 = "\\033\\033[A"   # Alt-Up Arrow
string F118 = "\\033\\033[B"   # Alt-Down Arrow
string F119 = "\\033\\033[C"   # Alt-Right Arrow
string F120 = "\\033\\033[D"   # Alt-Left Arrow
请注意,ALT-箭头传输一个 ESCAPE,后跟箭头键的正常转义序列。

当然,CTRL-ALT-DELETE 将重启 Linux,但是如果用户一天的工作已经完成,想要快速关机怎么办?要使 CTRL-ALT-H-END 关闭 Linux,请添加以下行

# Numeric keypad End
control alt     keycode  79 = KeyboardSignal
control altgr   keycode  79 = KeyboardSignal
# Editing keypad End
control alt     keycode  107 = KeyboardSignal
control altgr   keycode  107 = KeyboardSignal

然后保存文件,并编辑 /etc/inittab。按所示添加或编辑以下行

# Action on special keypress (CTRL-ALT-END).
kb::kbrequest:/sbin/shutdown -h now
保存文件,一切都准备好进行测试。键入
# loadkeys custom.map
并尝试新按键。DELETE 的作用应该与之前的 BACKSPACE 相同。Caps Lock 已与左 CTRL 键交换。退出所有程序,然后尝试 CTRL-ALT-END。关机后,使用硬件复位按钮重启。

如果键盘通过了这些基本测试,则可以将 us.map 替换为 custom.map。普通用户在运行 loadkeys 时可能会遇到错误,因为它需要读取 /dev/console 的权限。此外,不同用户使用不同的映射可能会导致混乱。因此,建议由 root 用户在系统上永久安装新的键盘映射。

警告:如果未正确遵循这些安装说明,则可能会使键盘处于无法使用的状态,迫使用户从安装软盘重新启动。请在继续操作之前采取任何必要的预防措施。

要永久安装 custom.map,请编辑 /etc/init.d/boot,或包含 loadkeys 命令的任何启动脚本,并将以下行添加到文件顶部

custom_keys=/usr/lib/kbd/keytables/custom.map

然后将 loadkeys 命令替换为

if [ -f $custom_keys ]  # If custom keys exist,
then                            # then load them.
  loadkeys $custom_keys
else                            # Else use the regular keys.
  loadkeys /usr/lib/kbd/keytables/us.map
fi
这样,如果 custom.map 以某种方式被删除,键盘仍然可以工作。运行此脚本以确保它是正确的。如果它有效,则新的键盘映射将在下次系统启动时自动激活。
X Window 系统

现在以 root 用户身份启动 X。将目录更改为 /etc/X11 并查看文件 Xmodmap。最有可能的是,此文件是空的,除了一些注释。如果不是,请将其重命名为 Xmodmap.old,退出窗口管理器并重新启动 X。

从空的 Xmodmap 开始很重要,因为当 X 启动时,它会根据内核当前的键盘转换表创建其键盘修饰符映射和键映射表,而这些表刚刚被重新配置。然后 X 读取 Xmodmap 文件,该文件会覆盖内核。这可能会破坏刚刚完成的内核工作的一些好处。

由于内核已重新配置,因此配置 X 的工作量将因创建 custom.map 时已完成的工作而减少。具体来说,DELETEBACKSPACE 仍将传输 DELETEBACKSPACE,因为 X 从内核获得了该信息。

现在输入以下命令以将 Xmodmap 替换为当前的键映射表

# xmodmap -pke > /etc/X11/Xmodmap

编辑 Xmodmap。它看起来类似于文件 custom.map,但不要被误导。键码是不同的。要查找给定按键的键码编号,请从 xterm 运行 xev,将鼠标光标放在 xev 窗口内,然后按下该按键。在输出中查找按键的 “keycode”。有关更多信息,请参见 xev(1)xmodmap(1)

最后,要切换 Caps Lock 和左 CTRL 键,请将以下行添加到文件末尾

! Recreate the Lock and Control modifier maps.
clear Lock
clear Control
add Lock = Caps_Lock
add Control = Control_L Control_R

为了能够配置数字小键盘上的按键,必须在等号后为它们提供适当的 键符。因此,按所示更改以下行

keycode  63 = KP_Multiply
keycode  77 = KP_F1
keycode  79 = KP_7
keycode  80 = KP_8
keycode  81 = KP_9
keycode  82 = KP_Subtract
keycode  83 = KP_4
keycode  84 = KP_5
keycode  85 = KP_6
keycode  86 = KP_Add
keycode  87 = KP_1
keycode  88 = KP_2
keycode  89 = KP_3
keycode  90 = KP_0
keycode  91 = KP_Decimal
keycode 108 = KP_Enter
keycode 112 = KP_Divide
键码 99 和 105 分别分配给键符 Prior 和 Next。就像在 custom.map 中所做的那样,将它们更改为以下键符,它们在功能上是等效的,但与键帽匹配
keycode  99 = Page_Up
keycode 105 = Page_Down
现在保存文件,然后键入
# xmodmap /etc/X11/Xmodmap
以激活新定义。如果您的键盘完全无法工作,请使用 CTRL-ALT-BACKSPACE 退出 X。然后使用虚拟控制台来解决问题。
Xterm

xterm 程序从 X 接收键符,并将它们转换为字符和转义序列。由于 xterm 模拟 VT102 终端,因此只需要很少的配置工作。

编辑 /etc/X11/Xresources 文件,并添加以下行

XTerm*ttyModes: erase ^H

这会自动使 BACKSPACE (CTRL-H) 删除光标左侧的字符。这与用户键入

$ stty erase ^H
每次启动 xterm 时都一样。还要添加此行
XTerm*appkeypadDefault: true
这将使数字小键盘的按键传输其转义序列,而不是数字、运算符等。这与用户在每个 xterm 窗口中按下 CTRL--MiddleButton 并选择 “Enable Application Keypad” 相同。

不幸的是,Emacs 通常会在退出时重置数字小键盘,因此按键不再传输转义序列。要纠正此行为,必须从 terminfo(5) 数据库中删除 “rmkx” 功能

# cd /etc/terminfo/x
# infocmp xterm > xterm.txt
# emacs xterm.txt

删除 “rmkx” 条目,保存文件,然后退出。

# tic xterm.txt
# rm xterm.txt
还需要告诉 xterm ALT-箭头键传输什么,以及 HOMEEND 编辑键传输什么。(xterm 用于 HOMEEND 的默认转义序列非常规。)键入以下前七行。然后从 xterm(1) 手册页中,在标题 “The default bindings in the VT102 window are.” 下方剪切并粘贴剩余的行。
XTerm*VT100*translations:\\
Alt <KeyPress> Up:string(0x1b) string(0x1b) string("OA")
Alt <KeyPress> Down:string(0x1b) string(0x1b) string("OB") \\n\\
Alt <KeyPress> Right:string(0x1b) string(0x1b) string("OC") \\n\\
Alt <KeyPress> Left:string(0x1b) string(0x1b) string("OD") \\n\\
<KeyPress> Home:string(0x1b) string("[1~") \\n\\
<KeyPress> End:string(0x1b) string("[4~") \\n\\
Shift <KeyPress> \
        Prior:scroll-back(1,halfpage) \\n\\
Shift <KeyPress> \
        Next:scroll-forw(1,halfpage) \\n\\
Shift <KeyPress> \
        Select:select-cursor-start() \\n\\
Shift <KeyPress> select-cursor-end(PRIMARY, \
        CUT_BUFFER0) \\n\\
Shift <KeyPress> Insert:insert-selection(PRIMARY,\
        CUT_BUFFER0) \\n\\
~Meta<KeyPress>:insert-seven-bit() \\n\\
Meta<KeyPress>:insert-eight-bit() \\n\\
!Ctrl <Btn1Down>:popup-menu(mainMenu) \\n\\
!Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \\n\\
!Mod2 Ctrl <Btn1Down>:popup-menu(mainMenu) \\n\\
!Mod2 Lock Ctrl \
        <Btn1Down>:popup-menu(mainMenu) \\n\\
~Meta <Btn1Down>:select-start() \\n\\
~Meta <Btn1Motion>:select-extend() \\n\\
!Ctrl <Btn2Down>:popup-menu(vtMenu) \\n\\
!Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \\n\\
!Mod2 Ctrl <Btn2Down>:popup-menu(vtMenu) \\n\\
!Mod2 Lock Ctrl \
        <Btn2Down>:popup-menu(vtMenu) \\n\\
~Ctrl ~Meta <Btn2Down>:ignore() \\n\\
~Ctrl ~Meta <Btn2Up>:insert-selection(PRIMARY, CUT_BUFFER0) \\n\\
!Ctrl <Btn3Down>:popup-menu(fontMenu) \\n\\
!Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \\n\\
!Mod2 Ctrl <Btn3Down>:popup-menu(fontMenu) \\n\\
!Mod2 Lock Ctrl \
        <Btn3Down>:popup-menu(fontMenu) \\n\\
~Ctrl ~Meta <Btn3Down>:start-extend() \\n\\
~Meta <Btn3Motion>:select-extend() \\n\\
<BtnUp>>>>>>>>:select-end(PRIMARY, CUT_BUFFER0) \\n\\
<BtnDown>:bell(0)
确保每行都完全按照所示结尾,并且每行最后一个反斜杠后甚至没有空格。然后将 “Prior” 更改为 “Page_Up”,将 “Next” 更改为 “Page_Down”,并将 “Select” 更改为 “End” 以匹配键帽。

ALT-箭头传输一个 ESCAPE(十六进制 0x1b),后跟箭头键的转义序列,但 ALT-<KeyPress> 设置该按键的第八位(检查以 “Meta<KeyPress>” 开头的行)。此外,ALT-箭头键的转义序列与 custom.map 中使用的序列不同。有关此文件格式的完整说明,请参见 X(1) 下的 RESOURCES 标题。保存文件。键入

# xrdb /etc/X11/Xresources

以激活定义。下次启动 xterm 时,BACKSPACE 键现在应该可以正常工作。

Bash

创建一个新文件,/etc/inputrc 用于系统范围,或 ~/.inputrc 用于个人用途。这将是一个 readline 启动文件(参见 bash(1))。

首先,使 DELETE 键删除光标下的字符,并使 HOMEEND 键工作,方法是添加

DEL: delete-char
# Home.
"\\e[1~": beginning-of-line
# End.
"\\e[4~": end-of-line"

DELbash 理解为 DELETE 的特殊符号。对于 HOMEEND 键,它们的转义序列在引号中给出,后跟一个冒号,然后是命令。

要确定按键传输的转义序列,请在 custom.map 中查找它。或者,启动 Emacs,然后键入 CTRL-Q,后跟按键。这通常会将转义序列插入缓冲区。ESCAPE 字符将显示为 ^[,即 control-左方括号。

到目前为止显示的 readline 命令取自 bash 手册页。如果您想对按键进行编程以在按下时输入常规命令,请将命令放在引号中。例如,要使数字小键盘上的 1 键列出当前目录,请添加以下行

# KP_1
"\\eOq": "ls\\C-m"

\\C-mCTRL-M 或回车符,我们知道,这是执行命令所必需的。

可以根据需要对其他按键进行编程。保存文件。

如果创建了系统范围的 /etc/inputrc 文件,请将以下行添加到 /etc/profile

export INPUTRC=/etc/inputrc

然后键入

# . /etc/profile
这将覆盖默认的初始化文件 ~/.inputrc。

无论文件创建在何处,现在都可以通过键入 CTRL-XCTRL-R 来激活它,这通常绑定到 readline 命令 “re-read-init-file”。

Less

创建一个新文件,/etc/lesskey,用于系统范围。这将是一个 lesskey(1) 输入文件。完全按照所示键入以下行,然后保存文件

#line-edit
\\177    delete
^H      backspace
\\e[1~   home
\\e[4~   end

控制行 #line-edit 引入了用于行编辑命令的绑定。\\177DELETE 的八进制表示形式,^H 代表 CTRL-H,即 BACKSPACE。转义序列是 HOMEEND 键传输的序列。

按如下方式编译文件

# lesskey -o /etc/less /etc/lesskey

将以下行添加到 /etc/profile

export LESS="-k/etc/less$"
然后键入
# . /etc/profile
下次执行 less 时,它将从 /etc/less 读取按键定义。当在屏幕底部输入命令行时(例如,搜索命令的模式),这些按键定义将处于活动状态。

如果用户想要向 less 添加个人按键定义,可以将它们放在一个文件中,例如 ~/lesskey,然后按如下方式编译

# lesskey -o ~/.less ~/lesskey

这些个人按键定义将与系统范围定义的按键定义一起激活。

Netscape 和 Minicom

由于 Netscape 来自 DOS/Windows 世界,因此不需要特殊配置。设计人员使 BACKSPACEDELETEHOMEENDPAGE UPPAGE DOWN 按预期工作。这只是表明有人做得很好,并且为这种设计增加了可信度。

如果使用 minicom,则以 root 用户身份输入命令

# minicom -s

这将激活 minicom 的配置菜单。从菜单中选择 “Screen and keyboard”。键入 “A”,然后按空格键。使用 “B” 确定 BACKSPACE 应传输什么。由于大多数远程系统将使用 DELETE 向左删除,“DEL” 可能是这里的最佳选择。如果这造成问题,请将其更改为 BS。完成后按 ESC

返回配置菜单,选择 “Save setup as dfl”,然后选择 “Exit from Minicom”。

Emacs

Emacs 可以在至少三种不同的环境中执行:在虚拟控制台中、在 xterm 中或在 X11 窗口管理器中。要在 xterm 中运行 Emacs,必须使用 -nw 选项。无论在何种环境中,按键都将执行相同的功能。

Emacs 包含一系列键映射,这些键映射将输入事件转换为其他输入事件,并最终转换为命令。图 1 中图解了其中三个键映射。省略号表示省略了本文范围之外的键映射。

以 root 用户身份,将目录更改为 /usr/lib/emacs/XX.XX/lisp/term,其中 XX.XX 是 Emacs 的已安装版本。此目录包含几种类型的终端的初始化文件。阅读 README 文件以获取更多信息。

备份 xterm.el,然后编辑此文件,使其看起来像 列表 1。此文件将按键发送的转义序列映射到长度为 1 的 Emacs 向量。向量是一个通用的 Emacs 数组,向量值用方括号括起来,例如,。

当 Emacs 在 xterm 或虚拟控制台中执行时,它会读取此文件。然后配置 function-key-map,以便当按下这些按键中的任何一个时,Emacs 会自动将转义序列转换为向量。这使得配置 Emacs 更加容易,不仅因为所有按键都可以通过其名称引用,而且还因为程序员在创建此文件后永远不需要记住转义序列。此外,这些向量的名称与 X Window 键符的名称相同,从而在所有三个执行环境之间提供了一致性。

PAGE UP/DOWN 键现在称为 prior 和 next。这些定义为某些 Emacs 命令(例如日历)提供了支持,这些命令期望这些按键可用。此外,即使 /etc/X11/Xmodmap 将这些按键定义为传输 Page_Up 和 Page_Down 键符,当在 X 下运行时,Emacs 会将它们视为 prior 和 next。

列出了两组箭头键的定义:Reset 或 Normal 和 Set 或 Application。这是因为 VT100 系列终端有两种操作模式,在这些模式下,按键传输不同的转义序列。请注意,在 /usr/lib/kbd/keytables/custom.map 中,ALT-UP ARROW 17) 传输 \\e\\e[A,但在 /etc/X11/Xresources 中,ALT-UP ARROW 传输 \\e\\eOA。在这两种情况下,它们都是 ESCAPE,后跟 UP ARROW 键传输的转义序列。处理此问题的一种方法是简单地定义两组转义序列,如此处所示。

配置文件 xterm.el 需要编译以提高性能,并覆盖先前编译的版本。保存文件后,输入以下命令

# emacs -batch -f batch-byte-compile xterm.el

由于此文件也专为虚拟控制台设计,因此请按如下方式创建链接

# ln -s xterm.el con80x25.el
# ln -s xterm.elc con80x25.elc
trl
.elc 文件(已编译)是 Emacs 使用的文件。

对于直接在 X 下运行 Emacs,需要对 x-win.el 进行一些更改。请备份副本,然后找到并按所示更改以下行

(define-key function-key-map [backspace] [?\\b])
(define-key function-key-map [M-backspace] [?\\M-\\b])
(put 'backspace 'ascii-character 8)

保存文件。使用以下命令编译它

# emacs -batch -f batch-byte-compile x-win.el
当直接在 X11 窗口管理器下运行时,Emacs 不需要了解转义序列,因为它直接接收键符并自动将其转换为向量。但是,由于设计声明 BACKSPACE 键传输 BACKSPACE,而不是 DELETE,因此必须更改三行以使 x-win.el 符合要求。请注意,M-backspace 是 Meta-backspace 的缩写,Meta-backspace 是 ALT-backspace 的同义词。

现在终于到了最后一步,为 Emacs 按键分配功能。将目录更改为 /usr/lib/emacs/site-lisp,这是本地 Emacs Lisp 程序的存储位置。

创建一个名为 “ibmkey.el” 的文件,以定义 IBM PC 兼容键盘的按键绑定。输入 列表 2 ibmkey.el 中所需的内容。

默认的 Emacs 键翻译映射在 /usr/lib/emacs/XX.XX/lisp/loaddefs.el 中定义。此文件包含在 Debian 发行版的 emacs-el (GNU Emacs LISP 文件) 包中。它通常将 F1 键和 HELP 键(如果存在)映射到 BACKSPACE,因为 BACKSPACE (CTRL-H) 通常在 global-map 中映射到 Emacs help-command。参考图 1。

但是,为了适应此处提出的设计,将重新定义 key-translation-map。由于 Emacs 基于以下假设:DELETE 用于删除光标左侧的字符,并且此处提出的设计假设 BACKSPACE 键将执行该功能,因此 key-translation-map 将用于切换 BACKSPACEDELETE 键。完成此操作后,按下 BACKSPACE 键将导致从 key-translation-map 中输出一个 DELETE,按下 DELETE 将导致输出一个 BACKSPACE

为了减少混乱,变量 “BACKSPACE” 定义为保存一个 DELETE,变量 “DELETE” 定义为保存一个 BACKSPACE。这样,当按下 BACKSPACE 时,变量 “BACKSPACE” 的值将从 key-translation-map 中输出,当按下 DELETE 时,变量 “DELETE” 的值将输出,从而消除由切换引起的混乱。

许多功能键被定义为示例,使用 global-map。由于 BACKSPACE 不再可用于帮助,因此 F1 现在直接映射到该功能,而无需使用 key-translation-map。F4 映射到 Undo。BACKSPACE 键和编辑键被定义为执行其标记的功能,除了 prior 和 next,它们已经由 Emacs 定义(参见 loaddefs.el)。按住 ALT 的同时,箭头键将向所有四个方向平移文本。最后,数字小键盘的按键被定义为执行各种功能。

有几个编程 Emacs 的信息来源。按 F1 两次以访问广泛的在线帮助工具。此外,《GNU Emacs Lisp 参考手册》(800 多页)可在 ftp://prep.ai.mit.edu/pub/gnu/elisp-manual-19-2.4.tar.gz 获取,供真正认真的 Emacs Lisp 程序员使用。本手册也可以从自由软件基金会订购。订单表格位于 /usr/lib/emacs/XX.XX/etc/ORDERS* 中。

现在保存,然后编译 ibmkey.el

# emacs -batch -f batch-byte-compile ibmkey.el

最后,编辑 /usr/lib/emacs/site-lisp/site-start.el,并添加此行

(load "ibmkey")
当系统上的任何人启动 Emacs 时,此文件将自动加载 ibmkey.el(或 ibmkey.elc,如果 ibmkey.el 已编译)。如果需要个人按键映射,请将其放置在 ~/.emacs 中。
总结

本文介绍了为 Linux 内核、X Window 系统、xterm、bash、less、Netscape、minicom 和 Emacs 配置和编程键盘的技术。表 1. 配置文件和命令 总结了配置文件和命令。

按照这些说明操作后,键盘应配置为更像典型用户习惯使用的键盘。编辑键将按标签执行操作。Caps Lock 和左 CTRL 键将被切换。各种其他按键将执行有用的功能。此外,此处讨论的基本技术可以应用于其他允许配置键盘的计算机程序。

John Bunch,bunch@ro.com,是阿拉巴马州亨茨维尔大学浸信会教堂的成员,他在那里在合唱团唱歌。为了支付他和教堂的账单,他在 Intergraph Corporation 担任软件顾问。他拥有田纳西大学诺克斯维尔分校的计算机科学学士学位和东田纳西州立大学约翰逊城分校的计算机科学硕士学位。

加载 Disqus 评论