Update FSF's address.
[bpt/emacs.git] / lisp / emacs-lisp / easymenu.el
CommitLineData
029b623a
RS
1;;; easymenu.el --- support the easymenu interface for defining a menu.
2
029b623a
RS
3;; Copyright (C) 1994 Free Software Foundation, Inc.
4
8df69fb0
RS
5;; Keywords: emulations
6;; Author: rms
7
029b623a
RS
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
b578f267
EN
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
029b623a 24
b578f267
EN
25;;; Commentary:
26
27;; This is compatible with easymenu.el by Per Abrahamsen
28;; but it is much simpler as it doesn't try to support other Emacs versions.
29;; The code was mostly derived from lmenu.el.
029b623a
RS
30
31;;; Code:
32
a8226f67 33;;;###autoload
8df69fb0 34(defmacro easy-menu-define (symbol maps doc menu)
029b623a 35 "Define a menu bar submenu in maps MAPS, according to MENU.
819fefed
RS
36The menu keymap is stored in symbol SYMBOL, both as its value
37and as its function definition. DOC is used as the doc string for SYMBOL.
029b623a
RS
38
39The first element of MENU must be a string. It is the menu bar item name.
40The rest of the elements are menu items.
41
8df69fb0 42A menu item is usually a vector of three elements: [NAME CALLBACK ENABLE]
029b623a 43
a8226f67 44NAME is a string--the menu item name.
029b623a 45
a8226f67
RS
46CALLBACK is a command to run when the item is chosen,
47or a list to evaluate when the item is chosen.
029b623a 48
5a51e0a6
RS
49ENABLE is an expression; the item is enabled for selection
50whenever this expression's value is non-nil.
8df69fb0 51
1ba15fe6
RS
52Alternatively, a menu item may have the form:
53
54 [ NAME CALLBACK [ KEYWORD ARG ] ... ]
55
56Where KEYWORD is one of the symbol defined below.
57
58 :keys KEYS
59
60KEYS is a string; a complex keyboard equivalent to this menu item.
61This is normally not needed because keyboard equivalents are usually
62computed automatically.
63
64 :active ENABLE
65
66ENABLE is an expression; the item is enabled for selection
67whenever this expression's value is non-nil.
68
69 :suffix NAME
70
71NAME is a string; the name of an argument to CALLBACK.
72
41e6ca7a 73 :style STYLE
1ba15fe6
RS
74
75STYLE is a symbol describing the type of menu item. The following are
76defined:
77
78toggle: A checkbox.
79 Currently just prepend the name with the string \"Toggle \".
80radio: A radio button.
81nil: An ordinary menu item.
82
83 :selected SELECTED
84
85SELECTED is an expression; the checkbox or radio button is selected
86whenever this expression's value is non-nil.
87Currently just disable radio buttons, no effect on checkboxes.
88
a8226f67
RS
89A menu item can be a string. Then that string appears in the menu as
90unselectable text. A string consisting solely of hyphens is displayed
91as a solid horizontal line.
029b623a 92
a8226f67 93A menu item can be a list. It is treated as a submenu.
029b623a
RS
94The first element should be the submenu name. That's used as the
95menu item in the top-level menu. The cdr of the submenu list
96is a list of menu items, as above."
1ba15fe6
RS
97 (` (progn
98 (defvar (, symbol) nil (, doc))
99 (easy-menu-do-define (quote (, symbol)) (, maps) (, doc) (, menu)))))
100
f39223a6 101;;;###autoload
1ba15fe6
RS
102(defun easy-menu-do-define (symbol maps doc menu)
103 ;; We can't do anything that might differ between Emacs dialects in
104 ;; `easy-menu-define' in order to make byte compiled files
105 ;; compatible. Therefore everything interesting is done in this
106 ;; function.
107 (set symbol (easy-menu-create-keymaps (car menu) (cdr menu)))
108 (fset symbol (` (lambda (event) (, doc) (interactive "@e")
109 (easy-popup-menu event (, symbol)))))
110 (mapcar (function (lambda (map)
111 (define-key map (vector 'menu-bar (intern (car menu)))
112 (cons (car menu) (symbol-value symbol)))))
113 (if (keymapp maps) (list maps) maps)))
a8226f67
RS
114
115(defvar easy-menu-item-count 0)
029b623a
RS
116
117;; Return a menu keymap corresponding to a Lucid-style menu list
118;; MENU-ITEMS, and with name MENU-NAME.
815d2127 119;;;###autoload
8b4b171e 120(defun easy-menu-create-keymaps (menu-name menu-items)
029b623a
RS
121 (let ((menu (make-sparse-keymap menu-name)))
122 ;; Process items in reverse order,
123 ;; since the define-key loop reverses them again.
124 (setq menu-items (reverse menu-items))
125 (while menu-items
126 (let* ((item (car menu-items))
127 (callback (if (vectorp item) (aref item 1)))
128 command enabler name)
129 (cond ((stringp item)
130 (setq command nil)
131 (setq name (if (string-match "^-+$" item) "" item)))
132 ((consp item)
8b4b171e 133 (setq command (easy-menu-create-keymaps (car item) (cdr item)))
4fd6247b 134 (setq name (car item)))
029b623a
RS
135 ((vectorp item)
136 (setq command (make-symbol (format "menu-function-%d"
a8226f67 137 easy-menu-item-count)))
a8226f67 138 (setq easy-menu-item-count (1+ easy-menu-item-count))
1ba15fe6
RS
139 (setq name (aref item 0))
140 (let ((keyword (aref item 2)))
141 (if (and (symbolp keyword)
142 (= ?: (aref (symbol-name keyword) 0)))
143 (let ((count 2)
144 style selected active keys
145 arg)
146 (while (> (length item) count)
147 (setq keyword (aref item count))
148 (setq arg (aref item (1+ count)))
149 (setq count (+ 2 count))
150 (cond ((eq keyword ':keys)
151 (setq keys arg))
152 ((eq keyword ':active)
153 (setq active arg))
154 ((eq keyword ':suffix)
155 (setq name (concat name " " arg)))
156 ((eq keyword ':style)
157 (setq style arg))
158 ((eq keyword ':selected)
159 (setq selected arg))))
160 (if keys
161 (setq name (concat name " (" keys ")")))
162 (if (eq style 'toggle)
163 ;; Simulate checkboxes.
164 (setq name (concat "Toggle " name)))
165 (if active
166 (put command 'menu-enable active)
167 (and (eq style 'radio)
168 selected
169 ;; Simulate radio buttons with menu-enable.
170 (put command 'menu-enable
0579e89d
KH
171 (list 'not selected)))))
172 (put command 'menu-enable keyword)))
8df69fb0
RS
173 (if (keymapp callback)
174 (setq name (concat name " ...")))
029b623a
RS
175 (if (symbolp callback)
176 (fset command callback)
177 (fset command (list 'lambda () '(interactive) callback)))))
178 (if (null command)
179 ;; Handle inactive strings specially--allow any number
180 ;; of identical ones.
181 (setcdr menu (cons (list nil name) (cdr menu)))
182 (if name
183 (define-key menu (vector (intern name)) (cons name command)))))
184 (setq menu-items (cdr menu-items)))
185 menu))
186
88153c47
RS
187(defun easy-menu-change (path name items)
188 "Change menu found at PATH as item NAME to contain ITEMS.
189PATH is a list of strings for locating the menu containing NAME in the
190menu bar. ITEMS is a list of menu items, as in `easy-menu-define'.
191These items entirely replace the previous items in that map.
192
193Call this from `activate-menubar-hook' to implement dynamic menus."
194 (let ((map (key-binding (apply 'vector
195 'menu-bar
196 (mapcar 'intern (append path (list name)))))))
197 (if (keymapp map)
198 (setcdr map (cdr (easy-menu-create-keymaps name items)))
199 (error "Malformed menu in `easy-menu-change'"))))
200
1ba15fe6 201(defun easy-menu-remove (menu))
8df69fb0 202
1ba15fe6 203(defun easy-menu-add (menu &optional map))
8df69fb0 204
029b623a
RS
205(provide 'easymenu)
206
207;;; easymenu.el ends here