SAAS or Spacemacs as a service
Introduction
For people who don't know what Spacemacs is, it is an Emacs configuration that is meant to be be Discoverable, Consistent, Crowd-configured and with an emphasis on Mnemonic. It supports vim's bindings out of the box (thanks to evil) and provides tons of functionalities through a module configuration system. If you haven't tested it yet, you may give it a try, even if you already have an emacs configuration. This post is oriented towards Spacemacs, but should be easily adapted to any Emacs version.
In Spacemacs, despite the packages being lazy loaded, reading the configurations and setting everything up can take some time. For instance right now on my (quite decent) computer:
[425 packages loaded in 4.756s]
It takes nearly 5 seconds to start. This is not too bad taking into consideration the number of packages, but this is still annoying while working. There are two schools to address this problem:
- Run one emacs instance, do everything in it and never close it.
- Run a daemon in the background, and open client frames when needed.
I'm not really fond of having always an emacs instance that should never be closed. I'm still used to the vim's way of working with files, i.e. opening a new editor whenever I need to do something different. The second approach then fits well my workflow.
Running as a daemon
The Emacs daemon can simply be started with emacs --daemon
. This will setup
Emacs, and when done the daemon will be forked into a background process. To
open client frames on this daemon there is an emacsclient
executable taking
some arguments, like -c
to ask it to create a new GUI frame. Note that -t
may be used to create a new frame within a terminal.
You can test running emacs as a daemon right away with these commands:
$ emacs --daemon
$ emacsclient -c
This should open instantaneously an Emacs frame. You can then close the newly
created frame by pressing SPC q z
. You can also try to open several frames
in parallel by running several more time emacsclient -c
. It is possible to
kill the server by pressing SPC q q
.
All the Emacs runtime is shared between clients as they are on the same Emacs
instance. This mean you can access any buffer or layout from any client. You
can try this by opening a file in a first client, then pressing SPC b b
in a
second: you will see the buffer opened on the first client.
Using a service
Starting the daemon is a repetitive and boring task that can be automated at
boot/login time. In Linux distributions using it, systemd
can be used to setup
user services. User services are conceptually the same as system services, the
only difference is that they are at the user level and thus placed on the home
folder. This characteristic allows to easily add user services to some
version-control tool and share the configuration among several machines. The
format of user services is the same as system services. On Archlinux, user
service should be placed in ~/.local/share/systemd/user/
and ends with
.service
.
For running emacs as a daemon, the service file is pretty simple:
[Unit]
Description=Emacs: the extensible, self-documenting text editor
[Service]
Type=forking
ExecStart=/usr/bin/emacs --daemon
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
Restart=always
Environment="DISPLAY=:0" "SSH_AUTH_SOCK=/home/fabien/.gnupg/S.gpg-agent.ssh"
[Install]
WantedBy=default.target
This can be placed in ~/.local/share/systemd/user/emacs.service
. It can be
enabled at user login time with:
$ systemctl --user enable emacs
And it can be started right away with:
$ systemctl --user start emacs
Stopping it and disabling it from user login time is as easy as:
$ systemctl --user stop emacs
$ systemctl --user disable emacs
Note: For an unknown reason this is not working right away on my computer:
Failed to connect to bus: No such file or directory
I solved this by adding XDG_RUNTIME_DIR=/run/user/$UID
in front of commands,
using an alias to make it simpler:
$ alias scu="XDG_RUNTIME_DIR=/run/user/$UID systemctl --user"
$ scu enable emacs
$ scu start emacs
$ scu stop emacs
$ scu disable emacs
Extra: using WIN + s to start new clients in i3
If like me you are using the i3
window manager, you can bind emacsclient -c
to a key in order to start Spacemacs even more quickly in all situations,
without having to start a terminal first to enter the command. For instance you
can bind it to WIN + s
by adding the following line in your ~/.i3/config
file:
bindsym $win+e exec "emacsclient -c"