Using emacsclient to Speed up Editing

When using a typical graphical text editor like gedit it is expected to be able to quickly open files from your file manager and make edits. Emacs is generally not well suited for this workflow as it is made to be customizable therefore most Emacs users will have long configuration files that must be loaded at startup causing Emacs to open comparatively slower. This works fine if you like to startup Emacs once and do everything inside of it, but if you are frequently opening and closing windows you would be better off just starting Emacs once and connect to it using the very fast and lightweight emacsclient.

Starting Emacs as a daemon

emacs --daemon

This can be added to startup files that are sourced at login like your ~/.profile, or ~/.bash_profile to easily start the daemon at login.

Using a Systemd service

Alternatively, I choose to start the Emacs daemon as using a Systemd user service. I went this route as it gives me a consistent way to manage my Emacs daemon as I would any other process using familiar systemctl commands.

Systemctl commands Description
start Start (activate) one or more units
stop Stop (deactivate) one or more units
restart Start or restart one or more units
enable Enable one or more unit files
disable Disable one or more unit files

To do this you must create a .service in ~/.config/systemd/user/. My example: emacs.service 1

[Unit]
Description=Emacs Daemon

[Service]
Type=forking
ExecStart=/usr/bin/emacs --daemon
ExecStop=/usr/bin/emacsclient --eval "(progn (setq kill-emacs-hook 'nil) (kill-emacs))"
Restart=always

[Install]
WantedBy=default.target

In order to control this user created service we have to preface our commands with --user. This gives us the benefit of our service being controlled and run without root privileges. You should always avoid running anything as root if you do not absolutely have to.

Then start and enable this service run

systemctl --user start emacs.service   # Start emacs for the current session
systemctl --user enable emacs.service  # Enable emacs to be started at login

Open files with your file browser

Now like any other graphical editor you will want to be able to open files from your graphical file browser. To do so create a desktop file for emacsclient and place it in ~/.local/share/applications/2

[Desktop Entry]
Name=Emacs 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++;
Exec=emacsclient -c %f
Icon=emacs
Type=Application
Terminal=false
Categories=Utility;TextEditor;

Note that some distributions ship with an Emacs client desktop icon by default, e.g. Debian, so this step may be unnecessary unless you want to make use of the following script.

Set as default in Nautilus

In nautilus file browser find a text file type you wish to be associated with Emacs client. Right click it, select properties, move to the “Open With” tab choose Emacs Client and press “Set as default”.

Open all files in one frame

This desktop file will result in each file being opened as a new Emacs frame (a new window). This will clutter up your desktop if you open many files. A better option would be to open a new frame only if none exist otherwise open the file as a new buffer in the existing frame. This is accomplished with the following emacsclient-one-frame.sh script 3

#!/bin/bash

# if no args open new frame
if [ $# -eq 0 ]; then
    emacsclient -c -n
    exit
fi

emacsclient -e "(frames-on-display-list \"$DISPLAY\")" &>/dev/null

if [ $? -eq 0 ]; then
    emacsclient -n "$*"
else
    emacsclient -c -n "$*"
fi

Make the script executable

chmod +x emacsclient-one-frame.sh

Test run the script with

./emacsclient-one-frame.sh testfile.sh

Add the script to your it to your path

The path is the directory where commands are sourced from. Generally you place user created executables in ~/bin or ~/.local/bin. You can check if these are path with

echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

As you can see ~/bin and ~/.local/bin are not in my path. To add them you can edit your bash profile which is stored in either ~/.profile or ~/.bash_profile. Add the following

PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH

To verify this was done correctly run this command from a shell

source ~/.bash_profile && echo $PATH
/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/home/tingram/.local/bin:/home/tingram/bin

Update the .desktop file

Change the Exec line in the desktop file we created earlier to use this script instead of emacsclient

Exec=emacsclient-one-frame.sh %f

Add a command alias

If you frequently start Emacs from the commandline you’ll want to start using emacsclient to speed up your startup time. In your ~/.bashrc consider adding one of the following aliases

alias emacs=emacsclient-one-frame.sh
alias ec=emacsclient -t # Opens emacs inside terminal

Set emacsclient as your default terminal editor

In your ~/.profile or ~/.bash_profile add the following lines

EDITOR='emacsclient -t'
export EDITOR

VISUAL=emacsclient-one-frame.sh
export VISUAL

VISUAL means visual editor and most things should default to it, EDITOR will be used if VISUAL cannot be. 4

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s