Êíèãà: Learning GNU Emacs, 3rd Edition

10.4 Customizing Your Key Bindings

Perhaps the most common things that Emacs users want to customize are the keystrokes that cause commands to run. Keystrokes are associated with commands via key bindings.

Actually, every keystroke runs a command in Emacs. Printable character keys (letters, numerals, punctuation, and spaces) run the self-insert-command, which merely causes the key just pressed to be inserted at the cursor in the current buffer. (You could play a nasty April Fool's joke on a na?ve Emacs user by changing the bindings of their printable characters.)

The default set of key bindings is adequate for most purposes, of course, but there are various cases in which you may want to add or change key bindings. Emacs contains literally hundreds of commands, only some of which have key bindings. As you know, you can access those that don't have bindings by typing M-x command-nameEnter.

If, however, you intend to use an unbound command often, you may want to bind it to a keystroke sequence for convenience. You may want to set special keys, such as arrow, numeric keypad, or function keys, to perform commands you use often.

The other important concept you need to know now is that of a keymap, which is a collection of key bindings. The most basic default key bindings in Emacs are kept in a keymap called global-map. There is also the concept of a local keymap, which is specific to a single buffer. Local keymaps are used to implement commands in modes (like C mode, text mode, shell mode, etc.), and each such mode has its own keymap it installs as the local map when invoked. When you type a key, Emacs first looks it up in the current buffer's local map (if any). If it doesn't find an entry there, it looks in global-map. If an entry for the key is found, its associated command is run.

What happens with commands that are bound to multiple keystrokes, as in C-x k for kill-buffer? The answer is that the keys C-x, Esc, and C-c are actually bound to special internal functions that cause Emacs to wait for another key to be pressed and then to look up that key's binding in another map; they also cause messages like C-x- to appear in the minibuffer if more than a second passes before the next key is pressed. The additional keymaps for C-x and Esc are called ctl-x-map and esc-map,[70] respectively; C-c is reserved for local keymaps associated with modes like C mode and shell mode.

For example, when you type Esc d or M-d, Emacs looks it up in the buffer's local keymap. We will assume it doesn't find an entry there. Then Emacs searches global-map; there it finds an entry for Esc with a special function (called ESC-prefix) that waits for the next keystroke and uses esc-map to determine which command to execute. When you type d, ESC-prefix looks up the entry for d in esc-map, finds kill-word, and runs it.

You can create your own key bindings by adding entries in keymaps (or overriding existing ones). Three functions are available for doing this: define-key, global-set-key, and local-set-key. Their forms are:

(define-key keymap "keystroke" 'command-name)
(global-set-key "keystroke" 'command-name)
(local-set-key "keystroke" 'command-name)

Notice the double quotes around keystroke and the single quote preceding command-name. This is Lisp syntax; for more details, see Chapter 11. The keystroke is one or more characters, either printable or special characters. For the latter, use the conventions in Table 10-2.

Table 10-2. Special character conventions

Special character Definition
C-x C-x (where x is any letter)
C-[ or e Esc
M Meta
C-j or n Newline
C-m or r Enter
C-i or t Tab

Thus, the string abcC-andef is equal to abc, C-a, newline, and def, all concatenated into one string. Note that control characters are case-insensitive—that is, C-A is the same thing as C-a. However, the characters that follow control characters may be case-sensitive; C-ae could be different from C-aE, for example.

The function define-key is the most general because it can be used to bind keys in any keymap. global-set-key binds keys in the global map only; since there is only one global-map, (global-set-key ...) is the same as (define-key global-map ...). The function local-set-key binds keys in the local map of the current buffer; it is useful only for specifying temporary key bindings during an Emacs session.

Here is an example of a simple keyboard customization. Let's say you are writing code in a programming language. You compile it and get error messages that contain the line number of the error, and you want to go to that line in the source file to correct the error.[71] You would want to use the goto-line command, which is not bound by default to any keystroke. Say you want to bind it to C-x l. The command to put into your .emacs file is

(global-set-key "C-xl" 'goto-line)

This binds the l slot in ctl-x-map to the function goto-line globally—that is, in all modes. Alternatively, you can use either of the following:

(define-key global-map "C-xl" 'goto-line)
(define-key ctl-x-map "l" 'goto-line)

These commands have the same effect but aren't really any more efficient or better. And really, you shouldn't have to know that the keymap for C-x is called ctl-x-map. We'll stick to showing the global-set-key approach for the remaining examples, but remember that you have define-key available for situations where setting the global key is not appropriate, such as when adding a mode-specific keystroke.

Other examples of key rebindings include binding C-x ? to help-command and C-h to backward-char. These key rebindings are shown below:

(global-set-key "C-x?" 'help-command)
(global-set-key "C-h" 'backward-char)

Notice that these could also be done as

(define-key ctl-x-map "?" 'help-command)
(define-key global-map "C-h" 'backward-char)

After you put a key binding (or any other code) in your .emacs file, you need to "run" (or evaluate) the file for the change to take effect. The command for this is M-x eval-current-buffer Enter. Even better, you could press C-x C-e, which (as we will see in the next chapter) causes only the single line of Lisp code that your cursor is on to run. If you don't do either of these, the changes won't take effect until the next time you invoke Emacs.

Îãëàâëåíèå êíèãè

Îãëàâëåíèå ñòàòüè/êíèãè

Ãåíåðàöèÿ: 1.127. Çàïðîñîâ Ê ÁÄ/Cache: 3 / 1
ïîäåëèòüñÿ
Ââåðõ Âíèç