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 ofnil
does not override lower-precedence keymaps; thus, if the local map gives a binding ofnil
, 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.