本节介绍用于遍历所有当前按键映射、以输出帮助信息的函数。
若要显示某个特定按键映射中的绑定关系,可以使用 describe-keymap 命令(see Other Help Commands in The GNU Emacs Manual)。
该函数返回所有可从 keymap(通过零个或多个前缀键)访问到的按键映射构成的列表。
返回值为一个关联表,元素格式为 (key . map),
其中 key 是一个前缀键,它在 keymap 中的定义即为 map。
该关联表中的元素按 key 长度递增排序。
第一个元素始终为 ([] . keymap),
因为指定的按键映射可通过不含任何事件的前缀访问到自身。
若指定了 prefix,它应当是一个前缀按键序列;
此时 accessible-keymaps 只包含前缀以 prefix 开头的子映射。
这些元素的形式与 (accessible-keymaps) 的返回值完全相同,唯一区别是省略了部分元素。
在下面的示例中,返回的关联表表明按键 ESC(显示为 ‘^[’)是一个前缀键,
其定义为稀疏按键映射 (keymap (83 . center-paragraph) (115 . foo))。
(accessible-keymaps (current-local-map))
⇒(([] keymap
(27 keymap ; Note this keymap for ESC is repeated below.
(83 . center-paragraph)
(115 . center-line))
(9 . tab-to-tab-stop))
("^[" keymap
(83 . center-paragraph)
(115 . foo)))
在下面的示例中,C-h 是一个前缀键,
它使用一个以 (keymap (118 . describe-variable)…) 开头的稀疏按键映射。
另一个前缀 C-x 4 使用的按键映射同时也是变量 ctl-x-4-map 的值。
事件 mode-line 是若干虚拟事件之一,用作窗口特定区域中鼠标操作的前缀。
(accessible-keymaps (current-global-map))
⇒ (([] keymap [set-mark-command beginning-of-line ...
delete-backward-char])
("^H" keymap (118 . describe-variable) ...
(8 . help-for-help))
("^X" keymap [x-flush-mouse-queue ...
backward-kill-sentence])
("^[" keymap [mark-sexp backward-sexp ...
backward-kill-word])
("^X4" keymap (15 . display-buffer) ...)
([mode-line] keymap
(S-mouse-2 . mouse-split-window-horizontally) ...))
以上并非实际中能看到的全部按键映射。
函数 map-keymap 会对 keymap 中的每一个绑定执行一次 function。
它传递两个参数:事件类型与绑定值。如果 keymap 存在父映射,
父映射中的绑定也会一并包含。该过程是递归的:若父映射自身还有父映射,则祖父映射的绑定也会被包含,依此类推。
该函数是遍历一个按键映射中所有绑定的最简洁方式。
该函数是 where-is 命令使用的子例程(see Help in The GNU Emacs Manual)。
它返回一组按键映射中所有绑定到 command 的按键序列(任意长度)构成的列表。
参数 command 可以是任意对象;
函数会使用 eq 与所有按键映射条目进行比较。
若 keymap 为 nil,则使用当前活跃的按键映射,
忽略 overriding-local-map(即假设其值为 nil)。
若 keymap 是一个按键映射,则搜索范围为 keymap 与全局按键映射。
若 keymap 是按键映射列表,则只搜索这些映射。
通常最适合将 overriding-local-map 作为 keymap 的参数表达式。
此时 where-is-internal 会精确搜索当前活跃的按键映射。
若只想搜索全局映射,可传入 (keymap)(空按键映射)作为 keymap。
若 firstonly 为 non-ascii,则返回值为单个向量,
表示找到的第一个按键序列,而非所有可能序列构成的列表。
若 firstonly 为 t,则返回第一个按键序列,
但优先选择完全由 ASCII 字符(或带 Meta 修饰的 ASCII 字符)组成的序列,
且返回值绝不会是菜单绑定。
若 noindirect 非 nil,where-is-internal 不会深入菜单项内部查找其绑定的命令。这使得可以直接搜索菜单项本身。
第五个参数 no-remap 决定函数如何处理命令重映射(see 命令重映射)。主要有两种情况:
若 no-remap 为 nil,则查找 other-command 的绑定并将其视作 command 的绑定。
若 no-remap 非 nil,则在可能的按键序列列表中包含向量 [remap other-command],而非查找这些绑定。
若 no-remap 为 nil,则返回 other-command 的绑定而非 command。
若 no-remap 非 nil,则返回 command 本身的绑定,忽略其被重映射的事实。
若某个命令绑定到类似 [some-event] 的按键,
且 some-event 的符号属性列表中包含非 nil 的 non-key-event 属性,则该绑定会被 where-is-internal 忽略。
该函数生成所有当前按键绑定的列表,并在名为 *Help* 的缓冲区中显示。 文本按模式分组:首先是次要模式,随后是主模式,最后是全局绑定。
若 prefix 非 nil,它应当是一个前缀键;此时列表只包含以 prefix 开头的按键。
当多个 ASCII 连续编码的字符具有相同定义时,
会合并显示为 ‘firstchar..lastchar’。
这种情况下需要知道 ASCII 编码才能确定具体字符。
例如,在默认全局映射中,字符 ‘SPC .. ~’ 由一行统一描述。
SPC 的 ASCII 码为 32,~ 为 126,其间包含所有常规可打印字符(如字母、数字、标点等);
所有这些字符均绑定到 self-insert-command。
若 buffer-or-name 非 nil,它应当是一个缓冲区或缓冲区名称。
此时 describe-bindings 会列出该缓冲区的绑定,而非当前缓冲区的绑定。