]> git.eshelyaron.com Git - emacs.git/commitdiff
unbind-key: Ensure that keys are removed from the keymap
authorDaniel Mendler <mail@daniel-mendler.de>
Wed, 10 Feb 2021 13:13:36 +0000 (14:13 +0100)
committerDaniel Mendler <mail@daniel-mendler.de>
Wed, 10 Feb 2021 14:34:12 +0000 (15:34 +0100)
* 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

index 13fd02ab89b17d23a225237fa456e07ba81e3a1c..1d611c2933cb55589e69c8b00ddee2da37771c79 100644 (file)
@@ -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)