Yi Tang Data Science and Emacs

Multiple Working Emacs

I work solely inside of Emacs, so when Emacs is down, I cannot do any work. Emacs itself is very reliable, but there might be some risks of downtime when upgrading Emacs or any of the 3rd party libraries that I use.

The downtime can be minimised by always having multiple Emacs versions and their 3rd party libraries available. This blog post documents how I implement it.

Installation

Firstly, install each Emacs into its separate folder, e.g. on my Debian box, I have ~/bin/emacs30.0.92/ installed 8 months ago and ~/bin/emacs30.2/ installed yesterday. This is easy to achieve by adding the prefix option when building Emacs from source, e.g.

 
./configure --with-tree-sitter  --prefix=$HOME/bin/emacs30.2

Daemon

Then have a separate systemd service for each Emacs version. Taking version 30.2 as an example, its unit file is saved as ~/.config/systemd/user/emacs30.2.service.

In that unit file, the Emacs executable is specified in full path to wherever it is installed

[Unit]
Description=Emacs text editor
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/
After=graphical-session.target


[Service]
Type=simple
ExecStart=%h/bin/emacs30.2/bin/emacs --fg-daemon=work --init-directory=%h/.config/emacs/emacs.d_30.2
ExecStop=%h/bin/emacs30.2/bin/emacsclient -s work --eval "(kill-emacs)"
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=on-failure

[Install]
WantedBy=graphical-session.target

In the unit file, I also added the initial option init-directory so it has its own .emacs.d directory. It ensures the 3rd party packages will be installed there.

Note if there is an init.el file in that directory, Emacs will use that instead of the ancient ~/.emacs file.

GUI

Finally, to open an Emacs GUI that connects to the Emacs 30.2 daemon, run

 
~/bin/emacs30.2/bin/emacsclient -s work -c .

from the command line.

I sometimes found it is more natural to have a desktop application for GUI, so I have ~/.local/share/applications/emacsclient-30.2.desktop file, and the content is

[Desktop Entry]
Name=Emacs 30.2 (Client)
GenericName=Text Editor
Comment=Edit text
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;x-scheme-handler/org-protocol;
Exec=~/bin/emacs30.2/bin/emacsclient --create-frame -s work %F
Icon=emacs
Type=Application
Terminal=false
Categories=Development;TextEditor;
StartupNotify=true
StartupWMClass=Emacs
Keywords=emacsclient;
Actions=new-window;new-instance;

[Desktop Action new-window]
Name=New Window
Exec=~/bin/emacs30.2/bin/emacsclient --create-frame -s work %F

[Desktop Action new-instance]
Name=New Instance
Exec=~/bin/emacs30.2/bin/emacsclient --create-frame -s work %F

Not Perfect But Close

There could still be some risks of downtime due to conflicts between Emacs/package versions, or caused by updating the OS/other programs. These cases are rare, so this setup is good enough for me.

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