In emacs 24, set-temporary-overlay-map
makes active a keymap which becomes inactivated as soon as the user presses a key which is not defined in that keymap.
I need to inactivate the overlay keymap manually, but no function is provided to do this in particular. I've peeked into the source code:
(defun set-temporary-overlay-map (map &optional keep-pred)
"Set MAP as a temporary keymap taking precedence over most other keymaps.
Note that this does NOT take precedence over the \"overriding\" maps
`overriding-terminal-local-map' and `overriding-local-map' (or the
`keymap' text property). Unlike those maps, if no match for a key is
found in MAP, the normal key lookup sequence then continues.
Normally, MAP is used only once. If the optional argument
KEEP-PRED is t, MAP stays active if a key from MAP is used.
KEEP-PRED can also be a function of no arguments: if it returns
non-nil then MAP stays active."
(let* ((clearfunsym (make-symbol "clear-temporary-overlay-map"))
(overlaysym (make-symbol "t"))
(alist (list (cons overlaysym map)))
(clearfun
;; FIXME: Use lexical-binding.
`(lambda ()
(unless ,(cond ((null keep-pred) nil)
((eq t keep-pred)
`(eq this-command
(lookup-key ',map
(this-command-keys-vector))))
(t `(funcall ',keep-pred)))
(set ',overlaysym nil) ;Just in case.
(remove-hook 'pre-command-hook ',clearfunsym)
(setq emulation-mode-map-alists
(delq ',alist emulation-mode-map-alists))))))
(set overlaysym overlaysym)
(fset clearfunsym clearfun)
(add-hook 'pre-command-hook clearfunsym)
;; FIXME: That's the keymaps with highest precedence, except for
;; the `keymap' text-property ;-(
(push alist emulation-mode-map-alists)))
I gather that the mechanism to inactivate the current overlay keymap is as follows:
- A function
clearfun
is defined to run before every command, checking if the previous command invoked was in the map. - If it was not in the map, the following code is executed:
(Why doesn't this format correctly? Ok, now it does)
(set ',overlaysym nil) ;Just in case.
(remove-hook 'pre-command-hook ',clearfunsym)
(setq emulation-mode-map-alists
(delq ',alist emulation-mode-map-alists))
Thus, what I really want is to execute the code above with the appropriate variables. But this code is part of a closure, and I'm having trouble determining values like overlaysym
, clearfunsym
, alist
inside the closure. I tried looking for clearfunsym
by eval
-ing pre-command-hook
, but strangely nothing is there (except for another unrelated hook).
I tried re-evaluating the function defintion and edebugging it, and I notcied after the (add-hook 'pre-command-hook clearfunsym)
, pre-command-hook
is still nil
, which puzzles me. I will continue digging deeper into the source code, and maybe I will just rewrite my own version of this function to additionally produce a force-clear
function that I can call later, but maybe someone can see a cleaner solution.