Emacs daemon on macOS
How many packages do you load at Emacs startup? Me? Lots. I’m not a big fan of hanging around for 8 whole seconds for them to load when I want to edit a file. So, what are the options?
- Run Emacs at Login. Get a coffee while it loads.
- Run the Emacs daemon as a LaunchAgent.
- I think I’ll talk about that one. 🙂
To run the Emacs daemon (day-mon, btw. A friendly spirit.) at login, you need to create a plist in ~/Library/LaunchAgents. You can try to find the Apple documentation on the necessary XML to use, or you can copy the following code. I named my file gnu.emacs.daemon.plist. I know; how original. Just change the UserName key field of course.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>gnu.emacs.daemon</string> <key>ProgramArguments</key> <array> <string>/Applications/Emacs.app/Contents/MacOS/Emacs</string> <string>--daemon</string> </array> <key>RunAtLoad</key> <true/> <key>UserName</key> <string>genedelisa</string> </dict> </plist> |
That’s it. Now log out, then log in. Or you can face Cupertino and issue the following incantation.
launchctl load -w ~/Library/LaunchAgents/gnu.emacs.daemon.plist
(you can change load to unload then load again if you need to debug)
How do you know it did anything? The daemon creates a socket file named emacs[your uid]/server. You can do a ps/grep cha cha if you want. I check Emacs’s (say that 3 times fast) open files. (List the files opened by Emacs, then grep for “server”. Then squeeze all the blanks into one so cut works, then get field 8 – the file name)
lsof -c Emacs | grep server | tr -s “[:blank:]” | cut -d’ ‘ -f8
You should get back the socket file. Mine looked like this just now. Yours might have a different path and user uid (mine is 501. See yours by typing id in iterm)
/var/folders/ff/3mb9tb5s167_hwm9sn3_c5dr0000gn/T/emacs501/server
Now what? Use emacsclient.
In my zsh setup files I created an alias to it. You can type the whole path out if you don’t want to bother with silly things like aliases.
alias emacsclient=/Applications/Emacs.app/Contents/MacOS/bin/emacsclient
Now you’e set. Run emacsclient and specify the socket file on the command line.
emacsclient –create-frame –socket-name=/var/folders/ff/3mb9tb5s167_hwm9sn3_c5dr0000gn/T/emacs501/server
Woo hoo!
I’m not telling you what to do, but I wrote a shell script to get the socket file name then launch emacsclient.
Nice, thanks!
Why keeping track of the Emacs daemon socket, though? Are you running more than one daemons in parallel?
Depending on your inits, startup might take a while. So, I start the daemon at my login.
Then I use emacsclient to connect to the emacs server. It starts almost immediately.