2008-12-02

binding keys

In quite some of the blog entries we define key bindings (or keyboard shortcuts, as they are called in other places). Key bindings are an essential part of what makes emacs such a productive editor.

Key bindings are discussed in a lot of detail in the Emacs documentation; but what about the very useful little subset we need here for defining keybindings? Let's see…

kbd

When defining key bindings, it's important to understand the emacs-notation for them. Emacs allows for different ways to specify key combinations, but the easiest way is to use the kbd-macro. We're using this macro in the examples below.

To figure out how to find the notation for some key we want to bind, we can use describe-key, or C-h k (Ctrl-h k), and type the key you want to use. Emacs will tell you if it's already bound, and the representation of the key. So, for example, pressing C-h k and then Ctrl-Shift-Return shows the representation for that as <C-S-return>.

binding a function

Once we have figured out the notation for the keybinding we'd like to use, the next step is mapping it to some function. If the function takes no arguments, it's easy (see the examples below). But how to call a function that requires an argument? Suppose,we want to insert the word "hello" whenever we presses C-c h. For that, we need a lambda-function:

(global-set-key (kbd "C-c h") '(lambda () (interactive)(insert "hello")))

Also note the (interactive), to tell emacs that this is an interactive function, because we want to have some output to the current buffer. Lambda-functions require some more explanation, which deserves its own entry…

keymap

So, we have seen how we can figure out a keybinding, and how we can bind it to some function. The final important concept ist that of a keymap, which is a set of keybindings. In emacs, you have multiple keymaps, because in different situations, we'd like to use different (combinations of) keymaps. You can define keybindings that apply throughout emacs (in the global keymap), in specific modes, or in the current buffer (in the local keymap). Let's see how this works in practice.

In this entry we define a global keybinding for toggling full-screen mode; in .emacs:

(global-set-key (kbd "<f11>") 'djcb-full-screen-toggle)

Because there are so many functions available in emacs, it is impossible to have global key bindings for everything that are still easy to remember (a keybinding you have to look up is rather useless). Also, many bindings only make sense in a particular mode.

Because of that, we can have mode-specific keybindings. For example, the command ff-find-other-file (to jump from .c-file to .h-file and vice-versa, as mentioned here), is only useful in c-mode (and derivatives), so:

(define-key c-mode-map  (kbd "C-c o")    'ff-find-other-file)

Finally, to set a key only for the current buffer, we could use:

(local-set-key (kbd "<f11>")  'djcb-full-screen-toggle)

But note that usually, all buffers in a certain mode share their keymap. This means that adding a keybinding to the keymap for the current buffer will likely add it to all buffers of that type.

Conclusion

This should be enough to get you started; the big challenge now is to come up with a set of intuitive key bindings for your most-used function. That is not so easy…

4 comments:

Anonymous said...

Nice post!
Just one tip:
If you want to find out the current active keymap in a given situation, like in the gnus group buffer, use this command:

M-: (mapcar (lambda(x)(car(rassq x minor-mode-map-alist)))(current-minor-mode-maps))

hth

ahck said...

Hi, Its a nice blog to learn emacs.
I found a typo , 1) in kbd section C-h k is mistyped as C-h g

djcb said...

@ahck: thanks, fixed.

Anonymous said...

Very helpful. Thanks!