aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2000-07-05 15:40:03 +0000
committerStefan Monnier2000-07-05 15:40:03 +0000
commitd0acce1e29485a348138d33a24584694e229ce20 (patch)
tree37eca116d321287b16eca23ae61e3f4ee20286ad
parent5e03eb84a161f32cd7c656b7b93508891bd36ec1 (diff)
downloademacs-d0acce1e29485a348138d33a24584694e229ce20.tar.gz
emacs-d0acce1e29485a348138d33a24584694e229ce20.zip
(easy-menu-define): Docstring fix.
(easy-menu-do-define): Use `menu-item' format. Handle case where easy-menu-create-menu returns a symbol. Manually call the potential top-level filter in the function binding. (easy-menu-filter-return): New arg NAME. Convert to a keymap if MENU is an XEmacs menu. (easy-menu-convert-item-1): New. Extracted from easy-menu-do-add-item. (easy-menu-converted-items-table, easy-menu-convert-item): New. (easy-menu-do-add-item): Use it. (easy-menu-create-menu): Use easy-menu-convert-item. Wrap easy-menu-filter-return around any :filter specification. Don't convert the menu if a filter was specified. Tell easy-menu-make-symbol not to check for MENU being an expression. (easy-menu-make-symbol): New arg NOEXP.
-rw-r--r--lisp/emacs-lisp/easymenu.el103
1 files changed, 74 insertions, 29 deletions
diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el
index ae3af3cc644..664bc4825ad 100644
--- a/lisp/emacs-lisp/easymenu.el
+++ b/lisp/emacs-lisp/easymenu.el
@@ -92,9 +92,9 @@ KEYS is expanded with `substitute-command-keys' before it is used.
92 92
93 :key-sequence KEYS 93 :key-sequence KEYS
94 94
95KEYS is nil a string or a vector; nil or a keyboard equivalent to this 95KEYS is nil, a string or a vector; nil or a keyboard equivalent to this
96menu item. 96menu item.
97This is a hint that will considerably speed up Emacs first display of 97This is a hint that will considerably speed up Emacs' first display of
98a menu. Use `:key-sequence nil' when you know that this menu item has no 98a menu. Use `:key-sequence nil' when you know that this menu item has no
99keyboard equivalent. 99keyboard equivalent.
100 100
@@ -108,9 +108,10 @@ whenever this expression's value is non-nil.
108INCLUDE is an expression; this item is only visible if this 108INCLUDE is an expression; this item is only visible if this
109expression has a non-nil value. 109expression has a non-nil value.
110 110
111 :suffix NAME 111 :suffix FORM
112 112
113NAME is a string; the name of an argument to CALLBACK. 113FORM is an expression that will be dynamically evaluated and whose
114value will be concatenated to the menu entry's NAME.
114 115
115 :style STYLE 116 :style STYLE
116 117
@@ -149,21 +150,42 @@ A menu item can be a list with the same format as MENU. This is a submenu."
149 ;; `easy-menu-define' in order to make byte compiled files 150 ;; `easy-menu-define' in order to make byte compiled files
150 ;; compatible. Therefore everything interesting is done in this 151 ;; compatible. Therefore everything interesting is done in this
151 ;; function. 152 ;; function.
152 (set symbol (easy-menu-create-menu (car menu) (cdr menu))) 153 (let ((keymap (easy-menu-create-menu (car menu) (cdr menu))))
153 (fset symbol `(lambda (event) ,doc (interactive "@e") 154 (set symbol keymap)
154 (x-popup-menu event ,symbol))) 155 (fset symbol
155 (mapcar (function (lambda (map) 156 `(lambda (event) ,doc (interactive "@e")
156 (define-key map (vector 'menu-bar (intern (car menu))) 157 ;; FIXME: XEmacs uses popup-menu which calls the binding
157 (cons (car menu) (symbol-value symbol))))) 158 ;; while x-popup-menu only returns the selection.
158 (if (keymapp maps) (list maps) maps))) 159 (x-popup-menu event
159 160 (or (and (symbolp ,symbol)
160(defun easy-menu-filter-return (menu) 161 (funcall
162 (or (plist-get (get ,symbol 'menu-prop)
163 :filter)
164 'identity)
165 (symbol-function ,symbol)))
166 ,symbol))))
167 (mapcar (lambda (map)
168 (define-key map (vector 'menu-bar (intern (car menu)))
169 (cons 'menu-item
170 (cons (car menu)
171 (if (not (symbolp keymap))
172 (list keymap)
173 (cons (symbol-function keymap)
174 (get keymap 'menu-prop)))))))
175 (if (keymapp maps) (list maps) maps))))
176
177(defun easy-menu-filter-return (menu &optional name)
161 "Convert MENU to the right thing to return from a menu filter. 178 "Convert MENU to the right thing to return from a menu filter.
162MENU is a menu as computed by `easy-menu-define' or `easy-menu-create-menu' or 179MENU is a menu as computed by `easy-menu-define' or `easy-menu-create-menu' or
163a symbol whose value is such a menu. 180a symbol whose value is such a menu.
164In Emacs a menu filter must return a menu (a keymap), in XEmacs a filter must 181In Emacs a menu filter must return a menu (a keymap), in XEmacs a filter must
165return a menu items list (without menu name and keywords). 182return a menu items list (without menu name and keywords).
166This function returns the right thing in the two cases." 183This function returns the right thing in the two cases.
184If NAME is provided, it is used for the keymap."
185 (when (and (not (keymapp menu)) (consp menu))
186 ;; If it's a cons but not a keymap, then it can't be right
187 ;; unless it's an XEmacs menu.
188 (setq menu (easy-menu-create-menu (or name "") menu)))
167 (easy-menu-get-map menu nil)) ; Get past indirections. 189 (easy-menu-get-map menu nil)) ; Get past indirections.
168 190
169;;;###autoload 191;;;###autoload
@@ -180,7 +202,9 @@ possibly preceded by keyword pairs as described in `easy-menu-define'."
180 (setq arg (cadr menu-items)) 202 (setq arg (cadr menu-items))
181 (setq menu-items (cddr menu-items)) 203 (setq menu-items (cddr menu-items))
182 (cond 204 (cond
183 ((eq keyword :filter) (setq filter arg)) 205 ((eq keyword :filter)
206 (setq filter `(lambda (menu)
207 (easy-menu-filter-return (,arg menu) ,menu-name))))
184 ((eq keyword :active) (setq enable (or arg ''nil))) 208 ((eq keyword :active) (setq enable (or arg ''nil)))
185 ((eq keyword :label) (setq label arg)) 209 ((eq keyword :label) (setq label arg))
186 ((eq keyword :help) (setq help arg)) 210 ((eq keyword :help) (setq help arg))
@@ -194,11 +218,15 @@ possibly preceded by keyword pairs as described in `easy-menu-define'."
194 (if filter (setq prop (cons :filter (cons filter prop)))) 218 (if filter (setq prop (cons :filter (cons filter prop))))
195 (if help (setq prop (cons :help (cons help prop)))) 219 (if help (setq prop (cons :help (cons help prop))))
196 (if label (setq prop (cons nil (cons label prop)))) 220 (if label (setq prop (cons nil (cons label prop))))
197 (while menu-items 221 (if filter
198 (easy-menu-do-add-item menu (car menu-items)) 222 ;; The filter expects the menu in its XEmacs form and the pre-filter
199 (setq menu-items (cdr menu-items))) 223 ;; form will only be passed to the filter anyway, so we'd better
224 ;; not convert it at all (it will be converted on the fly by
225 ;; easy-menu-filter-return).
226 (setq menu menu-items)
227 (setq menu (append menu (mapcar 'easy-menu-convert-item menu-items))))
200 (when prop 228 (when prop
201 (setq menu (easy-menu-make-symbol menu)) 229 (setq menu (easy-menu-make-symbol menu 'noexp))
202 (put menu 'menu-prop prop)) 230 (put menu 'menu-prop prop))
203 menu))) 231 menu)))
204 232
@@ -208,6 +236,23 @@ possibly preceded by keyword pairs as described in `easy-menu-define'."
208 '((radio . :radio) (toggle . :toggle))) 236 '((radio . :radio) (toggle . :toggle)))
209 237
210(defun easy-menu-do-add-item (menu item &optional before) 238(defun easy-menu-do-add-item (menu item &optional before)
239 (setq item (easy-menu-convert-item item))
240 (easy-menu-define-key-intern menu (car item) (cdr item) before))
241
242(defvar easy-menu-converted-items-table (make-hash-table :test 'equal))
243
244(defun easy-menu-convert-item (item)
245 ;; Memoize easy-menu-convert-item-1.
246 ;; This makes key-shortcut-caching work a *lot* better when this
247 ;; conversion is done from within a filter.
248 ;; This also helps when the NAME of the entry is recreated each time:
249 ;; since the menu is built and traversed separately, the lookup
250 ;; would always fail because the key is `equal' but not `eq'.
251 (or (gethash item easy-menu-converted-items-table)
252 (puthash item (easy-menu-convert-item-1 item)
253 easy-menu-converted-items-table)))
254
255(defun easy-menu-convert-item-1 (item)
211 ;; Parse an item description and add the item to a keymap. This is 256 ;; Parse an item description and add the item to a keymap. This is
212 ;; the function that is used for item definition by the other easy-menu 257 ;; the function that is used for item definition by the other easy-menu
213 ;; functions. 258 ;; functions.
@@ -305,13 +350,11 @@ possibly preceded by keyword pairs as described in `easy-menu-define'."
305 (or (null cache) (stringp cache) (vectorp cache))) 350 (or (null cache) (stringp cache) (vectorp cache)))
306 (setq prop (cons :key-sequence (cons cache prop)))))) 351 (setq prop (cons :key-sequence (cons cache prop))))))
307 (t (error "Invalid menu item in easymenu"))) 352 (t (error "Invalid menu item in easymenu")))
308 (easy-menu-define-key-intern menu name 353 (cons name (and (not remove)
309 (and (not remove) 354 (cons 'menu-item
310 (cons 'menu-item 355 (cons label
311 (cons label 356 (and name
312 (and name 357 (cons command prop))))))))
313 (cons command prop)))))
314 before)))
315 358
316(defun easy-menu-define-key-intern (menu key item &optional before) 359(defun easy-menu-define-key-intern (menu key item &optional before)
317 ;; This is the same as easy-menu-define-key, but it interns KEY and 360 ;; This is the same as easy-menu-define-key, but it interns KEY and
@@ -362,13 +405,15 @@ possibly preceded by keyword pairs as described in `easy-menu-define'."
362 405
363(defvar easy-menu-item-count 0) 406(defvar easy-menu-item-count 0)
364 407
365(defun easy-menu-make-symbol (callback) 408(defun easy-menu-make-symbol (callback &optional noexp)
366 ;; Return a unique symbol with CALLBACK as function value. 409 "Return a unique symbol with CALLBACK as function value.
410When non-nil, NOEXP indicates that CALLBACK cannot be an expression
411\(i.e. does not need to be turned into a function)."
367 (let ((command 412 (let ((command
368 (make-symbol (format "menu-function-%d" easy-menu-item-count)))) 413 (make-symbol (format "menu-function-%d" easy-menu-item-count))))
369 (setq easy-menu-item-count (1+ easy-menu-item-count)) 414 (setq easy-menu-item-count (1+ easy-menu-item-count))
370 (fset command 415 (fset command
371 (if (keymapp callback) callback 416 (if (or (keymapp callback) noexp) callback
372 `(lambda () (interactive) ,callback))) 417 `(lambda () (interactive) ,callback)))
373 command)) 418 command))
374 419