2

My Emacs translates C-m as RET like here: https://stackoverflow.com/questions/7235381/unbind-c-m-from-ret. I'd like to use C-m though, and I have a multilevel keyboard-layout in which <kp-enter> is much more convenient to reach than RET anyway. So I'd like to continue using <kp-enter> as it is now while rebinding C-m/RET. Is there a way to do this without having to manually rebind <kp-enter> to any function RET fulfills in any mode? For instance, could I rebind C-m to some other key combination while leaving <kp-enter> to point to where C-m was?

2 Answers 2

1

Going around re-binding all the bindings of RET would be tedious, so you can just leave them alone, and translate C-m to a different key, and then bind that. Of course that still leaves RET and <kp-enter> the same:

(key-translate "C-m" "C-z")
(keymap-local-set "C-z" (key-parse "hello world"))

In versions of Emacs prior to emacs-29 key-translate and keymap-local-set are not available, so do the following instead:

(keyboard-translate ?\C-m ?\C-z)
(local-set-key (kbd "C-z") "helloworld")
2
2

By default, <kp-enter> runs [13] (see function-key-map) which equals a single C-m.

So,

Is there a way to do this without having to manually rebind <kp-enter> to any function RET fulfills in any mode?

I'm afraid there's no way to do that.


could I rebind C-m to some other key combination while leaving <kp-enter> to point to where C-m was?

Yes. This may help:
(Thanks for @PRouleau's comment. Based on it, I rewrote the code to be more thoughtful.)

;; Take `ielm-mode' for example.
(add-hook 'ielm-mode-hook
          (letrec ((RET-rebinder
                    (lambda ()
                      ;; Before you rebind "<kp-enter>",
                      ;; evaluate the following expression:
                      (keymap-local-set "<kp-enter>"
                                        (if-let ((local-ret (keymap-local-lookup "C-m")))
                                            ;; `ielm-mode' binds "C-m" to a useful command,
                                            ;; you probably want it:
                                            local-ret  
                                          (keymap-global-lookup "C-m")))
                      ;; Then do rebinding:
                      (keymap-local-set "C-m" 'previous-line)
                      ;; The above expressions need to be executed only once.
                      (remove-hook 'ielm-mode-hook RET-rebinder))))
            RET-rebinder))
2
  • 1
    Note that (key-binding [13]) is major-mode specific so the binding you'd globally assign to "<kp-enter>" would be the mode-specific binding of [13] of the active major mode when the command is evaluated.
    – PRouleau
    Oct 7, 2023 at 16:41
  • 1
    This is the kind of thing that's best done in a with-eval-after-load expression, then you don't need to do the remove-hook
    – rpluim
    Oct 9, 2023 at 16:15

Your Answer

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

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