Setting up Emacs As a Daemon in Ubuntu

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.

image.png

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 use emacsclient.

  • To open an emacsclient window with an empty buffer, you need to use either --tty or --create-frame flag. The first command opens an emacsclient instance within the current terminal window and the second flag launches a GUI window. (Running emacsclient 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 the emacsclient 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 using C-x # (equivalent to M-x server-edit ) not C-x C-c which only kills the ‘frame’ or window.