After having used emacs for a couple of months now, I discovered the emacs --daemon option today and was astonished. Having quite a big emacs config, it takes ages for emacs to start preventing me from using it as the standard editor for config files etc. The --daemon mode starts emacs in the background acting as a server and allows one to create emacs frames using the emacsclient in various ways. EMacs shows up lightning-fast then and becomes an option for the always-to-use text editor.

Here is my setup on how to work with emacs and use it as an editor for quickly editing files on the command line.

# Starting the daemon using systemd

I switched from sysVinit to systemd some time ago, so the most convenient thing to do is to start the emacs daemon using a custom systemd service file. Put the following code into the file /etc/systemd/system/multi-user.target.wants/emacs.service:

[Unit]
Description=Emacs: the extensible, self-documenting text editor

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


Make sure you insert your username in the bottom line. Now, enable the service executing systemctl enable emacs.service and after the next boot the daemon is started automatically.

# Shell aliases and sudo-ing

One thing you will quickly notice is that sudo emacsclient ... doesn’t work since the daemon runs under your username. To be able to edit files as root, we need to load the tramp plugin of emacs. Put the following line somewhere in your .emacs or .emacs.d/init.el:

(require 'tramp)


Now, you would use emacsclient -c /sudo::/etc/somefile which is still a bit too long for quick file editing. (As well as the emacsclient command itself). This is why we create shell aliases. I am using zsh which is why I will use its syntax here.

export EDITOR="emacsclient -t -n -a nano"
alias ec='emacsclient -c -n -a nano'
alias et='emacsclient -t -a nano'
ecs() { emacsclient -c -n -a emacs "/sudo::$*" } ets() { emacsclient -t -a emacs "/sudo::$*" }


It sets emacs as the default editor and defines the commands ec (emacs in a separate window) and et (emacs in the terminal) as well as its sudo friends for write-protected files, ecs and ets. Simply put the code in your .zshrc or .bashrc (after editing it to fit bash’s syntax) and restart the terminal. Then you can use ec/et/ecs/ets /some/directory/some/file to edit the file. I think tramp uses ssh to connect to your pc as root, so you might need to install ssh to use it.

• Nov. 20, 2011, 7:44 p.m.

Tramp doesn’t need ssh to sudo.
stackoverflow.com/questions/95631/open-a-file-with-su-sudo-inside-emacs/2071375#2071375

• Nov. 20, 2011, 7:55 p.m.

Thanks for the tipp. I edited the article accordingly.

• Feb. 2, 2012, 10:35 p.m.

Thanks for the tip, emacsclient seems quite convenient! On my eee-pc, the startup speed improved noticably. But my color settings stopped working… maybe I should try the color-theme machinery.

• Feb. 13, 2012, 4:42 a.m.

I didn’t know I could use tramp like that, thanks. It really bogged to start emacs and then use tramp mode.

• Aug. 12, 2012, 2:36 p.m.

Have you had an issue of default-directory being set to /, or ansi-term defaulting to sh (opposed to zsh in my case)?

• Sept. 7, 2012, 9:27 p.m.

I’ve noticed that. The service is being started outside of the usual bash environment, or any shell, even if you specify the user. there are parameters like WorkingDirectory=, Enviroment= and EnvironmentFile= that can be used, but those don’t read scripts like .bashrc or even /etc/passwd, they just take variable-assignment pairs, so you have to set them all yourself.
One thing I’ve been trying is

ExecStart=/bin/su -l -c “emacs —daemon”

which seems to work. just be sure to unset User= , otherwise it will run su as you, and fail since it doesn’t have permission.

• Nov. 3, 2013, 1:39 p.m.

A while ago, I wrote a (zsh) shell function to handle the emacsclient/emacs+sudo handling (including the fact that emacsclient and emacs take different arguments for GUI/CLI toggling). Thought I’d share it

edit() {
local use_sudo=false use_cli=false ignore_daemon=false
while getopts cns name; do
case ${name} in s) use_sudo=true;; c) use_cli=true;; n) ignore_daemon=true;; esac done shift$((OPTIND-1))

local args
args=()

## sanitise paths for sudo
for arg in "${@}"; do if [[ "${arg}" == /* ]]; then
new_arg=${arg} else new_arg=${PWD}/${arg} fi${use_sudo} && new_arg=/sudo::${new_arg} args=( "${args[@]}" "${new_arg}" ) done local opts cmd if${ignore_daemon}; then
cmd=emacs
if ${use_cli}; then opts=-nw else opts= fi else cmd=emacsclient if${use_cli}; then
opts=-t
else
opts=-c
fi
fi

echo "Running ${cmd}${opts} ${args[@]}"${cmd} ${opts} "${args[@]}"
}


Hope this ends up looking sort of okay. You can invoke it e.g. as ‘edit -nc foo bar’ (c=CLI, n=new process) to get a new non-graphical emacs process or ‘edit -s foo bar’ (s=sudo) to get a graphical client of your daemon, with foo and bar opened using root privileges.

• Nov. 3, 2013, 2 p.m.

Hi, thank you! (I am just realizing I need to work on the formatting of comments a little bit. :) )