diff options
| author | John Wiegley | 2021-02-10 08:09:23 -0800 |
|---|---|---|
| committer | GitHub | 2021-02-10 08:09:23 -0800 |
| commit | ffa5f0397af87c7258f58082408281bf3a5a2deb (patch) | |
| tree | ea1363c97dfe81dce23507a47b9c72950fb4bd03 | |
| parent | a248658910204bb20b64eedba7d1c1f32bbaca94 (diff) | |
| parent | 5ca7bc321d1684cf718c59088b785a5fc00fc276 (diff) | |
| download | emacs-ffa5f0397af87c7258f58082408281bf3a5a2deb.tar.gz emacs-ffa5f0397af87c7258f58082408281bf3a5a2deb.zip | |
Merge pull request from minad/improved-unbind
GitHub-reference: https://github.com/jwiegley/use-package/issues/910
| -rw-r--r-- | lisp/use-package/bind-key.el | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index fef23740c67..1d611c2933c 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el | |||
| @@ -168,16 +168,19 @@ or operates on menu data structures, so you should write it so it | |||
| 168 | can safely be called at any time." | 168 | can safely be called at any time." |
| 169 | (let ((namevar (make-symbol "name")) | 169 | (let ((namevar (make-symbol "name")) |
| 170 | (keyvar (make-symbol "key")) | 170 | (keyvar (make-symbol "key")) |
| 171 | (kmapvar (make-symbol "kmap")) | ||
| 171 | (kdescvar (make-symbol "kdesc")) | 172 | (kdescvar (make-symbol "kdesc")) |
| 172 | (bindingvar (make-symbol "binding"))) | 173 | (bindingvar (make-symbol "binding"))) |
| 173 | `(let* ((,namevar ,key-name) | 174 | `(let* ((,namevar ,key-name) |
| 174 | (,keyvar (if (vectorp ,namevar) ,namevar | 175 | (,keyvar (if (vectorp ,namevar) ,namevar |
| 175 | (read-kbd-macro ,namevar))) | 176 | (read-kbd-macro ,namevar))) |
| 176 | (kmap (if (and ,keymap (symbolp ,keymap)) (symbol-value ,keymap) ,keymap)) | 177 | (,kmapvar (or (if (and ,keymap (symbolp ,keymap)) |
| 178 | (symbol-value ,keymap) ,keymap) | ||
| 179 | global-map)) | ||
| 177 | (,kdescvar (cons (if (stringp ,namevar) ,namevar | 180 | (,kdescvar (cons (if (stringp ,namevar) ,namevar |
| 178 | (key-description ,namevar)) | 181 | (key-description ,namevar)) |
| 179 | (if (symbolp ,keymap) ,keymap (quote ,keymap)))) | 182 | (if (symbolp ,keymap) ,keymap (quote ,keymap)))) |
| 180 | (,bindingvar (lookup-key (or kmap global-map) ,keyvar))) | 183 | (,bindingvar (lookup-key ,kmapvar ,keyvar))) |
| 181 | (let ((entry (assoc ,kdescvar personal-keybindings)) | 184 | (let ((entry (assoc ,kdescvar personal-keybindings)) |
| 182 | (details (list ,command | 185 | (details (list ,command |
| 183 | (unless (numberp ,bindingvar) | 186 | (unless (numberp ,bindingvar) |
| @@ -186,27 +189,57 @@ can safely be called at any time." | |||
| 186 | (setcdr entry details) | 189 | (setcdr entry details) |
| 187 | (add-to-list 'personal-keybindings (cons ,kdescvar details)))) | 190 | (add-to-list 'personal-keybindings (cons ,kdescvar details)))) |
| 188 | ,(if predicate | 191 | ,(if predicate |
| 189 | `(define-key (or kmap global-map) ,keyvar | 192 | `(define-key ,kmapvar ,keyvar |
| 190 | '(menu-item "" nil :filter (lambda (&optional _) | 193 | '(menu-item "" nil :filter (lambda (&optional _) |
| 191 | (when ,predicate | 194 | (when ,predicate |
| 192 | ,command)))) | 195 | ,command)))) |
| 193 | `(define-key (or kmap global-map) ,keyvar ,command))))) | 196 | `(define-key ,kmapvar ,keyvar ,command))))) |
| 194 | 197 | ||
| 195 | ;;;###autoload | 198 | ;;;###autoload |
| 196 | (defmacro unbind-key (key-name &optional keymap) | 199 | (defmacro unbind-key (key-name &optional keymap) |
| 197 | "Unbind the given KEY-NAME, within the KEYMAP (if specified). | 200 | "Unbind the given KEY-NAME, within the KEYMAP (if specified). |
| 198 | See `bind-key' for more details." | 201 | See `bind-key' for more details." |
| 199 | `(progn | 202 | (let ((namevar (make-symbol "name")) |
| 200 | (bind-key ,key-name nil ,keymap) | 203 | (kdescvar (make-symbol "kdesc"))) |
| 201 | (setq personal-keybindings | 204 | `(let* ((,namevar ,key-name) |
| 202 | (cl-delete-if #'(lambda (k) | 205 | (,kdescvar (cons (if (stringp ,namevar) ,namevar |
| 203 | ,(if keymap | 206 | (key-description ,namevar)) |
| 204 | `(and (consp (car k)) | 207 | (if (symbolp ,keymap) ,keymap (quote ,keymap))))) |
| 205 | (string= (caar k) ,key-name) | 208 | (bind-key--remove (if (vectorp ,namevar) ,namevar |
| 206 | (eq (cdar k) ',keymap)) | 209 | (read-kbd-macro ,namevar)) |
| 207 | `(and (stringp (car k)) | 210 | (or (if (and ,keymap (symbolp ,keymap)) |
| 208 | (string= (car k) ,key-name)))) | 211 | (symbol-value ,keymap) ,keymap) |
| 209 | personal-keybindings)))) | 212 | global-map)) |
| 213 | (setq personal-keybindings | ||
| 214 | (cl-delete-if (lambda (k) (equal (car k) ,kdescvar)) | ||
| 215 | personal-keybindings)) | ||
| 216 | nil))) | ||
| 217 | |||
| 218 | (defun bind-key--remove (key keymap) | ||
| 219 | "Remove KEY from KEYMAP. | ||
| 220 | |||
| 221 | In contrast to `define-key', this function removes the binding from the keymap." | ||
| 222 | (define-key keymap key nil) | ||
| 223 | ;; Split M-key in ESC key | ||
| 224 | (setq key (mapcan (lambda (k) | ||
| 225 | (if (and (integerp k) (/= (logand k ?\M-\0) 0)) | ||
| 226 | (list ?\e (logxor k ?\M-\0)) | ||
| 227 | (list k))) | ||
| 228 | key)) | ||
| 229 | ;; Delete single keys directly | ||
| 230 | (if (= (length key) 1) | ||
| 231 | (delete key keymap) | ||
| 232 | ;; Lookup submap and delete key from there | ||
| 233 | (let* ((prefix (vconcat (butlast key))) | ||
| 234 | (submap (lookup-key keymap prefix))) | ||
| 235 | (unless (keymapp submap) | ||
| 236 | (error "Not a keymap for %s" key)) | ||
| 237 | (when (symbolp submap) | ||
| 238 | (setq submap (symbol-function submap))) | ||
| 239 | (delete (last key) submap) | ||
| 240 | ;; Delete submap if it is empty | ||
| 241 | (when (= 1 (length submap)) | ||
| 242 | (bind-key--remove prefix keymap))))) | ||
| 210 | 243 | ||
| 211 | ;;;###autoload | 244 | ;;;###autoload |
| 212 | (defmacro bind-key* (key-name command &optional predicate) | 245 | (defmacro bind-key* (key-name command &optional predicate) |