2009-02-11

emacs --daemon

Emacs23 has gone in pre-test. As I mentioned before, there are a lot of improvements, and there's little reason not to migrate to this new version. YMMV, of course. As always, you can see all the news with C-h n (Ctrl-H and then n) -- but obviously you need emacs 23 to see the news for emacs 23.

There's even an easter egg, as Giorgos Keramidas notes: M-x butterfly, inspired by xkcd...

A more useful new feature that I'll discuss here, is emacs --daemon. Since many versions, you can set up emacs as an emacs-server. The idea is that you start one emacs instance (the 'server'), and you can then use emacsclient to quickly pop up a new emacs-frame (window). This new frame is not a new emacs instance, it's just a new frame (window) for the already-running emacs. The nice thing is that emacsclient is very quick - it doesn't need to parse all the startup packages or your 5000-line .emacs. You could activate it by putting (server-start) in your .emacs, or calling M-x server-start. I've been happily using that for years with mutt.

Those were happy years. Still, things could be better. Emacs-client/server had its limitations: first, an emacs could have graphical or console (tty) clients, but not both at the same time. Second, you always needed to start emacs in the foreground before you could use emacslient.

Both of these limitations have gone now -- hurray! You simply start emacs as:

 $ emacs --daemon
and it starts running in the background. After that, you can start emacs client frames (windows) using:
 $ emacsclient -c
. This will give you a graphical version when running X, or a terminal (console) version otherwise. If you want a terminal version even in windows-mode, use:
 $ emacsclient -t
. If you don't want the controlling terminal to wait for the emacsclient to finish, you can add the -n argument, so:
 $ emacsclient -c -n
and you can even specify an alternate editor if emacs is not yet running, so:
  $ emacsclient -c -a nano    # if all else fails...
Of course, you can also start emacs itself as the 'alternate'.

Now, my new way to run emacs is a follows:

  1. I start emacs in the background (as daemon) when logging into X; this can be done automatically by adding to make emacs --daemon to your list of startup-programs. In GNOME, this can be set through the Preferences/Sessions/Startup Programs-menu. I am sure other environments have something similar. Alternatively, you could put emacs --daemon & in ~/.xinitrc.
  2. I fire up emacs frames (windows) with emacsclient -c (or emacsclient -t to run it in a console);
  3. That's it!
If you want to terminate emacs outside emacs, you'll have to kill it by hand (AFAIK) -- something like
 $ pkill -TERM -u $USER emacs
Make sure you have no unsaved data, and no other emacsen running...

You also might want to set some influential environment variables in your .~/.bashrc, ~/.zshenv, ..., so other programs will automatically use an emacsclient when available; e.g.,

   EDITOR="emacsclient -c"
   VISUAL="emacsclient -c"
  
With emacs --daemon there's no longer any need to use vi for quick-editing some file. In other words: alias vi="emacsclient -c"...

28 comments:

7ocb said...

when creating new windows of emacs with emacsclient, this windows will behave as new instances of emacs or just as new frames, created with C-x 5 2 ?
I mean this window will share buffer list or not?

Zung! said...

@7ocb: the new frame shares the buffer list with other open frames

@djcb: Nice summary. Thanks.

I use the following to kill a running emacs server (version 22):

emacsclient --eval "(progn (save-some-buffers t t) (kill-emacs))"

djcb said...

@Zung!: ah, that's clever.

Anonymous said...

Don't forget the ALTERNATE_EDITOR environment variable. I haven't yet tried 23, but perhaps one could try

ALTERNATE_EDITOR='emacs --daemon; emacsclient -c'

?

Saint Aardvark said...

Dude! I didn't know about the -c and -t options. Thanks!

Jared said...

That sounds like a nice addition although I don't think it will help with my (perhaps unusual) requirement to have multiple emacs instances with a different environment. I propose a different solution: launching a cutdown emacs
here that allows me to avoid using vi.

Zed Lopez said...

Within emacsclient, C-x C-c is mapped to save-buffers-kill-terminal. You can still M-x kill-emacs or M-x save-buffers-kill-emacs.

I have this script as /usr/local/bin/editor:

#!/bin/bash
if [ -z $DISPLAY ] ; then
OPT="-t"
else
OPT="-c"
fi

emacsclient $OPT "$*" 2>/dev/null || (
(emacs --daemon)
sleep 2
emacsclient $OPT "$*")

Sadly, even on a modern, not overloaded machine, I needed sleep 2 -- sleep 1 could be too short.

djcb said...

@Jared: emacs --daemon creates a unix socket (something like /tmp/emacs$uid/server), and the client connects to that.

emacsclient has the --socket-name option to connect to any socket.

So, if you could start *another* emacs --daemon, and have the emacsclients connect to that...

Unfortunately, that does not seem possible at this time. There seems to be no (documented) way to have emacs --daemon use another socket. *sigh*

@Zed Lopez: the DISPLAY check is not necessary; -c will fallback to terminal if there's no DISPLAY.

Also, I think the ALTERNATE_EDITOR solution as mentioned by Anonymous solves this.

Zed Lopez said...

the DISPLAY check is not necessary; -c will fallback to terminal if there's no DISPLAY.

Ah, thanks.

I think the ALTERNATE_EDITOR solution as mentioned by Anonymous solves this.

Nope. Tried it. It's calling execvp on ALTERNATE_EDITOR. But maybe some bash -c phrase would work and I just didn't get all the relevant shell-escaping working.

But with this as /usr/local/bin/editor2:
#!/bin/bash
emacs --daemon
sleep 2
emacsclient -c "$*"

then /usr/local/bin/editor can be just:
#!/bin/bash
emacsclient -c -a /usr/local/bin/editor2 "$*"

This has an advantage over my original that emacs --daemon will only be run if emacsclient specifically has a failed to connect error.

SETH said...

Hrrm, since upgrading, any frame I create using emasclicent doesn't have the correct background. And I get errors in about unspecified-bg in the messages buffer.

Any ideas?

djcb said...

@SETH: hmmm... i've seen that problem - the easiest way to solve it might be to use 'color-theme'; it works correctly in the other frames.

SETH said...

@djcb: Thanks, that seems to have done the trick. Very frustrating problem.

Please keep up the great posts.

David Biesack said...

I've used variations of emacsclient - gnuserv, gnuclient, gnudoit - for years. I especially like gnudoit because you can pass a lisp expression on the command line for Emacs to evaluate. I also have a modified version of gnuclient that does not wait for you to close the buffer. Is there a -daemon version that supports gnudoit and/or gnuclient like operations ?

djcb said...

@David Biesack: the emacsclient for Emacs 22 and 23 should work. For not-waiting, use '-n', for evaluating elisp, use '-e'.

Anonymous said...

@Zed: try this:

emacsclient -a ""

This will automatically start the server, if it's not running...

M.

Anonymous said...

Is it possible to have every emacsclient instance more independent from the others? Mainly I would like the emacsclient instances to have their own buffer list.

Anonymous said...

I don't start Emacs daemon automatically with my desktop. I have just configured everywhere that my emacsclient starts with one of these:

emacsclient -c -a ""
emacsclient -c -n -a ""
emacsclient -t -a ""

It depends on the application etc. which one of those I use. Then Emacs daemon is started the first time I need it.

Elias Pipping said...

mg[1] is ideal for those "vi tasks" for which emacs is too big

[1] http://www.han.dds.nl/software/mg/

Luke Hoersten said...

Hmm. Doesn't seem to be using my color theme (like SETH said) even though I'm using 'color-theme'. Any other suggestions? Also, have you found a way to start multiple daemons yet?

RishiD said...

Anyone having a problem when trying to start emacsclient -c, the menu shows up in a straight line vertically instead of normally horizontally? I am using Cygwin, Emacs 23.1, and Xming as my X server.

fengshaun said...

I have a problem. After I start the emacs daemon using the --daemon option, when I start emacsclient with -c option, an emacs frame just flickers and goes away in a fraction of a second and emacsclient exits. The only output is "Waiting for Emacs..." Does anyone have any idea how to solve this? the -t option works without a problem!

Jérémie said...

I also have a problem: I want emacs as a shortcut in Gnome, but putting "/usr/bin/emacsclient -c" doesn't seem to cut it, as nothing happens... Ideas?

djcb said...

@Jérémie: first, I'd verify if that seem line works on the command line. Also
note that e.g. Ubuntu come with menu entries for emacsclient already, which
you can drag to your desktop or wherever.

Anonymous said...

@Jérémie: had the same problem under ubuntu 9.10 with the packaged emacs23 it all started working perfectly once i left out the "-c" option. this is fine for me since i have no need to differentiate between terminal and gui use.

my editor command is: "emacsclient -n -a emacs %s"

freegnu said...

I used update-alternatives to create an entry for emacsclient as an alternative for editor. I then set emacsclient as the default editor and set EDITOR="editor" in my .bashrc in order to get git on board with the change.
I also have emacsclient -c -a '' bound to the global shortcut Super-C. Since emacs makes a better terminal and screen than all the other "consoles" and terminals.

Anonymous said...

Since emacs --daemon doesn't create any frame my frame-related configuration of .emacs is ignored when I lauch emacsclient -c (for example my set-default-font is ignored loading defaults)

I mean no override configuration loaded on the emacsclient but it works well with just "emacs", do you have that problem?

Anonymous said...

Thanks for the nice tutorial. But my emacsclient has the -s option which allows me to define a different socket to connect to.

Anonymous said...

@Anonymous
Check:
(set-face-font 'default '"font name")
Font name:
M-x describe-font