aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2008-01-15 22:33:05 +0000
committerStefan Monnier2008-01-15 22:33:05 +0000
commit5dbb074d607340282798b3eea482fa7c9bff6658 (patch)
tree11061122c289157de11ab55d009a9f0ef69938bb
parent30e68410fec9e2d3f0d06c6b9e60a77b7feb4c2a (diff)
downloademacs-5dbb074d607340282798b3eea482fa7c9bff6658.tar.gz
emacs-5dbb074d607340282798b3eea482fa7c9bff6658.zip
(easy-menu-avoid-duplicate-keys): New var.
(easy-menu-create-menu, easy-menu-convert-item-1): Use it to avoid using the same key for different menu entries.
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/emacs-lisp/easymenu.el65
2 files changed, 47 insertions, 22 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index efd472826c1..396aa0fd92f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,9 @@
12008-01-15 Stefan Monnier <monnier@iro.umontreal.ca> 12008-01-15 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * emacs-lisp/easymenu.el (easy-menu-avoid-duplicate-keys): New var.
4 (easy-menu-create-menu, easy-menu-convert-item-1): Use it to avoid
5 using the same key for different menu entries.
6
3 * smerge-mode.el (smerge-refine): Also work on "same change conflicts". 7 * smerge-mode.el (smerge-refine): Also work on "same change conflicts".
4 (smerge-makeup-conflict): New command. 8 (smerge-makeup-conflict): New command.
5 9
diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el
index fa19ecd9c0f..ca5151fa984 100644
--- a/lisp/emacs-lisp/easymenu.el
+++ b/lisp/emacs-lisp/easymenu.el
@@ -216,12 +216,18 @@ If NAME is provided, it is used for the keymap."
216 (setq menu (cdr (easy-menu-convert-item menu))))) 216 (setq menu (cdr (easy-menu-convert-item menu)))))
217 menu) 217 menu)
218 218
219(defvar easy-menu-avoid-duplicate-keys t
220 "Dynamically scoped var to register already used keys in a menu.
221If it holds a list, this is expected to be a list of keys already seen in the
222menu we're processing. Else it means we're not processing a menu.")
223
219;;;###autoload 224;;;###autoload
220(defun easy-menu-create-menu (menu-name menu-items) 225(defun easy-menu-create-menu (menu-name menu-items)
221 "Create a menu called MENU-NAME with items described in MENU-ITEMS. 226 "Create a menu called MENU-NAME with items described in MENU-ITEMS.
222MENU-NAME is a string, the name of the menu. MENU-ITEMS is a list of items 227MENU-NAME is a string, the name of the menu. MENU-ITEMS is a list of items
223possibly preceded by keyword pairs as described in `easy-menu-define'." 228possibly preceded by keyword pairs as described in `easy-menu-define'."
224 (let ((menu (make-sparse-keymap menu-name)) 229 (let ((menu (make-sparse-keymap menu-name))
230 (easy-menu-avoid-duplicate-keys nil)
225 prop keyword arg label enable filter visible help) 231 prop keyword arg label enable filter visible help)
226 ;; Look for keywords. 232 ;; Look for keywords.
227 (while (and menu-items 233 (while (and menu-items
@@ -341,22 +347,22 @@ ITEM defines an item as in `easy-menu-define'."
341 (setq prop (cons :button 347 (setq prop (cons :button
342 (cons (cons (cdr style) selected) prop))))) 348 (cons (cons (cdr style) selected) prop)))))
343 (when (stringp keys) 349 (when (stringp keys)
344 (if (string-match "^[^\\]*\\(\\\\\\[\\([^]]+\\)]\\)[^\\]*$" 350 (if (string-match "^[^\\]*\\(\\\\\\[\\([^]]+\\)]\\)[^\\]*$"
345 keys) 351 keys)
346 (let ((prefix 352 (let ((prefix
347 (if (< (match-beginning 0) (match-beginning 1)) 353 (if (< (match-beginning 0) (match-beginning 1))
348 (substring keys 0 (match-beginning 1)))) 354 (substring keys 0 (match-beginning 1))))
349 (postfix 355 (postfix
350 (if (< (match-end 1) (match-end 0)) 356 (if (< (match-end 1) (match-end 0))
351 (substring keys (match-end 1)))) 357 (substring keys (match-end 1))))
352 (cmd (intern (match-string 2 keys)))) 358 (cmd (intern (match-string 2 keys))))
353 (setq keys (and (or prefix postfix) 359 (setq keys (and (or prefix postfix)
354 (cons prefix postfix))) 360 (cons prefix postfix)))
355 (setq keys 361 (setq keys
356 (and (or keys (not (eq command cmd))) 362 (and (or keys (not (eq command cmd)))
357 (cons cmd keys)))) 363 (cons cmd keys))))
358 (setq cache-specified nil)) 364 (setq cache-specified nil))
359 (if keys (setq prop (cons :keys (cons keys prop))))) 365 (if keys (setq prop (cons :keys (cons keys prop)))))
360 (if (and visible (not (easy-menu-always-true-p visible))) 366 (if (and visible (not (easy-menu-always-true-p visible)))
361 (if (equal visible ''nil) 367 (if (equal visible ''nil)
362 ;; Invisible menu item. Don't insert into keymap. 368 ;; Invisible menu item. Don't insert into keymap.
@@ -371,12 +377,27 @@ ITEM defines an item as in `easy-menu-define'."
371 ;; `intern' the name so as to merge multiple entries with the same name. 377 ;; `intern' the name so as to merge multiple entries with the same name.
372 ;; It also makes it easier/possible to lookup/change menu bindings 378 ;; It also makes it easier/possible to lookup/change menu bindings
373 ;; via keymap functions. 379 ;; via keymap functions.
374 (cons (easy-menu-intern name) 380 (let ((key (easy-menu-intern name)))
375 (and (not remove) 381 (when (listp easy-menu-avoid-duplicate-keys)
376 (cons 'menu-item 382 ;; Merging multiple entries with the same name is sometimes what we
377 (cons label 383 ;; want, but not when the entries are actually different (e.g. same
378 (and name 384 ;; name but different :suffix as seen in cal-menu.el) and appear in
379 (cons command prop)))))))) 385 ;; the same menu. So we try to detect and resolve conflicts.
386 (while (and (stringp name)
387 (memq key easy-menu-avoid-duplicate-keys))
388 ;; We need to use some distinct object, ideally a symbol, ideally
389 ;; related to the `name'. Uninterned symbols do not work (they
390 ;; are apparently turned into strings and re-interned later on).
391 (setq key (intern (format "%s (%d)" (symbol-name key)
392 (length easy-menu-avoid-duplicate-keys)))))
393 (push key easy-menu-avoid-duplicate-keys))
394
395 (cons key
396 (and (not remove)
397 (cons 'menu-item
398 (cons label
399 (and name
400 (cons command prop)))))))))
380 401
381(defun easy-menu-define-key (menu key item &optional before) 402(defun easy-menu-define-key (menu key item &optional before)
382 "Add binding in MENU for KEY => ITEM. Similar to `define-key-after'. 403 "Add binding in MENU for KEY => ITEM. Similar to `define-key-after'.