I have the following code in my init.el

(defun my-foo (arg)
  (interactive "^p")
  (message "We got hit")

(defvar my-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-r") 'my-foo) map))

(define-minor-mode my-mode :keymap my-mode-map ())
(defun turn-mode-on () (my-mode +1) )
(define-globalized-minor-mode my-global-mode my-mode turn-mode-on)
(my-global-mode t)

In it, I define a global mode with a keymap so that C-r displays the message "We got hit". If I open Emacs's term and hit C-r in character mode I get the message "We got hit"!

I was under the impression that in character mode Emacs just relays the keys that I press to the shell without interpreting them. Is this not the case? How can I fix this while still maintaining my global keymap?


Minor mode keymaps take precedence over major mode keymaps (i.e. the 'local' keymap). When term-char-mode is called it sets the local keymap to term-raw-map, and your minor mode map therefore has precedence over that.

Note that C-r is not reserved for minor mode use (nor for major mode use), so there's no convention saying that things ought to work the way you're wanting them to work. See C-h i g (elisp)Key Binding Conventions

How can I fix this while still maintaining my global keymap?

To be clear, it's not the global keymap; it's a minor mode keymap.

I would suggest not binding C-r in a minor mode keymap. If you bind C-r in the actual global keymap, you won't encounter this problem.

If you're adamant, then you could perhaps use https://stackoverflow.com/a/22863701 and filter based on (term-in-char-mode)

  • Thanks for taking the time to explain. Things are clearer to me now. – Tohiko Aug 16 '18 at 10:03

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.