0

I would like to define a keyboard shortcut in my .emacs file so that the Break (a.k.a. Pause) key does a C-x C-s C-x C-c. As a warmup, I thought I would try something simpler, so as a test I did this, which seemed almost identical to examples I found by googling:

(global-set-key [C-r] 'next-line)

This doesn't actually work. Control-r is still bound to something else.

For my actual intended mapping, I was imagining something like this:

(global-set-key [pause] ('save-buffer 'save-buffer-kill-terminal))

But I haven't attempted this yet because I couldn't even get the simpler example to work.

How does one find out what name Rmacs gives to a key such as the one labeled Pause/Break on my keyboard? Are the square brackets a lisp thing, or are they just interpreted as literal characters? Is this different from using angle brackets or the kbd function?

7

You ask several related questions, but this is the main one, I think:

How does one find out what name emacs gives to a key such as the one labeled pause/break on my keyboard?

For Emacs's description of a key, use C-h k.

So C-h k, then hit the Pause key. Emacs probably tells you this:

<pause> is undefined

So you now know that Emacs describes that key as <pause>.

Next, how to tell Lisp about that key? Function kbd tells you how to write the Lisp form of Emacs's description of a key. It takes the description as a string argument.

Try M-: (kbd "<pause>"). Emacs tells you this:

[pause]

So [pause] is a Lisp form for that key. So you could do this:

(global-set-key [pause] 'some-command)

But you could also do just this, without bothering to find the Lisp form [pause], i.e., just letting kbd do that in the code:

(global-set-key (kbd "<pause>") 'some-command)

OK. You were already thinking of trying something similar, but what you suggested would have failed, giving you an error message like this:

Debugger entered--Lisp error: (invalid-function (quote save-buffer))

C-h f global-set-key tells you that the second argument must be a command. And it tells you:

COMMAND is the command definition to use; usually it is a symbol naming an interactively-callable function.

You instead would be trying to pass this as the second arg: ('save-buffer 'save-buffer-kill-terminal). That's a list with two elements.

Lisp functions, including commands, evaluate their arguments, and when an argument is a nonempty list it interprets the first element as a function, which it applies to the other elements (after evaluating each one).

So it would try to interpret your 'save-buffers, which is shorthand for the list (quote save-buffers), as a function - in fact as a function that's a command ("interactively-callable").

But it's just a list, not a function.

What you want is a function, which you can define using defun:

(defun my-break-command ()
  "Save buffer, then quit Emacs."
  (interactive)
  (save-buffer)
  (save-buffers-kill-terminal))

(global-set-key (kbd "<pause>") 'my-break-command)

It's the interactive spec, (interactive) that makes the function into a command, i.e., that makes it "interactively-callable".

Alternatively, you could use an anonymous function, instead of defining a named function such as my-break-command:

(global-set-key (kbd "<pause>")
                (lambda ()
                  (interactive)
                  (save-buffer)
                  (save-buffers-kill-terminal)))

(Generally it's better to use named functions for things like this.)


Now what went wrong with your simpler example:

(global-set-key [C-r] 'next-line)

Start from the beginning. How does Emacs describe Control+r? C-h k followed by that tells you:

C-r runs the command isearch-backward...

So it describes that key as just C-r. Function kbd wants a string argument, so what you want is this:

(global-set-key (kbd "C-r") 'next-line)

You can't use [C-r]. Just what does (kbd "C-r") return? It returns the ASCII Control-R character.

You could, in fact, use that control character directly, if you had a way to insert it into a string (which is what kbd expects).

You can do that using Controlq followed by Controlr. (We write that in key descriptions as just C-q C-r.)

Type this: (global-set-key " followed by ControlqControlr followed by: " 'next-line)

You'll see this, but the "^R" will actually be a single character (Control-R), not a ^ character followed by an R character:

(global-set-key "^R" 'next-line)

And that works just as well as (global-set-key (kbd "C-r") 'next-line).


UPDATE

I meant to add some info about how you can ask Emacs, to find out this stuff on your own. Doing that is really one of the best ways to learn Emacs and Emacs Lisp, IMO.

First, the help keys. They all have prefix key C-h. C-h C-h will get you started. But the main ones are C-h m (tell me about the current mode), C-h k (key help, including mouse actions & menu items), C-h v (variable help), and C-h f (function help).

Second, the manuals. C-h r visits the Emacs manual using the Info interface (Info mode). C-h i visits any manual (choose from a menu of available manuals).

Learn first how to use Info, by (what else?) visiting the Info manual. Use C-h i TAB RET or C-h i m in TAB. It's a tiny manual, and it really helps to learn what it has to say.

When you visit a manual, you're in Info mode. And there's a menu-bar Info menu, to help you out. That menu will also teach you some navigation keys.

In any manual, to look for something use the index(es), by hitting i, typing some text, and hitting TAB to match it against index entries. You can also use I, to get a virtual index of links to all index matches for some term - very handy.

Another way to look for something is incremental search: C-s. Keep repeating the same search to look for the same thing across the nodes (pages) of a manual.

But don't let search be your first recourse. Why? Because you can waste a lot of time wading through lots of hits for a search pattern. You're essentially searching blindly and sequentially, which for a large manual can be tedious and, well, not very productive.

Your first, second, ... approach should be i: using the index, not search. There might be 80 zillion search hits for some term/text, or their might be none, but with i you get the benefit of an expert (in Emacs and its manuals) having chosen which parts of the manual are most helpful/relevant for that term.

And the term you're looking for might not even be present in the manual, using the same text you provide, but it might have been added as an index entry.

In addition to i, you can use the table of contents of a manual, that is, the menu that's in its Top node, to navigate. Important concepts are typically listed there as main entry points. E.g., in addition to using i keymap you'll find a top-level menu entry Keymaps, and similarly for buffers, windows, and other Emacs thingies. Both i (index) and table of contents (menu at Top) are far more useful that just searching (C-s) for some common term (e.g. key binding).

When is search helpful? When what you're looking for is hard to find - not in the index, for example.

And if you find this to be the case for something you really think should be in the index, please use M-x report-emacs-bug to suggest that enhancement to Emacs developers.

In particular, the index is the place for alternative ways to describe something important. The terms in which you might be thinking of something might not be those used in the manual to talk about it. Maybe the terms you're thinking in should be indexed, to get readers to the relevant parts of the manual.

Remember: Ask Emacs! It's easy to do. Enjoy.

| improve this answer | |
  • Thanks for the very complete explanation! Turns out that the break key gets caught in every terminal emulator I've tried, but I was able to get this working with the end key. – Ben Crowell Aug 30 at 1:05
  • While simply browsing through hot questions, this is an awesome answer and taught me more about what certain elements mean in Emacs in 5 minutes than I would have discovered on my own in weeks/months. Now I know why I use or (interactive) instead of using it “just because”. Thanks! – Phoenix Aug 30 at 6:21

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.