动态显示/隐藏Emacs菜单栏

5
我将menu-bar-open绑定在f11上,并关闭了菜单栏,因此f11调用tmm-menubar,这很不方便,而且由于某些原因没有特定于模式的菜单项(如org-mode中的org和tbl)。我希望它能这样工作:使菜单栏可见,允许用户选择菜单项,然后再次使菜单栏不可见。
最常用和优雅的方法是什么?
我考虑过编写建议,但Emacs开发人员通常不建议这样做,因为它会导致调试问题,标准的Emacs代码不包括建议。
我在GUI中使用Emacs 24.1。

2
建议肯定有可能引起混乱并使事情变得更加复杂,我记得这确实是Emacs自己的代码不这样做的原因之一(但另一个明显的原因是Emacs自己的代码不需要这样做——原始代码可以在必要时更改),但作为最终用户为其自己的需求定制行为,如果没有明显更好的方法可用,编写一些建议肯定没有问题。我认为这就是该设施首先开发的原因。 - phils
4个回答

9
在Emacs-24中,您可以简单地执行以下操作:
(global-set-key [f9] 'toggle-menu-bar-mode-from-frame)
  • 不确定Emacs 24版本以前的情况。
  • 确保您的安装中确实有f9按键可用。

这怎么成为最受欢迎的答案了?它只是切换菜单栏,而这只是 OP 想要的第一步。 - user643005

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这样的东西在选择后再次禁用它,但我不确定。如果时间允许,我会进一步调查。
此外,您可能希望查看第三方菜单栏包,(参见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

请注意,这更像是一个hack而不是一个正确的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接