4

I have a keymap which uses [t] to bind a default command which should be executed if any key not bound in the map is pressed. This is described in the documentation of define-key and it works for the most part. BUT if I bind a Meta combination in that map, any other Meta key combination will skip this default command from there on.

Example Code to illustrate the problem:

(let ((map (make-sparse-keymap)))
  (define-key map (kbd "M-a") 'some-command)
  (define-key map [t] (lambda ()
                        (interactive)
                        (message "this will be skipped by Meta combinations")))
  (set-transient-map map))  

I want to be able to bind a command to a Meta combination, but let other Meta combinations still run the default.

How to do that?

4

For historical reasons, M-key and ESC key are mostly treated as equivalent. Physical terminals, and terminal emulators, communicate with the application by sending characters, and there's no character for “meta character” (whereas ASCII includes control characters corresponding to Ctrl+letter and a few punctuation characters). Two conventions exist to encode Meta+character: set the 8th bit on character (which is only applicable with a 7-bit character set), or send the ESC character followed by the character from the keychord.

Graphical terminals send keychords to the application, so they can encode Meta+character and more generally Meta+key just fine. However, to preserve compatibility with text terminals, Emacs internally translates Meta+key to ESC key (or more generally meta-prefix-char key but I suspect that changing meta-prefix-char would break a lot of modes).

Thus, if you're defining a fallback binding in a keymap, include that binding for ESC as well.

(let ((map (make-sparse-keymap)))
  (define-key map [?\e t] (lambda ()
             (interactive)
             (message "this will be triggered by Meta combinations")))
  (define-key map (kbd "M-a") 'some-command)
  (define-key map [t] (lambda ()
                        (interactive)
                        (message "this will be skipped by Meta combinations")))
  (set-transient-map map))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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