在 Emacs 中动态显示/隐藏菜单栏

问题描述 投票:0回答:5

我在

f11
上绑定了 menu-bar-open 并关闭了菜单栏,因此,f11 调用
tmm-menubar
,这很不方便,并且由于某种原因没有特定于模式的菜单项(例如 org和 org 模式下的 tbl)。我希望它的行为方式如下:使菜单栏可见,使用户能够选择菜单项,然后再次使菜单栏不可见。

最惯用和优雅的方式是什么?

我想过编写建议,但 Emacs 开发人员通常建议不要这样做,因为它会导致调试问题,而标准 Emacs 代码不包含建议。

我在 GUI 中使用 Emacs 24.1。

emacs menu elisp menubar
5个回答
9
投票

在 Emacs-24 中你可以简单地这样做:

(global-set-key [f9] 'toggle-menu-bar-mode-from-frame)
  • 不确定 24 之前的 Emacs 版本。
  • 只需确保 f9 在您的安装中确实可用。

4
投票

如果您在禁用

menu-bar-mode
的情况下运行图形 Emacs 会话,则
C-<mouse-3>
应该将菜单的全部内容显示为弹出对话框。然而,如果您在终端中运行 Emacs,这肯定行不通;你没有具体说明是哪种情况,所以我会尽量不做假设。还可以为
mouse-popup-menubar
和/或
mouse-popup-menubar-stuff
函数创建自定义鼠标绑定(可选地,使用键盘修饰符),但最终这只会让您复制与我上面描述的标准功能类似的行为。

由于

menu-bar-mode
有点不灵活和全局性(即它适用于所有 Emacs 框架并通过钩子等提供相对较少的定制),我认为精确实现该行为将非常困难你想要的普通 Emacs。可能可以编写一个自定义函数来临时启用
menu-bar-mode
,然后在做出选择后使用类似
post-command-hook
的功能再次禁用它,但我不确定。如果时间允许,我会尝试进一步调查。

此外,您可能希望研究第三方菜单栏软件包,(q.v.,EmacsWiki 的菜单栏部分)。

编辑:我编写了一个相当笨拙的解决方案,您可能会发现有用......

(add-hook
 'pre-command-hook
 (lambda ()
   (when (eq menu-bar-mode 42)
     (menu-bar-mode -1))))

(defun my-menu-bar-open ()
  (interactive)
  (unless menu-bar-mode
    (menu-bar-mode 1))
  (menu-bar-open)
  (setq menu-bar-mode 42))

我已经在图形会话中对此进行了测试,它似乎可以模拟您想要的行为,只要您在执行

my-menu-bar-open
和做出选择之间不执行 Emacs 注册为命令的任何操作(这基本上是除了导航菜单本身之外的任何内容)。
42
的选择是一个神奇的数字(也是对 Douglas Adams 的致敬),旨在最大限度地降低钩子函数针对
menu-bar-mode
变量的更典型值而被激活的风险。我并不认为这在任何方面都是优雅的,但是,以它明显丑陋的方式,它确实有效。如果您决定使用此功能,只需将
my-menu-bar-open
绑定到
f11
(或您喜欢的任何内容),即:

(global-set-key [f11] 'my-menu-bar-open)

或者,您可以通过以类似的方式使用

pre-command-hook
并建议
menu-bar-open
执行
menu-bar-mode
的临时切换来实现非常相似的功能。


2
投票

对 Greg 的答案进行了一个小改进,使

pre-command-hook
保持干净:

(menu-bar-mode -1)

(defun my-menu-bar-open-after ()
  (remove-hook 'pre-command-hook 'my-menu-bar-open-after)
  (when (eq menu-bar-mode 42)
    (menu-bar-mode -1)))

(defun my-menu-bar-open (&rest args)
  (interactive)
  (let ((open menu-bar-mode))
    (unless open
      (menu-bar-mode 1))
    (funcall 'menu-bar-open args)
    (unless open
      (setq menu-bar-mode 42)
      (add-hook 'pre-command-hook 'my-menu-bar-open-after))))

(global-set-key [f10] 'my-menu-bar-open)

0
投票

我已经在 GNU Emacs 25.2 和 26.3 中对此进行了测试:

(menu-bar-mode -1)

(advice-add 'menu-bar-open
            :around
            (lambda (orig-fun &rest args)
              (menu-bar-mode 1)
              (apply orig-fun args)
              (menu-bar-mode -1)))

结果行为(假设

menu-bar-open
绑定到 F10,这是默认值):

  • 默认情况下不显示菜单栏。
  • 如果按F10,将显示菜单栏。
  • 一旦离开菜单栏,菜单栏就会消失,直到您下次按 F10

请注意,这更像是一种黑客行为,而不是正确的解决方案。


0
投票

我自己偶然发现了这一点,发现 Emacs 默认设置实际上对我来说没问题。

默认情况下,f10绑定到

menu-bar-open
,当我关闭菜单栏时,它会方便地弹出一个上下文菜单。请注意,它并没有在顶部显示实际的菜单栏,但我发现这不会造成太大的破坏,因为它不会“移动”整个窗口。

由于某种原因,这在终端模式下不起作用(

emacs -nw
)。在那里,就像你所描述的那样,当我输入 f10 时,我得到了更丑陋的
tmm-menubar
并且对
tty-menu-open-use-tmm
的任何干预都无法解决这个问题,无论 菜单栏文档怎么说。但那是在终端模式下,而你说你是在 GUI 模式下。

这是我在 GUI 模式(后面)和 TTY 模式(前面)中看到的屏幕截图:

screenshot of two emacs, one in Pure GTK mode and the other in TTY, showing menus

所以我不确定你发生了什么,但我发现在这种情况下删除一些自定义内容会很有帮助,就像我老化的 Emacs 配置向上游移动时经常出现的情况一样......我也明白我的回答并不完全是你想要的

我在 Debian bookworm 上使用 emacs-pgtk 和 Emacs 29 backport。

© www.soinside.com 2019 - 2024. All rights reserved.