Make `keymap-set-after' work for menus

It still doesn't work for an AFTER that's a key, though, since
`key-parse' produces vectors, and keymaps contain integers.

* lisp/keymap.el (keymap-set-after): Only parse AFTER as a key if it's
a string.  For consistency, use `key-parse' on the definition if it's
a string, just like `keymap-set'.
* test/src/keymap-tests.el (keymap-tests--command-3): New dummy command.
(keymap-set-after-menus): New test.  Check that we can insert a menu
item after a specific entry.
This commit is contained in:
Robert Pluim 2023-01-19 16:05:45 +01:00
parent dcd59457b4
commit 06953fc8e1
2 changed files with 26 additions and 3 deletions

View file

@ -187,10 +187,16 @@ a menu, so this function is not useful for non-menu keymaps."
(compiler-macro (lambda (form) (keymap--compile-check key) form))) (compiler-macro (lambda (form) (keymap--compile-check key) form)))
(keymap--check key) (keymap--check key)
(when (eq after t) (setq after nil)) ; nil and t are treated the same (when (eq after t) (setq after nil)) ; nil and t are treated the same
(when after (when (stringp after)
(keymap--check after)) (keymap--check after)
(setq after (key-parse after)))
;; If we're binding this key to another key, then parse that other
;; key, too.
(when (stringp definition)
(keymap--check definition)
(setq definition (key-parse definition)))
(define-key-after keymap (key-parse key) definition (define-key-after keymap (key-parse key) definition
(and after (key-parse after)))) after))
(defun key-parse (keys) (defun key-parse (keys)
"Convert KEYS to the internal Emacs key representation. "Convert KEYS to the internal Emacs key representation.

View file

@ -226,6 +226,7 @@ commit 86c19714b097aa477d339ed99ffb5136c755a046."
(defun keymap-tests--command-1 () (interactive) nil) (defun keymap-tests--command-1 () (interactive) nil)
(defun keymap-tests--command-2 () (interactive) nil) (defun keymap-tests--command-2 () (interactive) nil)
(defun keymap-tests--command-3 () (interactive) nil)
(put 'keymap-tests--command-1 :advertised-binding [?y]) (put 'keymap-tests--command-1 :advertised-binding [?y])
(ert-deftest keymap-where-is-internal () (ert-deftest keymap-where-is-internal ()
@ -446,6 +447,22 @@ g .. h foo
(should-not (keymap-set-after k "f" "f" "a")) (should-not (keymap-set-after k "f" "f" "a"))
(should (equal (keymap-lookup k "f") (key-parse "f"))))) (should (equal (keymap-lookup k "f") (key-parse "f")))))
(ert-deftest keymap-set-after-menus ()
(let ((map (make-sparse-keymap)))
(keymap-set map "<cmd1>"
'(menu-item "Run Command 1" keymap-tests--command-1
:help "Command 1 Help"))
(keymap-set-after map "<cmd2>"
'(menu-item "Run Command 2" keymap-tests--command-2
:help "Command 2 Help"))
(keymap-set-after map "<cmd3>"
'(menu-item "Run Command 3" keymap-tests--command-3
:help "Command 3 Help")
'cmd1)
(should (equal (caadr map) 'cmd1))
(should (equal (caaddr map) 'cmd3))
(should (equal (caar (last map)) 'cmd2))))
(ert-deftest keymap-test-duplicate-definitions () (ert-deftest keymap-test-duplicate-definitions ()
"Check that defvar-keymap rejects duplicate key definitions." "Check that defvar-keymap rejects duplicate key definitions."
(should-error (should-error