adding custom menus

If you read emacs-fu and other emacs websites, you might gather an increasing number of useful functions in your .emacs; so many, in fact, that it can be hard to remember them all. One way to solve this, is by adding a new menu to emacs, in which you can put your most useful commands. So, how to add our own custom menu? It's easy - when you use the aptly-named easymenu-package. Suppose we want to add a top-level menu called MyMenu, with some useful functions; simply add this to your .emacs:
(easy-menu-define djcb-menu global-map "MyMenu"
     ;; http://emacs-fu.blogspot.com/2008/12/running-console-programs-inside-emacs.html
     ("Programs" ;; submenu
       ["mutt"  (djcb-term-start-or-switch "mutt" t)]
       ["mc"    (djcb-term-start-or-switch "mc" t)]
       ["htop"  (djcb-term-start-or-switch "htop" t)]
       ["iotop" (djcb-term-start-or-switch "iotop" t)])
     ;; http://emacs-fu.blogspot.com/2009/03/math-formulae-in-webpages.html
     ;; this submenu is only visible when in html-mode or html-helper-mode
     ("TeXDrive"  :visible (or (string= major-mode "html-helper-mode") (string= major-mode "html-mode"))
       ["Insert formula"   texdrive-insert-formula :help "Insert some formula"]
       ["Generate images"  texdrive-generate-images :help "(Re)generate the images for the formulae"])
     ;; http://emacs-fu.blogspot.com/2009/03/twitter.html
     ("Twitter" ;; submenu
       ["View friends" twitter-get-friends-timeline]
       ["What are you doing?" twitter-status-edit])

     ("Misc"  ;; submenu
       ;; http://emacs-fu.blogspot.com/2009/01/counting-words.html
       ["Count words" djcb-count-words]

       ["Show/hide line numbers" linum]

       ;; http://emacs-fu.blogspot.com/2008/12/running-emacs-in-full-screen-mode.html
       ["Toggle full-screen" djcb-fullscreen-toggle])))
Suffice it to say that you actually need to have the functions installed - see the links for the ones that interest you.

The menu-system is much more powerful than I show here. With easy-menu, your menus are mode-specific (or mode-map-specific); I use the global-map, so the menu is always visible. You can also include special 'toggle' menu items, you can make items active/inactive visible/invisible based on some function evaluation. You can also add your menu as a submenu to an existing one. I don't really need all that, but there are some great ways to spend some hours to get things just right :) Anyway, as an example of some of the extras, look at the TexDrive submenu, which is only visible when we're in html-mode or html-helper-mode. And see the help:-expressions, that define tooltips for the menu items.

There is one imperfection left. Right now, my menu is added at the left-most position. I haven't been able to figure out is to add the menu at the most-right position in the menubar (or maybe just before the 'Help' entry). It can be done with e.g. Drew Adams' menubar+, but I found that a bit less... easy. Anyway, an exercise for the reader...


emilio said...

Try this to move your Menu before the help menu:

(easy-menu-remove-item global-map '("menu-bar") "MyMenu")

(easy-menu-add-item nil '("menu-bar") djcb-menu "help-menu")

djcb said...

Hmmm... that gives me a copy of my 'djcb' menu as a submenu of a new top level menu called "menu-bar", between Tools and Lisp-Interaction. That might be some e24-specific though... anyway I'll play around a bit with easy-menu-(remove|add)-item, thanks!

lawlist said...

Did anyone ever figure out how to add a new menu to the right of Help?