@end lisp
This function creates a new sparse keymap, defines the keystrokes in
-@var{pairs}, and returns the new keymap.
+@var{pairs}, and returns the new keymap. It signals an error if there
+are duplicate key bindings in @var{pairs}.
@var{pairs} is a list of alternating key bindings and key definitions,
as accepted by @code{keymap-set}. In addition, the key can be the
This macro defines @var{name} as a variable, passes @var{options}
and @var{pairs} to @code{define-keymap}, and uses the result as the
-default value for the variable.
+default value for the variable. It signals an error if there are
+duplicate key bindings in @var{pairs}.
@var{options} is like the keywords in @code{define-keymap}, but
there's an additional @code{:doc} keyword that provides the doc
(keymap keymap)
(prefix (define-prefix-command prefix nil name))
(full (make-keymap name))
- (t (make-sparse-keymap name)))))
+ (t (make-sparse-keymap name))))
+ seen-keys)
(when suppress
(suppress-keymap keymap (eq suppress 'nodigits)))
(when parent
(let ((def (pop definitions)))
(if (eq key :menu)
(easy-menu-define nil keymap "" def)
+ (if (member key seen-keys)
+ (error "Duplicate definition for key: %S %s" key keymap)
+ (push key seen-keys))
(keymap-set keymap key def)))))
keymap)))
(push (pop defs) opts))))
(unless (zerop (% (length defs) 2))
(error "Uneven number of key/definition pairs: %s" defs))
+ (let ((defs defs)
+ key seen-keys)
+ (while defs
+ (setq key (pop defs))
+ (pop defs)
+ (when (not (eq key :menu))
+ (if (member key seen-keys)
+ (error "Duplicate definition for key '%s' in keymap '%s'"
+ key variable-name)
+ (push key seen-keys)))))
`(defvar ,variable-name
(define-keymap ,@(nreverse opts) ,@defs)
,@(and doc (list doc)))))
(make-non-key-event 'keymap-tests-event)
(should (equal (where-is-internal 'keymap-tests-command) '([3 103]))))
+(ert-deftest keymap-test-duplicate-definitions ()
+ "Check that defvar-keymap rejects duplicate key definitions."
+ (should-error
+ (defvar-keymap
+ ert-keymap-duplicate
+ "a" #'next-line
+ "a" #'previous-line))
+ (should-error
+ (define-keymap
+ "a" #'next-line
+ "a" #'previous-line)))
+
(provide 'keymap-tests)
;;; keymap-tests.el ends here