5

I have a set of functions that I'd like to put to menu bar for ease of access. For this, I need to create new menu item on menu bar. How can I achieve that?

Dan
  • 32,584
  • 6
  • 98
  • 168
MatthewRock
  • 1,453
  • 13
  • 27

3 Answers3

7

So-called easy-menu is one way. But it is not always easier than the "hard way", and the "hard way" is not hard. This is all you need to do:

  1. Define a variable to hold your menu keymap, e.g., my-menu-bar-menu.

  2. Bind a menu key in some keymap (e.g. global-map), which puts your menu on the menu-bar: (define-key global-map [menu-bar my-menu] (cons "Mine" my-menu-bar-menu)).

  3. Bind menu-item keys in your menu keymap. E.g., (define-key my-menu-bar-menu [my-cmd1] ...).

(defvar my-menu-bar-menu (make-sparse-keymap "Mine"))
(define-key global-map [menu-bar my-menu] (cons "Mine" my-menu-bar-menu))

(define-key my-menu-bar-menu [my-cmd1]
  '(menu-item "My Command 1" my-cmd1 :help "Do what my-cmd1 does"))
(define-key my-menu-bar-menu [my-cmd2]
  '(menu-item "My Command 2" my-cmd2 :help "Do what my-cmd2 does"))
...
JeanPierre
  • 7,323
  • 1
  • 18
  • 37
Drew
  • 75,699
  • 9
  • 109
  • 225
3

Use easy-menu

Quoting Emacswiki:

EasyMenu (lisp/emacs-lisp/easymenu.el) is a package which allows you to write menu definitions which work under both, Emacs and XEmacs.

Usage

The code below can serve as an example to easymenu:

(defvar menuitem1
  ["Set mark!" (set-mark-command nil)]) ; Boring alias for C-SPC

(defvar menuitem2
  ["Show fireworks!" (lambda () (interactive) (message-box "Fun!"))]) ; Making function interactive

;;Menu with submenus.
(defvar menuitem3
  '("Submenu" ; Note that list must be quoted, otherwise it would be treated as function.
    ("SubSubmenu"
     ["This will do wonders" (lambda () (interactive) (beep)) [:help "Welcome to the banana"]]
     ["And this will do nothing" (lambda () (interactive))])
    ("SubSubmenu2"
     ["Boring alias" (replace-string " " " banana ")])))

(easy-menu-define test-menu nil "Menu used as an example."
  `("Test menu"
    ,menuitem1
    ,menuitem2
    ,menuitem3
    ["Items can also be defined here" (lambda () (interactive) (message-box "It's simple!"))]))

;;; Insert menu after options menu, in global menu bar.
(define-key-after (lookup-key global-map [menu-bar])
  [mymenu] ; shortcut for our menu
  (cons "Test menu" test-menu) 'options) ; Our menu's name in cons.
MatthewRock
  • 1,453
  • 13
  • 27
1

Menu-bar is actually a pretty good memory aid for remembering important commands and its shortcuts. Its a pity that many modes come just with basic menus.
But you can add items to those mode menus. Here is how to do that. This answer fits pretty well to this question and expands the other answers already given.

Say you want to add Items to *scratch* buffers Lisp-interaction menu-bar menu. First you need to know where to add your item (the path). Press C-h k (describe-key) and select item Evaluate and Print from the Lisp-Interaction menu-bar.
Help will show you something like this:

<menu-bar> <lisp-interaction> <eval-print-last-sexp> runs the command
eval-print-last-sexp (found in lisp-interaction-mode-map) ...

The parts inside the pointed brackets is the path to this item. Also the name of the keymap is stated, inside the round brackets.

With this knowledge, lets add an menu item to the top of this menu:

(define-key lisp-interaction-mode-map [menu-bar lisp-interaction menu-item-test-1]
  '(menu-item "My Command 1" my-cmd1 :help "Do what my-cmd1 does"))

As you can see the path (inside the square brackets) changed to point to the new item.

Add an Item to the end of this menu:

(define-key-after lisp-interaction-mode-map [menu-bar lisp-interaction menu-item-test-2]
  '(menu-item "My Command 2" my-cmd2 :help "Do what my-cmd2 does"))

Now add an item directly after Evaluate and Print:

(define-key-after lisp-interaction-mode-map [menu-bar lisp-interaction menu-item-test-3]
    '(menu-item "My Command 3" my-cmd3 :help "Do what my-cmd3 does")
    'eval-print-last-sexp)

And last but not least how to add an item before Evaluate and Print with easy-menu:

(easy-menu-add-item lisp-interaction-mode-map '(menu-bar lisp-interaction)
                    ["My Command 4" my-cmd-4 :help "Do what my-cmd4 does"] "Evaluate and Print")

With this many examples, I hope you can see the pattern.

jue
  • 4,476
  • 8
  • 20