- Friday, January 05, 2007
Emacs Hack #2: Manage Emacs Instances with gnuserv
If you followed Hack 1, you can now launch Emacs and open files from within the interface. On Windows (and in some other environments), you can also drag files to Emacs from your window manager.
But what if you want to send a file to Emacs from a console session, or via a shortcut? You could invoke Emacs using
runemacs(or create a shortcut to it), but every time you do that you end up with a whole extra instance of Emacs -- a unique operating system process which is independent from any previous instance(s).In some cases, this might be what you want. In the rare case of an Emacs crash, for example, you would not lose any active buffers in the other instances (note that Emacs' auto-save facility would probably mitigate the damage here). Most of the time, however, you'd rather open the file in an existing instance of Emacs. This has a number of advantages:
- Memory is conserved by sharing a single process.
- Shortened start-up time since Emacs is already loaded.
- All open buffers in the shared instance can be quickly accessed from any Emacs frame.
- The buffer list can be used to see every open file across frames, and to perform actions on them.
- Dynamic abbreviations (covered in a future hack) can be sourced from a larger set of files.
- Contention issues (multiple processes accessing the same file) are avoided.
Fortunately, there is a small client / server program called gnuserv which enables us to do just this.
Installing
Installing gnuserv consists of two parts -- some platform-specific binaries (
gnuserv,gnudoit,gnuclientand, on Windows,gnuclientw), and an Emacs Lisp file which we'll load into Emacs. The Lisp code will spawn thegnuservprocess after Emacs has started, listening for received commands ongnuserv's standard output stream.On Windows, the first step is to unpack the ZIP file containing the gnuserv binaries (on Unix and derivatives, simply install the gnuserv package for your distribution). The Windows port is available at Guy Gascoigne - Piggford's site, or attached to this post if the site is unavailable. Extract the binaries to a directory in your
%PATH%(see Hack 1 for some tips on setting up your path), e.g.C:\Program Files\gnuserv.Next, we need to install the Emacs Lisp portion of gnuserv. This involves placing the
gnuserv.elfile (attached to this post) somewhere in Emacs' load path. The easiest way to do this is to copy the file to thesite-lispdirectory, typically located under your base Emacs installation directory (Windows) or at/usr/local/share/emacs/site-lisp(Unix and its derivatives). Files placed here are automatically available to Emacs.Configuring
We've installed all of the pieces necessary for gnuserv, but nothing has really changed in terms of Emacs' behavior. Even though we've added
gnuserv.elto its load path, we still need to instruct Emacs to load the file. We'll do this by adding some initialization code to our.emacsfile (see Hack 1).From within Emacs, type
C-x C-f(that's the control key plus x, followed by the control key plus f -- you can keep the control key pressed the whole time). This invokes Emacs'find-filefunction, which prompts you for a file path to open using the minibuffer (the bottom line in the frame). Emacs will present you with a suggested path. Type~/.emacs, pressTab(Emacs will remove the suggested path as part of its completion algorithm), and then pressEnterto open the file.If you're a Windows user, this path might look strange. The tilde (
~) character is simply a handy shortcut for the folder represented by your%HOME%environment variable, and the forward slash is Emacs' preferred path separator (that is,C:/Usersis preferred toC:\Users). The path syntax for the home directory is not only convenient to type, it also makes your Emacs configuration more portable. For example,~/Desktopalways maps to your Windows desktop, regardless of your login name or other machine-specific details.At this point, you should be staring at a blank buffer. Add the following lines to your
.emacsfile:(require 'gnuserv) (gnuserv-start) (setq gnuserv-frame (selected-frame))
This might look somewhat strange -- it's actually just some simple Elisp which tells Emacs to load and start gnuserv. The first line calls the built-in
requirefunction, which tells Emacs to load gnuserv if it hasn't already done so (this causes Emacs to go findgnuserv.elin our load path). The next line calls a function ingnuserv.el, which starts (or restarts) thegnuservprocess. The last line is an optional customization which tells Emacs that it should open new files from the clients of gnuserv in its startup frame (if you find that you prefer to have multiple Emacs frames, comment this line out by prefixing it with a;character, or delete it entirely).Emacs reads its
.emacsfile and evaluates these lines each time it starts up. You can either restart Emacs now, or pressM-x(M stands for meta, which is typicallyAlt), typeeval-buffer, and pressEnter(this tells Emacs to evaluate the contents of the current buffer without requiring a restart).Launching Emacs
At this point, you should have an Emacs instance running with
gnuservstarted. So far, so good. Now it's time to use the client programs which came with the gnuserv distribution.gnuclient and gnuclientw
The
gnuclientprogram can be used to open a file in a running instance of Emacs. For example, typinggnuclient READMEfrom a console session will open a new buffer for the fileREADME(even if it doesn't yet exist). If Emacs is not currently running, it will automatically be started (at which point it will evaluate its.emacsfile, loading gnuserv).You may notice that when a file is opened using
gnuclient, a message is displayed in Emacs' minibuffer: "When done with a buffer, type C-x #.". You may also have noticed that when you invokegnuclient, it does not immediately exit (that is, you can't continue using the console). What's happening is that thegnuclientprocess is waiting for you to finish working on the file -- when you pressC-x #from within Emacs, thegnuclientprocess exits. This is convenient in many cases -- for example, when editing a Subversion commit message. If the process returned immediately, Subversion would not be able to read the message you typed in to Emacs because there is no longer any connection between the editor and the launcher.In other cases, however, you just want to open a file in Emacs and continue using your console session immediately. In this case, you can use
gnuclientw(Windows only -- on other platforms, usegnuclient -q). This is a variation ofgnuclientwhich returns immediately. It's also compiled as a Windows application, so it's ideal for creating Windows shortcuts (gnuclientopens an unneeded console window in these cases). I typically add a shortcut tognuclientwin%USERPROFILE%\SendToand%USERPROFILE%\Desktop. In practice, I nearly always usegnuclientw(with or without arguments) to start Emacs on Windows (because it's in your path, it can also be executed from the Run dialog). If you find yourself runninggnuclientwa lot when Emacs is already open, try adding a-xoption to "top" the Emacs frame (make it visible if it's hidden).gnudoit
The last (and in this case, the least) client program is
gnudoit, which can be used to evaluate an Elisp form. For example,gnudoit (list-buffers)will open a window within your Emacs frame listing the currently open buffers. This command is deprecated because the same behavior can be achieved usinggnuclient-- on Windows, usegnuclient -e (list-buffers). On other platforms, typegnuclient -batch -eval (list-buffers). In practice, you probably won't be running these forms very often.Attachments
Comments
- Thursday, February 15, 2007 9:29:06 AM by Franck Mesirard
- Thursday, February 22, 2007 7:06:24 PM by DerekHi Franck, did you use the gnuserv.el file attached to this post, or another one?
Also make sure you don't have a gnuserv.elc somewhere in your path from a different version, as that would take precedence (it's probably safe to delete that file if you find it). - Monday, March 26, 2007 8:53:05 AM by KYou might want to mention that there's an equivalent program called emacsclient that does the same thing as gnuserv, before linux users who already have emacsclient start installing unnecessary programs... I at least didn't have to install anything, nor modify .emacs.
- Tuesday, January 08, 2008 4:47:34 PM by Robert InderThanks for this. Followed our instructions, and now I can use the "It's all text" extension to let me edit form fields in Emacs on Windows.
Couldn't have done it without (someone like) you! Thanks for taking the time to set out the steps so clearly.
Robert - Friday, January 18, 2008 4:01:24 PM by MCI really appreciate all this good info for emacs.
I am trying to get gnuserv to run on XP.
I have installed the emacsclientw in the emacs bin directory and put the .el file in the site-lisp directory.
When i start emacs i can see the gnuserv process in process explorer.
When i try to open a file with emacsclientw i get an error
unable to bind to socket
WSAgetlasterror ...
as an aside i have trouble opening files with spaces in their names in them using open with emacs.
i am using emacs 22.1.1
any help would be appreciated
mc - Friday, January 18, 2008 4:15:34 PM by MCPlease ignore my earlier comment.
I was supposed to use gnuclientw not emacsclientw. - Thursday, February 21, 2008 1:16:13 AM by DougGreat blog!
I have the (setq gnuserv-frame (selected-frame)) line in my .emacs file. Each time I run gnuclientw I am getting a new window. When I display the gnuserv-frame variable in emacs it does show selected-frame.
Am using the gnuserv.el from your download.
Any suggestions? - Friday, May 09, 2008 2:24:07 PM by ManishThanks for the compiled gnuserv binaries.
- Thursday, July 08, 2010 7:34:19 AM by GregThe gnuserv.el link appears to be broken. When you click it you get a server-error (excerpt below). The .zip downloads fine
Cheers,
Server Error in '/blog' Application.
Runtime Error
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons)....
I tried to install gnuserv on my windows XP box this morning: I added the binaries to the bin folder of emacs (I also added this folder to my path), and I added the gnuserv.el file to the site-lisp folder. This is what I get when I launch gnuclientw (alone or from the command line with a filename) "error in process filter: Symbol's function definition is void: gnuserv-edit-files-quickly"
Did I miss a step?
Cheers,
Franck