Setting up Emacs As a Daemon in Ubuntu
How to set up Emacs to run as a background process under Systemd
The Problem
Emacs is slow. Every time I need to edit a file, it takes forever for an Emacs window to load my configuration and open up an editor window for me to start working on my file.
The Solution
Searching for a solution to improve launch times, I got to know that the Emacs engine can be launched as a background service, with individual editor files launched in lightweight windows or as emacs calls it, ‘frames’. Since you only have to launch light-weight client instances instead of a full engine, emacs opens up in less than half the time it used to take before.
(The below instructions are tested on Ubuntu 22.10 Kinetic Kudu, but should work on any recent Ubuntu distribution.)
Start by installing emacs, if you haven't already. I recommend installing the latest emacs (currently version 28) from the official PPA.
sudo add-apt-repository ppa:kelleyk/emacs
sudo apt-get update
sudo apt install emacs28
You can verify your installation was successful by launching emacs
from the terminal. To open a file with Emacs, run emacs filename
. You will notice that launches were rather slow.
(Aside: The default Emacs configuration to load is read from file ~/.emacs.el More details about the Emacs configuration file can be found at this link.)
There are several ways to launch emacs as a daemon during startup in Ubuntu. Since systemd is the init daemon in Focal, we will register emacs as a service under systemd to be launched during startup. Systemd will monitor this service and restart if the service crashes for any reason. To configure the service, we first create a new file ~/.config/systemd/user/emacs.service
with the following content:
[Unit]
Description=Emacs text editor
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/
[Service]
Type=forking
ExecStart=/usr/bin/emacs --daemon
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=on-failure
[Install]
WantedBy=default.target
We now use this systemd service configuration file to register and start the new service by running the below commands on the terminal.
systemctl enable --user emacs
systemctl start --user emacs
Verify that the emacs service is running by using:
systemctl status --user emacs
The output should indicate that status is running. Press ‘q’ to return to the terminal prompt.
Now that the Emacs engine is running in the background, we need to use emacsclient
instead of emacs to open files.
emacsclient filename
You will notice that files open a LOT faster than they used to before!
Things to remember while using Emacs as a daemon:
Using
emacs
binary launches a separate instance of emacs engine and client. To edit a file using the emacs daemon/service, you should always useemacsclient
.To open an
emacsclient
window with an empty buffer, you need to use either--tty
or--create-frame
flag. The first command opens anemacsclient
instance within the current terminal window and the second flag launches a GUI window. (Runningemacsclient
without any flags will throw an error.)To make launching emacs easier, it helps to configure the below aliases in your
~/.bashrc
alias em='emacsclient --tty'
alias ema='emacsclient --create-frame'
Note: When launching files using
emacsclient
, the terminal is blocked by theemacsclient
process. To have the terminal not wait for emacs to close the file, use the--no-wait
flag.Closing an
emacsclient
instance doesn’t necessarily mean that emacs has disposed of the file handle. The right way to quit an emacsclient instance is by usingC-x #
(equivalent toM-x server-edit
) notC-x C-c
which only kills the ‘frame’ or window.