Mercurial > emacs
changeset 87768:2dfbe4c86ab7
(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.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Tue, 15 Jan 2008 22:33:05 +0000 |
parents | 90318261ac4d |
children | d62f6920cb4d |
files | lisp/ChangeLog lisp/emacs-lisp/easymenu.el |
diffstat | 2 files changed, 47 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/ChangeLog Tue Jan 15 21:40:09 2008 +0000 +++ b/lisp/ChangeLog Tue Jan 15 22:33:05 2008 +0000 @@ -1,5 +1,9 @@ 2008-01-15 Stefan Monnier <monnier@iro.umontreal.ca> + * emacs-lisp/easymenu.el (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. + * smerge-mode.el (smerge-refine): Also work on "same change conflicts". (smerge-makeup-conflict): New command.
--- a/lisp/emacs-lisp/easymenu.el Tue Jan 15 21:40:09 2008 +0000 +++ b/lisp/emacs-lisp/easymenu.el Tue Jan 15 22:33:05 2008 +0000 @@ -216,12 +216,18 @@ (setq menu (cdr (easy-menu-convert-item menu))))) menu) +(defvar easy-menu-avoid-duplicate-keys t + "Dynamically scoped var to register already used keys in a menu. +If it holds a list, this is expected to be a list of keys already seen in the +menu we're processing. Else it means we're not processing a menu.") + ;;;###autoload (defun easy-menu-create-menu (menu-name menu-items) "Create a menu called MENU-NAME with items described in MENU-ITEMS. MENU-NAME is a string, the name of the menu. MENU-ITEMS is a list of items possibly preceded by keyword pairs as described in `easy-menu-define'." (let ((menu (make-sparse-keymap menu-name)) + (easy-menu-avoid-duplicate-keys nil) prop keyword arg label enable filter visible help) ;; Look for keywords. (while (and menu-items @@ -341,22 +347,22 @@ (setq prop (cons :button (cons (cons (cdr style) selected) prop))))) (when (stringp keys) - (if (string-match "^[^\\]*\\(\\\\\\[\\([^]]+\\)]\\)[^\\]*$" - keys) - (let ((prefix - (if (< (match-beginning 0) (match-beginning 1)) - (substring keys 0 (match-beginning 1)))) - (postfix - (if (< (match-end 1) (match-end 0)) - (substring keys (match-end 1)))) - (cmd (intern (match-string 2 keys)))) - (setq keys (and (or prefix postfix) - (cons prefix postfix))) - (setq keys - (and (or keys (not (eq command cmd))) - (cons cmd keys)))) - (setq cache-specified nil)) - (if keys (setq prop (cons :keys (cons keys prop))))) + (if (string-match "^[^\\]*\\(\\\\\\[\\([^]]+\\)]\\)[^\\]*$" + keys) + (let ((prefix + (if (< (match-beginning 0) (match-beginning 1)) + (substring keys 0 (match-beginning 1)))) + (postfix + (if (< (match-end 1) (match-end 0)) + (substring keys (match-end 1)))) + (cmd (intern (match-string 2 keys)))) + (setq keys (and (or prefix postfix) + (cons prefix postfix))) + (setq keys + (and (or keys (not (eq command cmd))) + (cons cmd keys)))) + (setq cache-specified nil)) + (if keys (setq prop (cons :keys (cons keys prop))))) (if (and visible (not (easy-menu-always-true-p visible))) (if (equal visible ''nil) ;; Invisible menu item. Don't insert into keymap. @@ -371,12 +377,27 @@ ;; `intern' the name so as to merge multiple entries with the same name. ;; It also makes it easier/possible to lookup/change menu bindings ;; via keymap functions. - (cons (easy-menu-intern name) - (and (not remove) - (cons 'menu-item - (cons label - (and name - (cons command prop)))))))) + (let ((key (easy-menu-intern name))) + (when (listp easy-menu-avoid-duplicate-keys) + ;; Merging multiple entries with the same name is sometimes what we + ;; want, but not when the entries are actually different (e.g. same + ;; name but different :suffix as seen in cal-menu.el) and appear in + ;; the same menu. So we try to detect and resolve conflicts. + (while (and (stringp name) + (memq key easy-menu-avoid-duplicate-keys)) + ;; We need to use some distinct object, ideally a symbol, ideally + ;; related to the `name'. Uninterned symbols do not work (they + ;; are apparently turned into strings and re-interned later on). + (setq key (intern (format "%s (%d)" (symbol-name key) + (length easy-menu-avoid-duplicate-keys))))) + (push key easy-menu-avoid-duplicate-keys)) + + (cons key + (and (not remove) + (cons 'menu-item + (cons label + (and name + (cons command prop))))))))) (defun easy-menu-define-key (menu key item &optional before) "Add binding in MENU for KEY => ITEM. Similar to `define-key-after'.