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")))
killdash9
  • 179
  • 8
  • 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: http://stackoverflow.com/a/20036348/2112489 – lawlist Oct 27 '15 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 09 '15 at 21:26
  • My comment above provided two (2) options. Did you try the solution by Stefan in the above-link? – lawlist Nov 09 '15 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). – Gilles 'SO- stop being evil' Nov 09 '15 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 '15 at 17:08
  • @killdash9, I agree, without lawlists pointer I would not have been able to come up with the solution. – Lindydancer Nov 10 '15 at 18:10

1 Answers1

1

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.

Lindydancer
  • 6,095
  • 1
  • 13
  • 25