Emacs provide a function global-set-key to set your key bindings, this is the most used way to do key binding. For example

(global-set-key (kbd "M-<return>") 'toggle-frame-fullscreen)

This command set Alt + Enter to toggle full screen mode. But the name global-set-key is misleading. Its actually can not guarantee the settings will be "global". If you just write it in you .emacs configuration file. You can not for sure this binding will work in all situations.

The core issues is other mode can overwrite you settings. Each time a minor mode or major mode is activated it may set some key bindings, some of them are your configurations. The problem is this can happen anytime anywhere, you don't know what the minor mode would do with your configurations.

Our goal is setting a key binding that globally overrides and takes precedence over all other bindings for that key. Its hard for some key bindings for example the C-x, C-c, C-m, these bindings are used by many other minor and major modes, they will overwrite yours in unpredictable places.

How to find which mode changed a key binding

For example, in Java major mode, the C-c is a prefix command even it already defined as another command in .emacs. How to find out where the binding is changed?

First show information about current Major mode, in this example , suppose its java, see How to check current modes in Emacs. We will see the java mode map is defined in cc-mode.el. The CC mode will be activated for any file containing C, C++, Objective-C, Java, CORBA IDL , Pike and AWK code. The CC mode defined a lot of key bindings for C-c.

Open this file and search for java-mode-map, this is how a major mode map is named: modename-mode-map.

(defvar java-mode-map ()
  "Keymap used in java-mode buffers.")
(if java-mode-map
  (setq java-mode-map (c-make-inherited-keymap))
  ;; add bindings which are only useful for Java

Turns out is defined in c-make-inherited-keymap. Then it points to c-mode-base-map. Search for "define-key c-mode-base-map" in cc-mode.el to find all the key binding defined in this map. Those all will take effect in java major mode.

So how to bring it back? Here is the solution. Add this to your .emacs files.

(add-hook 'java-mode-hook
  (lambda ()
    (define-key java-mode-map "\C-c" 'kill-ring-save)))

The pattern can be used for any other key bindings, just if you know the right names. Here is another example to bind Enter key to ielm-return function in ielm mode.

(add-hook 'ielm-mode-hook
  (lambda ()
     (define-key ielm-map (kbd "<return>") 'ielm-return)))

One of the problems of this method is its only works for the mode you are dealing with, if any other mode also used the key binding, you need to do it again. Another way is to write your own minor mode and enable it for every buffer. But I won't do it.

At least now you should know what to do to bring it back in case your key binding is overwrite.

Key map inheritance

Sometimes you may not find the key binding in current mode, some key bindings may be inherited from other key maps. For example, the Buffer menu mode which is defined in buff-menu.el.

The C-i is bound to forward-button, but its not defined in Buffer-menu-mode-map. You will not find it in buff-menu.el. So how we find where this key is bound?

First see the definition of Buffer-menu-mode-map:

(defvar Buffer-menu-mode-map
  (let ((map (make-sparse-keymap))
    (menu-map (make-sparse-keymap)))
    (set-keymap-parent map tabulated-list-mode-map)

It inherits from tabulated-list-mode-map. And the definition of tabulated-list-mode-map

(defvar tabulated-list-mode-map
  (let ((map (copy-keymap special-mode-map)))
    (set-keymap-parent map button-buffer-map)

It inherit from another key map , the button-buffer-map, here we will find the binding:

(defvar button-buffer-map
  (let ((map (make-sparse-keymap)))
    (define-key map [?\t] 'forward-button)

The [?\t] means TAB key, this is the key generate whey you press TAB or C-i.


Globally override key binding in Emacs

Global key bindings in Emacs