Dynamically show/hide menu bar in Emacs
elisp, emacs, menu, menubar
Solution
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`.
Problem
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.