A Tab Bar Menu in Emacs
One of the first customizations folks make to their Emacs is to hide the menu bar. This makes some sense if you’re using a completion UI like Ivy: it’s usually faster and more convenient to find an option using fuzzy completion in the minibuffer than it is to mouse over a series of menus. Also, the menu covers only options that are relevant to the end-user. If you want fine-grained customization or access to Emacs’ API, you’ll need to use a different interface (like
customize). The menu is thus seen as a crutch for new users to outgrow.
It’s a shame, though. The menu bar serves two useful purposes:
describe-*commands are good for “keyword searches”, i.e finding exact names for features that you know exist, including a rough idea of what it might be called ("…probably ends in
-hook?"). But what about the unknown unkowns? Unless you chance upon features you want when looking for something else, you’re out of luck. The menu bar is a helpful guide to discover features. CUA-mode, one of the most common new user requests is front and center in the menu bar:
Organization: The menu bar for any major-mode usually contains a comprehensive collection of options for that mode. Notwithstanding some recent improvements to command filtering, the
M-xinterface throws up the entire bag of Emacs’ commands at you irrespective of the context in which it’s called. The
describe-*commands are worse. In contrast, the menu bar changes depending on what modes you have active, and generally provides a relevant set of actions. For example, the menu bar in programming modes provides options for linting, compilation, tracing, code folding and so on.1 The menu in LaTeX or Org-mode is quite different.
But if we’re honest, the real reason the menu bar is avoided tends to be more superficial: it takes up space and does not compose visually with Emacs’ theming.
Let’s address this too. There are at least two non-invasive approaches to using the menu in Emacs.
The text-mode menu
There’s a text-mode menu built into Emacs. Calling
tmm-menubar (bound to
M-` by default) will allow menu-bar access from the minibuffer (or equivalent), helping with discoverability and organization as before:
The tab-bar menu
The second method requires Emacs 28. You can shove the menu into the tab-bar:
To do this, you add the built-in function
tab-bar-format, which is the list of widgets to show in the tab bar.
(add-to-list 'tab-bar-format #'tab-bar-format-menu-bar)
Contrary to its name, the tab-bar can show arbitrary information. For example, the system time and battery information in addition to the menu and open tabs:
I use tabs (as workspaces) and the tab-bar already, so I prefer this method for accessing the menu occasionally.2