18

I'm new to emacs, and have a rookie question. I can bind a key to a particular function by (global-set-key (kbd "C-c a b c") 'some-command), where some-command is a function. How can I invoke two functions (say some-command and some-other-command) with one key binding? Thanks a lot!

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Ying Xiong
  • 4,578
  • 8
  • 33
  • 69

4 Answers4

30

You can define your own function which call the two functions, and bind the key to your own function. Or use a simple lambda:

(global-set-key (kbd "C-c a b c") (lambda () (interactive) (some-command) (some-other-command)))
phils
  • 71,335
  • 11
  • 153
  • 198
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • @Stefan Will you please explain why not quote lambdas? – songyuanyao Dec 03 '14 at 03:27
  • This works great. Thanks! I have the same question about quote though --- I usually also quote the lambdas, and would like to know why not to. – Ying Xiong Dec 03 '14 at 03:36
  • 2
    @songyuanyao: Because `'(...)` is a *list*, not a *function*. See http://stackoverflow.com/questions/16801396/when-should-emacs-function-syntax-be-used/16802304#16802304 – Stefan Dec 03 '14 at 04:20
  • Also, quoting lambdas hurts byte compilation. – Nick McCurdy Jan 20 '17 at 09:48
  • 1
    Can I follow inputs after a command. For example: `find-name-dired)` , `enter` , `*py` ,`t`, `Q` .. and continue from this point @songyuanyao – alper Feb 10 '20 at 23:19
25

I recommend never binding lambda expressions to keys, for the simple reason that when you ask Emacs what that key does, it will end up telling you something like this (to use the accepted code, when byte-compiled, as an example):

C-c a b c runs the command #[nil "\300 \210\301 \207" [some-command
some-other-command] 1 nil nil], which is an interactive compiled Lisp
function.

It is bound to C-c a b c.

(anonymous)

Not documented.

If you never byte-compile your code, it's less cryptic, but still unformatted:

C-c a b c runs the command (lambda nil (interactive) (some-command)
(some-other-command)), which is an interactive Lisp function.

Which, while still readable in the case of a small function like this, gets rapidly incomprehensible for larger functions.

Compared with:

C-c a b c runs the command my-run-some-commands, which is an
interactive compiled Lisp function in `foo.el'.

It is bound to C-c a b c.

(my-run-some-commands)

Run `some-command' and `some-other-command' in sequence.

Which you get if you name the function (which encourages you to document it more than an anonymous function does).

(defun my-run-some-commands ()
  "Run `some-command' and `some-other-command' in sequence."
  (interactive)
  (some-command)
  (some-other-command))

(global-set-key (kbd "C-c a b c") 'my-run-some-commands)

Finally, as abo-abo points out, this also means you can easily visit the definition of that function at any time, to view or edit/re-evaluate the code, either by following the link provided in the help buffer (to foo.el in my example), or by using M-x find-function (enter the name of the function), or M-x find-function-on-key (type the key sequence it's bound to).

phils
  • 71,335
  • 11
  • 153
  • 198
1

Define a command that calls each of the functions (commands) that you want, conditionally. Use the prefix arg to distinguish which to call. So if the new, dispatching command is bound to, say, C-o, then C-u C-o would call one of the functions and C-o (without a prefix arg) would call the other.

You will want to do C-h f interactive, to see how to define a command that recognizes a prefix argument etc. Consult the Elisp manual also - use i interactive to find where it teaches this.

This is an easy and fun exercise. Learning to define your own simple commands is a good way to start to talk to Emacs in its own language.

Drew
  • 29,895
  • 7
  • 74
  • 104
0

You can define another functon with defunin which you invoke the others with funcallorapplyso, when you call this third function (which you can also bind) it will invoke the others.

nsm
  • 319
  • 1
  • 9