elisp: Changing Key Bindings

 
 21.12 Changing Key Bindings
 ===========================
 
 The way to rebind a key is to change its entry in a keymap.  If you
 change a binding in the global keymap, the change is effective in all
 buffers (though it has no direct effect in buffers that shadow the
 global binding with a local one).  If you change the current buffer’s
 local map, that usually affects all buffers using the same major mode.
 The ‘global-set-key’ and ‘local-set-key’ functions are convenient
 interfaces for these operations (SeeKey Binding Commands).  You can
 also use ‘define-key’, a more general function; then you must explicitly
 specify the map to change.
 
    When choosing the key sequences for Lisp programs to rebind, please
 follow the Emacs conventions for use of various keys (SeeKey Binding
 Conventions).
 
    In writing the key sequence to rebind, it is good to use the special
 escape sequences for control and meta characters (SeeString Type).
 The syntax ‘\C-’ means that the following character is a control
 character and ‘\M-’ means that the following character is a meta
 character.  Thus, the string ‘"\M-x"’ is read as containing a single
 ‘M-x’, ‘"\C-f"’ is read as containing a single ‘C-f’, and ‘"\M-\C-x"’
 and ‘"\C-\M-x"’ are both read as containing a single ‘C-M-x’.  You can
 also use this escape syntax in vectors, as well as others that aren’t
 allowed in strings; one example is ‘[?\C-\H-x home]’.  SeeCharacter
 Type.
 
    The key definition and lookup functions accept an alternate syntax
 for event types in a key sequence that is a vector: you can use a list
 containing modifier names plus one base event (a character or function
 key name).  For example, ‘(control ?a)’ is equivalent to ‘?\C-a’ and
 ‘(hyper control left)’ is equivalent to ‘C-H-left’.  One advantage of
 such lists is that the precise numeric codes for the modifier bits don’t
 appear in compiled files.
 
    The functions below signal an error if KEYMAP is not a keymap, or if
 KEY is not a string or vector representing a key sequence.  You can use
 event types (symbols) as shorthand for events that are lists.  The ‘kbd’
 function (SeeKey Sequences) is a convenient way to specify the key
 sequence.
 
  -- Function: define-key keymap key binding
      This function sets the binding for KEY in KEYMAP.  (If KEY is more
      than one event long, the change is actually made in another keymap
      reached from KEYMAP.)  The argument BINDING can be any Lisp object,
      but only certain types are meaningful.  (For a list of meaningful
      types, see SeeKey Lookup.)  The value returned by ‘define-key’
      is BINDING.
 
      If KEY is ‘[t]’, this sets the default binding in KEYMAP.  When an
      event has no binding of its own, the Emacs command loop uses the
      keymap’s default binding, if there is one.
 
      Every prefix of KEY must be a prefix key (i.e., bound to a keymap)
      or undefined; otherwise an error is signaled.  If some prefix of
      KEY is undefined, then ‘define-key’ defines it as a prefix key so
      that the rest of KEY can be defined as specified.
 
      If there was previously no binding for KEY in KEYMAP, the new
      binding is added at the beginning of KEYMAP.  The order of bindings
      in a keymap makes no difference for keyboard input, but it does
      matter for menu keymaps (SeeMenu Keymaps).
 
    This example creates a sparse keymap and makes a number of bindings
 in it:
 
      (setq map (make-sparse-keymap))
          ⇒ (keymap)
      (define-key map "\C-f" 'forward-char)
          ⇒ forward-char
      map
          ⇒ (keymap (6 . forward-char))
 
      ;; Build sparse submap for ‘C-x’ and bind ‘f’ in that.
      (define-key map (kbd "C-x f") 'forward-word)
          ⇒ forward-word
      map
      ⇒ (keymap
          (24 keymap                ; C-x
              (102 . forward-word)) ;      f
          (6 . forward-char))       ; C-f
 
      ;; Bind ‘C-p’ to the ‘ctl-x-map’.
      (define-key map (kbd "C-p") ctl-x-map)
      ;; ctl-x-map
      ⇒ [nil ... find-file ... backward-kill-sentence]
 
      ;; Bind ‘C-f’ to ‘foo’ in the ‘ctl-x-map’.
      (define-key map (kbd "C-p C-f") 'foo)
      ⇒ 'foo
      map
      ⇒ (keymap     ; Note ‘foo’ in ‘ctl-x-map’.
          (16 keymap [nil ... foo ... backward-kill-sentence])
          (24 keymap
              (102 . forward-word))
          (6 . forward-char))
 
 Note that storing a new binding for ‘C-p C-f’ actually works by changing
 an entry in ‘ctl-x-map’, and this has the effect of changing the
 bindings of both ‘C-p C-f’ and ‘C-x C-f’ in the default global map.
 
    The function ‘substitute-key-definition’ scans a keymap for keys that
 have a certain binding and rebinds them with a different binding.
 Another feature which is cleaner and can often produce the same results
 is to remap one command into another (SeeRemapping Commands).
 
  -- Function: substitute-key-definition olddef newdef keymap &optional
           oldmap
      This function replaces OLDDEF with NEWDEF for any keys in KEYMAP
      that were bound to OLDDEF.  In other words, OLDDEF is replaced with
      NEWDEF wherever it appears.  The function returns ‘nil’.
 
      For example, this redefines ‘C-x C-f’, if you do it in an Emacs
      with standard bindings:
 
           (substitute-key-definition
            'find-file 'find-file-read-only (current-global-map))
 
      If OLDMAP is non-‘nil’, that changes the behavior of
      ‘substitute-key-definition’: the bindings in OLDMAP determine which
      keys to rebind.  The rebindings still happen in KEYMAP, not in
      OLDMAP.  Thus, you can change one map under the control of the
      bindings in another.  For example,
 
           (substitute-key-definition
             'delete-backward-char 'my-funny-delete
             my-map global-map)
 
      puts the special deletion command in ‘my-map’ for whichever keys
      are globally bound to the standard deletion command.
 
      Here is an example showing a keymap before and after substitution:
 
           (setq map '(keymap
                       (?1 . olddef-1)
                       (?2 . olddef-2)
                       (?3 . olddef-1)))
           ⇒ (keymap (49 . olddef-1) (50 . olddef-2) (51 . olddef-1))
 
           (substitute-key-definition 'olddef-1 'newdef map)
           ⇒ nil
           map
           ⇒ (keymap (49 . newdef) (50 . olddef-2) (51 . newdef))
 
  -- Function: suppress-keymap keymap &optional nodigits
      This function changes the contents of the full keymap KEYMAP by
      remapping ‘self-insert-command’ to the command ‘undefined’ (See
      Remapping Commands).  This has the effect of undefining all
      printing characters, thus making ordinary insertion of text
      impossible.  ‘suppress-keymap’ returns ‘nil’.
 
      If NODIGITS is ‘nil’, then ‘suppress-keymap’ defines digits to run
      ‘digit-argument’, and ‘-’ to run ‘negative-argument’.  Otherwise it
      makes them undefined like the rest of the printing characters.
 
      The ‘suppress-keymap’ function does not make it impossible to
      modify a buffer, as it does not suppress commands such as ‘yank’
      and ‘quoted-insert’.  To prevent any modification of a buffer, make
      it read-only (SeeRead Only Buffers).
 
      Since this function modifies KEYMAP, you would normally use it on a
      newly created keymap.  Operating on an existing keymap that is used
      for some other purpose is likely to cause trouble; for example,
      suppressing ‘global-map’ would make it impossible to use most of
      Emacs.
 
      This function can be used to initialize the local keymap of a major
      mode for which insertion of text is not desirable.  But usually
      Major Modes::); then its keymap will automatically inherit from
      ‘special-mode-map’, which is already suppressed.  Here is how
      ‘special-mode-map’ is defined:
 
           (defvar special-mode-map
             (let ((map (make-sparse-keymap)))
               (suppress-keymap map)
               (define-key map "q" 'quit-window)
               ...
               map))