0

The following code allows me to catch an escape key press. After evaluating the code, pressing ESC will print "Escape pressed", as desired.

Unfortunately, due to the equivalence between ESC and Meta, Meta keys do not function when this keymap is active. Instead, I see messages like

M-f is undefined

I would like to be able to evaluate the following block of code, press M-f, and have it invoke forward-word as usual. Is there any way to achieve this?

(set-transient-map
 `(keymap 
   (27 . ,(lambda () (interactive) (message "Escape pressed"))))
 nil (lambda () (message "Other key pressed")))
6
  • 2
    I use Emacs on OSX in GUI mode and have separated the escape and meta keys: (setq meta-prefix-char nil) I evaluate it first thing when Emacs loads so keymaps defined subsequent thereto are aware of it. As an alternative approach, have a look at something Stefan wrote up for conditional use of the escape key to see if that interests you -- I used it for about a year or so -- the method is similar to how the universal argument works: stackoverflow.com/a/20036348/2112489
    – lawlist
    Oct 27, 2015 at 23:51
  • I don't want set meta-prefix-char to nil globally, I like the standard arrangement. I just would like to have this special behavior temporarily in a transient keymap.
    – killdash9
    Nov 9, 2015 at 21:26
  • My comment above provided two (2) options. Did you try the solution by Stefan in the above-link?
    – lawlist
    Nov 9, 2015 at 21:27
  • What interfaces (GUI/terminal) do you care about? If the answer is all of them, you can't. But if you only care about some, there might be a solution (maybe not with this exact piece of code). Nov 9, 2015 at 22:14
  • @lawlist, I did look at Stefan's solution, but couldn't figure out how to adapt it. Lindydancer was able to make it work by examining (this-command-keys-vector), so I have accepted his solution. Sorry I can't give you partial credit for the pointer.
    – killdash9
    Nov 10, 2015 at 17:08

1 Answer 1

1
+50

After reading the question @lawlist referred to, I put together the following. It seems to work (and I learned something new):

(set-transient-map
 `(keymap
   (27 . (menu-item ""
                    ,(lambda () (interactive) (message "Escape pressed"))
                    :filter
                    ,(lambda (binding)
                       (let ((keys (this-command-keys-vector)))
                         (if (and (> (length keys) 0)
                                  (eq (aref keys 0) 27))
                             binding
                           nil)))))))

Clearly, this is not a menu item, but it seems as though the menu system contains bells and whistles that can be used for normal key bindings as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.