A long time ago I implemented
remove-key to completely undo the effect of
define-key, but when I just tried that implementation, it did not work reliably. How would you implement
remove-key so that for any given key this is true:
(let ((map (make-sparse-keymap))) (define-key map KEY 'bound) (remove-key map KEY) map) => (keymap)
It should also work for non-sparse keymaps. And when a sub-keymap is involved which becomes empty when the key is removed, then the sub-keymap should also be removed.
Here's the documentation - now I only need an implementation :-)
(defun remove-key (keymap key) "In KEYMAP, remove key sequence KEY. Make the event KEY truely undefined in KEYMAP by removing the respective element of KEYMAP (or a sub-keymap) as opposed to merely setting it's binding to nil. There are several ways in which a key can be \"undefined\": (keymap (65 . undefined) ; A (66)) ; B As far as key lookup is concerned A isn't undefined at all, it is bound to the command `undefined' (which doesn't do anything but make some noise). This can be used to override lower-precedence keymaps. B's binding is nil which doesn't constitute a definition but does take precedence over a default binding or a binding in the parent keymap. On the other hand, a binding of nil does _not_ override lower-precedence keymaps; thus, if the local map gives a binding of nil, Emacs uses the binding from the global map. All other events are truly undefined in KEYMAP. Note that in a full keymap all characters without modifiers are always bound to something, the closest these events can get to being undefined is being bound to nil like B above." ...)
Why do I want that? It has already been mentioned in the above doc-string, but here it is again, quoting (elisp)Format of Keymaps (emphasis mine).
When the binding is
nil, it doesn't constitute a definition but it does take precedence over a default binding or a binding in the parent keymap. On the other hand, a binding of
nildoes not override lower-precedence keymaps; thus, if the local map gives a binding of
nil, Emacs uses the binding from the global map.
(define-key map KEY nil) does not remove the entry for
KEY, it just sets the binding to
nil, which "doesn't constitute a definition", but which never-the-less can have an effect.