I have menu-bar-open
bound on f11 and menu-bar turned off, and because of that, f11 calls tmm-menubar
, which is inconvenient and doesn't have mode-specific menu items for some reason (like org and tbl in org-mode). I want it to behave this way: make menu-bar visible, enable user to choose menu item, after that make menu-bar invisible again.
What is the most idiomatic and elegant way to to that?
I thought on writing advices, but Emacs developers usually recommend against it, as it causes problems for debug, and standard Emacs code does not include advices.
I use Emacs 24.1 in GUI.
In Emacs-24 you can simply do this:
(global-set-key [f9] 'toggle-menu-bar-mode-from-frame)
If you're running a graphical Emacs session with menu-bar-mode
disabled, then C-<mouse-3>
should bring up the entire contents of the menu as a popup dialogue box. If you're running Emacs in a terminal, however, this definitely won't work; you haven't specified which is the case, so I'll try not to make assumptions. It's also possible to create custom mouse bindings (optionally, with keyboard modifiers) to the mouse-popup-menubar
and/or mouse-popup-menubar-stuff
functions, but ultimately that would only enable you to replicate behavior similar to the standard functionality that I've described above.
Due to the somewhat inflexible and global nature of menu-bar-mode
(i.e., the fact that it applies across all Emacs frames and provides for relatively little customization via hooks, etc.), I think it would be very difficult to achieve precisely the behavior you desire with vanilla Emacs. It might be possible to write a custom function to temporarily enable menu-bar-mode
and then use something like post-command-hook
to disable it again after a selection is made, but I'm not certain. I'll try to investigate further if time allows.
Also, you might wish to look into third-party menu-bar packages, (q.v., the Menu Bar section of EmacsWiki).
Edit: I've hacked together a rather kludgy solution that you may find useful...
(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))
I've tested this in a graphical session and it appears to simulate the behavior that you wanted, as long as you don't perform any action that Emacs registers as a command between executing my-menu-bar-open
and making your selection (which is basically anything other than navigating the menu itself). The choice of 42
is a magic number (and a Douglas Adams homage) intended to minimize the risk that the hook function would be activated for more typical values of the menu-bar-mode
variable. I don't claim that this is in any way elegant, but, in its decidedly ugly way, it does work. If you decide to use this, simply bind my-menu-bar-open
to f11
(or whatever you prefer), i.e.:
(global-set-key [f11] 'my-menu-bar-open)
Alternatively, you can probably achieve very similar functionality by using pre-command-hook
in an analogous fashion and instead advising menu-bar-open
to perform a temporary toggle of menu-bar-mode
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With