From 5ca7bc321d1684cf718c59088b785a5fc00fc276 Mon Sep 17 00:00:00 2001 From: Daniel Mendler Date: Wed, 10 Feb 2021 14:13:36 +0100 Subject: [PATCH] unbind-key: Ensure that keys are removed from the keymap * The removal from the keymap is performed by bind-key--remove * Use the same argument normalization as bind-key --- lisp/use-package/bind-key.el | 52 ++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 13fd02ab89b..1d611c2933c 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -199,17 +199,47 @@ can safely be called at any time." (defmacro unbind-key (key-name &optional keymap) "Unbind the given KEY-NAME, within the KEYMAP (if specified). See `bind-key' for more details." - `(progn - (bind-key ,key-name nil ,keymap) - (setq personal-keybindings - (cl-delete-if #'(lambda (k) - ,(if keymap - `(and (consp (car k)) - (string= (caar k) ,key-name) - (eq (cdar k) ',keymap)) - `(and (stringp (car k)) - (string= (car k) ,key-name)))) - personal-keybindings)))) + (let ((namevar (make-symbol "name")) + (kdescvar (make-symbol "kdesc"))) + `(let* ((,namevar ,key-name) + (,kdescvar (cons (if (stringp ,namevar) ,namevar + (key-description ,namevar)) + (if (symbolp ,keymap) ,keymap (quote ,keymap))))) + (bind-key--remove (if (vectorp ,namevar) ,namevar + (read-kbd-macro ,namevar)) + (or (if (and ,keymap (symbolp ,keymap)) + (symbol-value ,keymap) ,keymap) + global-map)) + (setq personal-keybindings + (cl-delete-if (lambda (k) (equal (car k) ,kdescvar)) + personal-keybindings)) + nil))) + +(defun bind-key--remove (key keymap) + "Remove KEY from KEYMAP. + +In contrast to `define-key', this function removes the binding from the keymap." + (define-key keymap key nil) + ;; Split M-key in ESC key + (setq key (mapcan (lambda (k) + (if (and (integerp k) (/= (logand k ?\M-\0) 0)) + (list ?\e (logxor k ?\M-\0)) + (list k))) + key)) + ;; Delete single keys directly + (if (= (length key) 1) + (delete key keymap) + ;; Lookup submap and delete key from there + (let* ((prefix (vconcat (butlast key))) + (submap (lookup-key keymap prefix))) + (unless (keymapp submap) + (error "Not a keymap for %s" key)) + (when (symbolp submap) + (setq submap (symbol-function submap))) + (delete (last key) submap) + ;; Delete submap if it is empty + (when (= 1 (length submap)) + (bind-key--remove prefix keymap))))) ;;;###autoload (defmacro bind-key* (key-name command &optional predicate) -- 2.39.2