diff options
| author | Stefan Monnier | 2008-01-15 22:33:05 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2008-01-15 22:33:05 +0000 |
| commit | 5dbb074d607340282798b3eea482fa7c9bff6658 (patch) | |
| tree | 11061122c289157de11ab55d009a9f0ef69938bb | |
| parent | 30e68410fec9e2d3f0d06c6b9e60a77b7feb4c2a (diff) | |
| download | emacs-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/ChangeLog | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/easymenu.el | 65 |
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 @@ | |||
| 1 | 2008-01-15 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2008-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. | ||
| 221 | If it holds a list, this is expected to be a list of keys already seen in the | ||
| 222 | menu 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. |
| 222 | MENU-NAME is a string, the name of the menu. MENU-ITEMS is a list of items | 227 | MENU-NAME is a string, the name of the menu. MENU-ITEMS is a list of items |
| 223 | possibly preceded by keyword pairs as described in `easy-menu-define'." | 228 | possibly 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'. |