Emacs 通常会在每个框架顶部显示一个 菜单栏(menu bar)。 See Menu Bars in The GNU Emacs Manual。 菜单项是虚拟功能键 MENU-BAR 的子命令,由当前生效的按键映射定义。
若要向菜单栏添加一项,可自行定义一个虚拟功能键(记作 key),
并为按键序列 [menu-bar key] 创建绑定。
最常见的做法是将该绑定设为一个菜单按键映射,
这样点击菜单栏该项即可打开下级菜单。
当多个生效的按键映射为菜单栏定义了同一个功能键时, 该菜单项只会出现一次。用户点击该菜单项后, 会弹出一个合并后的单一菜单,包含该项的所有子命令— 全局子命令、局部子命令以及次要模式子命令。
在计算菜单栏内容时,通常会忽略变量 overriding-local-map。
也就是说,菜单栏是按照 overriding-local-map 为 nil
时本应生效的按键映射计算得出的。See 活跃按键映射表。
下面是设置菜单栏项的示例:
;; 创建一个菜单按键映射(附带提示字符串) ;; 并将其设为菜单栏项的定义。 (define-key global-map [menu-bar words] (cons "Words" (make-sparse-keymap "Words")))
;; 在该菜单中定义具体子命令。
(define-key global-map
[menu-bar words forward]
'("Forward word" . forward-word))
(define-key global-map
[menu-bar words backward]
'("Backward word" . backward-word))
局部按键映射可以通过将同一个虚拟功能键重新绑定为 undefined
来取消全局按键映射创建的菜单栏项。
例如,Dired 模式就是这样隐藏 ‘Edit’ 菜单项的:
(define-key dired-mode-map [menu-bar edit] 'undefined)
此处 edit 是一个虚拟功能键对应的符号,
全局映射用它表示 ‘Edit’ 菜单项。
隐藏全局菜单项的主要目的,是为模式专属项腾出空间。
默认情况下,菜单栏先显示全局项,再显示局部映射定义的项。
该变量保存一组虚拟功能键列表,
用于指定哪些项显示在菜单栏末尾,而非按常规顺序排列。
默认值为 (help-menu),
因此 ‘Help’ 菜单项通常出现在菜单栏最后,位于局部菜单项之后。
这是一个常规钩子,在重绘菜单栏前由重绘机制运行,用于更新菜单栏内容。 你可以用它更新内容需要动态变化的菜单。 由于该钩子会被频繁调用,建议确保其调用的函数在常规情况下耗时很短。
在每个菜单栏项旁边,Emacs 会显示执行相同命令的按键绑定(若存在)。
这为不熟悉按键的用户提供了便捷提示。
若一个命令存在多个绑定,Emacs 通常显示找到的第一个绑定。
你可以为命令设置 :advertised-binding 符号属性,
指定要显示的特定按键绑定。See 文档中的按键绑定替换。