Yi Tang Data Science and Emacs

Setup Emacs Servers in MacOS

I switched to MacOS last year for editing home gym videos. I was and am still amazed by how fast the M1 chip is for exporting 4K videos. The MacOS also enriched the Emacs experience which makes it deserve another blog post.

So I have been slowly adapting my Emacs configuration and workflow to MacOS. One of the changes is the Emacs server.

The goal is to have fully loaded Emacs instances running all the time so I can use them at any time and anywhere, in Terminal or Spotlight. They are initiated upon login. In cases of Emacs crashes (it is rare but more often than I like) or I have to stop them because I messed up the configuration, they restart automatically.

Emacs Server Configuration

I have this setup in Linux using systemd, as in my previous blog post.

In MacOS, the launchctl is the service manager. It provides a user interface to list, start and stop services.

To build an Emacs server, create a plist file in ~/Library/LaunchAgents folder. In my case, I named it emacs_work.plist.

 1: # cat ~/library/LaunchAgents/emacs_work.plist
 2: <plist version="1.0">
 3:   <dict>
 4:     <key>Label</key>
 5:     <string>emacs_work</string>
 6:     <key>ProgramArguments</key>
 7:     <array>
 8:       <string>/opt/homebrew/opt/emacs-plus@29/bin/emacs</string>
 9:       <string>--fg-daemon=work</string>
10:     </array>
11:     <key>RunAtLoad</key>
12:     <true/>
13:     <key>KeepAlive</key>
14:     <true/>    
15:     <key>StandardOutPath</key>
16:     <string>/tmp/emacs_work.stdout.log</string>
17:     <key>StandardErrorPath</key>
18:     <string>/tmp/emacs_work.stderr.log</string>
19:   </dict>
20: </plist>

It is an extension of Emacs Plus' plist file. I made a few changes for running two Emacs servers: one for work (data sciences, research) and one for personal usage (GTD, books). Taking the "work" server as an example, the important attributes of the plist configuration file are:

Line 5
The unique service name to launchctl
Line 8
The full path to the Emacs program. In my case, it is /opt/homebrew/opt/emacs-plus@29/bin/emacs
Line 9
The "--fg-daemon" option set the Emacs server name to "work". Later I can connect to this server by specifying "-s=work" option to emacsclient
Line 13
The KeepAlive is set to true so it keeps trying to restart the server in case of failures
Line 16 and 18
The location of standard output and error files. They are used to debug. Occasionally I have to check those files to see why Emacs servers stopped working, usually because of me introducing bugs in my .emacs.d.

With the updated plist files in place, I start the Emacs servers with

launchctl load -w ~/Library/LaunchAgents/emacs_work.plist
launchctl load -w ~/Library/LaunchAgents/emacs_org.plist

The launchctl list | grep -i emacs is a handy snippet that lists the status of the services whose name includes "emacs". The output I have right now is

PID Exit Code Server ID
1757 0 emacs_org
56696 0 emacs_work

It shows both Emacs servers are running fine with exit code 0.

Launch Emacs GUI in Terminal

I can now open a Emacs GUI and connect it to the "work" Emacs server by running emacsclient -c -s work &. The -c option

Launch Emacs GUI in Spotlight

In MacOS, I found it is natural to open applications using Spotlight, for example, type ⌘ + space to invoke Spotlight, put "work" in the search bar, it narrows the search down to "emacs_work" application, and hit return to finalise the search. It achieves the same thing as the command above but can be used anywhere.

I uploaded a demo video on YouTube to show it in action. You might want to watch it at 0.5x speed because I typed so fast...

To implement this shortcut, open "Automator" application, start a new "Application", select "Run Shell Script", and paste the following bash code

/opt/homebrew/opt/emacs-plus@29/bin/emacsclient \
    --no-wait \
    --quiet \
    --suppress-output \
    --create-frame -s work \
    "$@"

and save it as emacsclient_work in the ~/Application folder.

Essentially, the bash script above is wrapped up as a MacOS application, named emacsclient_work and the Spotlight searches the application folder by default.

If you have any questions or comments, please post them below. If you liked this post, you can share it with your followers or follow me on Twitter!
comments powered by Disqus