Skip to main content

22.17.1 Defining Menus

A keymap acts as a menu if it has an overall prompt string, which is a string that appears as an element of the keymap. (See Format of Keymaps.) The string should describe the purpose of the menu’s commands. Emacs displays the overall prompt string as the menu title in some cases, depending on the toolkit (if any) used for displaying menus.1 Keyboard menus also display the overall prompt string.

The easiest way to construct a keymap with a prompt string is to specify the string as an argument when you call make-keymap, make-sparse-keymap (see Creating Keymaps), or define-prefix-command (see Definition of define-prefix-command). If you do not want the keymap to operate as a menu, don’t specify a prompt string for it.

function keymap-prompt keymap

This function returns the overall prompt string of keymap, or nil if it has none.

The menu’s items are the bindings in the keymap. Each binding associates an event type to a definition, but the event types have no significance for the menu appearance. (Usually we use pseudo-events, symbols that the keyboard cannot generate, as the event types for menu item bindings.) The menu is generated entirely from the bindings that correspond in the keymap to these events.

The order of items in the menu is the same as the order of bindings in the keymap. Since define-key puts new bindings at the front, you should define the menu items starting at the bottom of the menu and moving to the top, if you care about the order. When you add an item to an existing menu, you can specify its position in the menu using define-key-after (see Modifying Menus).

Simple Menu Items  A simple kind of menu key binding.
Extended Menu Items  More complex menu item definitions.
Menu Separators  Drawing a horizontal line through a menu.
Alias Menu Items  Using command aliases in menu items.

22.17.1.1 Simple Menu Items

The simpler (and original) way to define a menu item is to bind some event type (it doesn’t matter what event type) to a binding like this:

(item-string . real-binding)

The CAR, item-string, is the string to be displayed in the menu. It should be short—preferably one to three words. It should describe the action of the command it corresponds to. Note that not all graphical toolkits can display non-ASCII text in menus (it will work for keyboard menus and will work to a large extent with the GTK+ toolkit).

You can also supply a second string, called the help string, as follows:

(item-string help . real-binding)

help specifies a help-echo string to display while the mouse is on that item in the same way as help-echo text properties (see Help display).

As far as define-key is concerned, item-string and help-string are part of the event’s binding. However, lookup-key returns just real-binding, and only real-binding is used for executing the key.

If real-binding is nil, then item-string appears in the menu but cannot be selected.

If real-binding is a symbol and has a non-nil menu-enable property, that property is an expression that controls whether the menu item is enabled. Every time the keymap is used to display a menu, Emacs evaluates the expression, and it enables the menu item only if the expression’s value is non-nil. When a menu item is disabled, it is displayed in a fuzzy fashion, and cannot be selected.

The menu bar does not recalculate which items are enabled every time you look at a menu. This is because the X toolkit requires the whole tree of menus in advance. To force recalculation of the menu bar, call force-mode-line-update (see Mode Line Format).

22.17.1.2 Extended Menu Items

An extended-format menu item is a more flexible and also cleaner alternative to the simple format. You define an event type with a binding that’s a list starting with the symbol menu-item. For a non-selectable string, the binding looks like this:

(menu-item item-name)

A string starting with two or more dashes specifies a separator line; see Menu Separators.

To define a real menu item which can be selected, the extended format binding looks like this:

(menu-item item-name real-binding
. item-property-list)

Here, item-name is an expression which evaluates to the menu item string. Thus, the string need not be a constant.

The third element, real-binding, can be the command to execute (in which case you get a normal menu item). It can also be a keymap, which will result in a submenu. Finally, it can be nil, in which case you will get a non-selectable menu item. This is mostly useful when creating separator lines and the like.

The tail of the list, item-property-list, has the form of a property list which contains other information.

Here is a table of the properties that are supported:

:enable form

The result of evaluating form determines whether the item is enabled (non-nil means yes). If the item is not enabled, you can’t really click on it.

:visible form

The result of evaluating form determines whether the item should actually appear in the menu (non-nil means yes). If the item does not appear, then the menu is displayed as if this item were not defined at all.

:help help

The value of this property, help, specifies a help-echo string to display while the mouse is on that item. This is displayed in the same way as help-echo text properties (see Help display). Note that this must be a constant string, unlike the help-echo property for text and overlays.

:button (type . selected)

This property provides a way to define radio buttons and toggle buttons. The CAR, type, says which: it should be :toggle or :radio. The CDR, selected, should be a form; the result of evaluating it says whether this button is currently selected.

A toggle is a menu item which is labeled as either on or off according to the value of selected. The command itself should toggle selected, setting it to t if it is nil, and to nil if it is t. Here is how the menu item to toggle the debug-on-error flag is defined:

(menu-item "Debug on Error" toggle-debug-on-error
:button (:toggle
. (and (boundp 'debug-on-error)
debug-on-error)))

This works because toggle-debug-on-error is defined as a command which toggles the variable debug-on-error.

Radio buttons are a group of menu items, in which at any time one and only one is selected. There should be a variable whose value says which one is selected at any time. The selected form for each radio button in the group should check whether the variable has the right value for selecting that button. Clicking on the button should set the variable so that the button you clicked on becomes selected.

:key-sequence key-sequence

This property specifies which key sequence to display as keyboard equivalent. Before Emacs displays key-sequence in the menu, it verifies that key-sequence is really equivalent to this menu item, so it only has an effect if you specify a correct key sequence. Specifying nil for key-sequence is equivalent to the :key-sequence attribute being absent.

:keys string

This property specifies that string is the string to display as the keyboard equivalent for this menu item. You can use the ‘\\[...]’ documentation construct in string.

:filter filter-fn

This property provides a way to compute the menu item dynamically. The property value filter-fn should be a function of one argument; when it is called, its argument will be real-binding. The function should return the binding to use instead.

Emacs can call this function at any time that it does redisplay or operates on menu data structures, so you should write it so it can safely be called at any time.

22.17.1.3 Menu Separators

A menu separator is a kind of menu item that doesn’t display any text—instead, it divides the menu into subparts with a horizontal line. A separator looks like this in the menu keymap:

(menu-item separator-type)

where separator-type is a string starting with two or more dashes.

In the simplest case, separator-type consists of only dashes. That specifies the default kind of separator. (For compatibility, "" and - also count as separators.)

Certain other values of separator-type specify a different style of separator. Here is a table of them:

"--no-line"

"--space"

An extra vertical space, with no actual line.

"--single-line"

A single line in the menu’s foreground color.

"--double-line"

A double line in the menu’s foreground color.

"--single-dashed-line"

A single dashed line in the menu’s foreground color.

"--double-dashed-line"

A double dashed line in the menu’s foreground color.

"--shadow-etched-in"

A single line with a 3D sunken appearance. This is the default, used separators consisting of dashes only.

"--shadow-etched-out"

A single line with a 3D raised appearance.

"--shadow-etched-in-dash"

A single dashed line with a 3D sunken appearance.

"--shadow-etched-out-dash"

A single dashed line with a 3D raised appearance.

"--shadow-double-etched-in"

Two lines with a 3D sunken appearance.

"--shadow-double-etched-out"

Two lines with a 3D raised appearance.

"--shadow-double-etched-in-dash"

Two dashed lines with a 3D sunken appearance.

"--shadow-double-etched-out-dash"

Two dashed lines with a 3D raised appearance.

You can also give these names in another style, adding a colon after the double-dash and replacing each single dash with capitalization of the following word. Thus, "--:singleLine", is equivalent to "--single-line".

You can use a longer form to specify keywords such as :enable and :visible for a menu separator:

(menu-item separator-type nil . item-property-list)

For example:

(menu-item "--" nil :visible (boundp 'foo))

Some systems and display toolkits don’t really handle all of these separator types. If you use a type that isn’t supported, the menu displays a similar kind of separator that is supported.

22.17.1.4 Alias Menu Items

Sometimes it is useful to make menu items that use the same command but with different enable conditions. The best way to do this in Emacs now is with extended menu items; before that feature existed, it could be done by defining alias commands and using them in menu items. Here’s an example that makes two aliases for read-only-mode and gives them different enable conditions:

(defalias 'make-read-only 'read-only-mode)
(put 'make-read-only 'menu-enable '(not buffer-read-only))
(defalias 'make-writable 'read-only-mode)
(put 'make-writable 'menu-enable 'buffer-read-only)

When using aliases in menus, often it is useful to display the equivalent key bindings for the real command name, not the aliases (which typically don’t have any key bindings except for the menu itself). To request this, give the alias symbol a non-nil menu-alias property. Thus,

(put 'make-read-only 'menu-alias t)
(put 'make-writable 'menu-alias t)

causes menu items for make-read-only and make-writable to show the keyboard bindings for read-only-mode.


  1. It is required for menus which do not use a toolkit, e.g., on a text terminal.