2

Easymenu is great for creating menus, but how can you remove a top-level menu that was created with it?

Here's an example. A minor mode might create the following menu:

  (easy-menu-define some-minor-mode-menu some-minor-mode-map
    "Menu keymap for some minor mode."
    '("Menu"
      ["Item" command t]
      ...))

How would you remove this menu from the menubar using easymenu's own commands? Unfortunately, easymenu is poorly documented and all the available documentation is about how to add menus and submenus.

(I have been able to remove this sort of menu by adding (define-key some-minor-mode-map [menu-bar Menu] nil) to the major mode's hook, but is that the only way to do it? Does easymenu provide no facilities for this?)

Drew
  • 75,699
  • 9
  • 109
  • 225
GrB
  • 207
  • 1
  • 6
  • Do the last two messages in [this conversation](http://emacs.1067599.n8.nabble.com/How-to-delete-item-from-menu-bar-td59803.html) help you? – dalanicolai Dec 14 '20 at 12:46
  • Thanks for the pointer. The penultimate message there is the same as the solution I came up with. The solution with easy-menu-remove in the last message does not work for me -- it does remove the menu in question, but also several others and some other customizations don't load any more. Perhaps it has to be put into a hook. I'll investigate further. This might be trivial if easymenu were properly documented. – GrB Dec 14 '20 at 23:36

1 Answers1

1

I found an easy solution: use the :visible or :active properties of the fourth parameter of easy-menu-define.

Say you have defined a menu like this:

(easy-menu-define org-glaux-menu global-map "Org-glaux"
  (list "Org-glaux"
        ...
  ))

You can disable it with:

(easy-menu-define nil global-map nil 
  (list "Org-glaux" :visible nil))

Replacing :visible to :active also works. It would not be too hard to warp it into a function:

(defun my/easy-menu-remove (maps menu-name)
  "Remove MENU-NAME from the current menu bar."
  (easy-menu-define nil maps nil 
            (list menu-name :visible nil)))

See the documentation of easy-menu-define:

The first element of MENU must be a string. It is the menu bar item name. It may be followed by the following keyword argument pairs:

...

:visible INCLUDE

INCLUDE is an expression.  The menu is visible if the
expression evaluates to a non-nil value.  ‘:included’ is an
alias for ‘:visible’.

:active ENABLE

ENABLE is an expression.  The menu is enabled for selection
if the expression evaluates to a non-nil value.  ‘:enable’ is
an alias for ‘:active’.

A relevant comment from the documentation of easy-menu-remove:

(easy-menu-remove MENU)

This function is obsolete since 28.1; use ‘ignore’ instead. This function does not change global state, including the match data.

Remove MENU from the current menu bar. Contrary to XEmacs, this is a nop on Emacs since menus are automatically (de)activated when the corresponding keymap is (de)activated.

Firmin Martin
  • 1,265
  • 7
  • 23