1

As a result of an answer in a previous question of mine I am trying to translate M-RET in C-u C-RET using the following code:

(define-key key-translation-map (kbd "M-RET") (kbd "C-u C-RET"))

I have used the same code to translate other functions and it worked flawlessly so I don't know what is wrong with it. Does anyone?

Adam
  • 2,407
  • 2
  • 21
  • 38

2 Answers2

9

The input translation maps (input-decode-map, local-function-key-map, function-key-map, key-translation-map) apply only within a key sequence. While you can specify multiple keys in the output of the translation, they'll only be counted towards binding.

For example, consider:

(define-key key-translation-map [f12] [?\C-x ?\C-f ?a])
(define-key key-translation-map [f11] [?\C-u C-return])
(define-key key-translation-map [f10] "abc")

F12 is translated to C-x C-f a. The key sequence C-x C-f is bound to find-file, so pressing F12 will invoke find-file, and the extra a input event will be discarded. Similarly, F11 is translated to C-u C-return, which invokes universal-argument and discards the extraneous event C-return. Pressing F10 invokes the command bound to a, which is self-insert-command; the character c is actually inserted, because self-insert-command inserts the character based on the last input event.

If you want M-RET to be equivalent to C-u C-return in all contexts where M-RET is not bound, then you can bind it in the global keymap. In keymaps other than the translation maps, if the binding for a key is an array of events (such as constructed by kbd) or a string, then the binding is interpreted as a sequence of events to replay — a macro. Note that C-RET isn't normally generated; Ctrl+Return is C-return.

(global-set-key (kbd "M-RET") (kbd "C-u C-<return>"))

Given that C-return is not globally bound by default, it would probably make more sense to define M-RET in the mode where you want to use it. It would be clearer to bind M-RET to a function which does whatever you want — if C-return invokes foo-frobnicate then you might do something like

(defun foo-frobnicate-harder ()
  (interactive)
  (frobnicate t))
(define-key foo-mode-map (kbd "M-RET") 'foo-frobnicate-harder)

If you really want M-RET to be equivalent to C-u C-return in every context, you can stuff events into unread-command-events — see Simulating mouse operations with keyboard for an example.

2

I don't know what is wrong with using key-translation-map (I hope somebody else will chime in). My guess is that it makes Emacs look up the binding of C-u C-RET, not C-RET with a prefix argument.

This alternative seems to work, though:

(global-set-key (kbd "M-RET") (kbd "C-u C-<return>"))
Constantine
  • 9,072
  • 1
  • 34
  • 49
  • Ok that works fine! Thank you. Let's wait for someone to explain why my solution didn't work... – Adam Nov 23 '14 at 00:18