命令循环通过调用 read-key-sequence 每次读取一个按键序列。Lisp 程序也可调用此函数;
例如,describe-key 会使用它读取需要描述的按键。
该函数读取一个按键序列,并以字符串或向量形式返回。它会持续读取事件,直到收集到一个完整的 按键序列—即足以通过当前激活的按键映射表指定非前缀命令的序列。(请注意,以鼠标事件开头 的按键序列会使用鼠标所在窗口的缓冲区按键映射表读取,而非当前缓冲区的。)
若所有事件均为字符且均可存入字符串,则 read-key-sequence 返回字符串(see 将键盘事件存入字符串)。
否则返回向量,因为向量可存储各类事件—字符、符号和列表。
字符串或向量的元素即为按键序列中的事件。
读取按键序列的过程包含对事件进行多种方式的转换,See 事件序列翻译键盘映射。
参数 prompt 可为字符串(会显示在回显区作为提示),或 nil(表示不显示提示)。
参数 continue-echo 若非 nil,表示将此按键作为前一按键的延续进行回显。
默认情况下,若某个大写事件未定义绑定,但其小写等效事件已定义,则会将该事件转换为小写。
参数 dont-downcase-last 若非 nil,表示不将最后一个事件转换为小写。此参数适用于
读取待定义的按键序列场景。
参数 switch-frame-ok 若非 nil,表示若用户在输入任何内容前切换框架,则此函数应
处理 switch-frame 事件。若用户在按键序列输入过程中切换框架,或在序列起始时切换但
switch-frame-ok 为 nil,则该事件会延迟至当前按键序列读取完成后处理。
参数 command-loop 若非 nil,表示此按键序列由需要连续读取命令的程序读取。若调用方
仅读取单个按键序列,则应设为 nil。
参数 disable-text-conversion 若非 nil,表示读取此按键序列期间,系统输入法不会
直接编辑缓冲区文本;用户输入始终只会生成独立的按键事件。关于文本转换的更多信息,See 其他系统事件。
以下示例中,Emacs 会在回显区显示提示 ‘?’,随后用户按下 C-x C-f:
(read-key-sequence "?")
---------- Echo Area ----------
?C-x C-f
---------- Echo Area ----------
⇒ "^X^F"
函数 read-key-sequence 会抑制退出操作:在此函数读取输入时按下 C-g,其行为与其他
字符无异,不会设置 quit-flag。See 退出。
此函数与 read-key-sequence 功能相同,区别在于它始终以向量形式返回按键序列,
从不以字符串形式返回。See 将键盘事件存入字符串。
若输入字符为大写(或带有 Shift 修饰符)且无按键绑定,但其小写等效字符有绑定,则
read-key-sequence 会将该字符转换为小写。(可通过将用户选项
translate-upper-case-key-bindings 设置为 nil 禁用此行为。)请注意,
lookup-key 不会以这种方式执行大小写转换。
当读取输入时发生此类 Shift 转换(shift-translation),Emacs 会将变量
this-command-keys-shift-translated 设置为非 nil 值。Lisp 程序若需在被
Shift 转换后的按键调用时修改行为,可检查此变量。例如,函数 handle-shift-selection
会检查此变量的值,以确定如何激活或取消激活区域(see handle-shift-selection)。
函数 read-key-sequence 还会转换部分鼠标事件:将未绑定的拖动事件转换为点击事件,
并完全丢弃未绑定的按下按钮事件。它还会重新整理焦点事件和各类窗口事件,使其不会与其他
事件一同出现在按键序列中。
当鼠标事件或 touchscreen-begin、touchscreen-end 事件发生在窗口或框架的特殊区域
(如模式行、滚动条)时,事件类型无特殊标识—使用的符号与通常表示该鼠标按键和修饰键组合的
符号相同。关于窗口区域的信息存储在事件的其他位置—坐标中。但 read-key-sequence 会将
此信息转换为虚拟前缀按键(均为符号):tab-line、header-line、
horizontal-scroll-bar、menu-bar、tab-bar、mode-line、
vertical-line、vertical-scroll-bar、left-margin、right-margin、
left-fringe、right-fringe、right-divider 和 bottom-divider。
你可通过使用这些虚拟前缀按键定义按键序列,来为窗口特殊区域的鼠标点击定义功能。
例如,若调用 read-key-sequence 后点击窗口的模式行,会得到两个事件,如下所示:
(read-key-sequence "Click on the mode line: ")
⇒ [mode-line
(mouse-1
(#<window 6 on NEWS> mode-line
(40 . 63) 5959987))]
此变量的值为当前 Emacs 会话中已处理的按键序列总数,包括从终端读取的按键序列和执行键盘宏 时读取的按键序列。