Working with EmacsClient
Previously, I showed how I set $EDITOR. On my laptop, I actually do something different to take advantage of my favorite Emacs feature EmacsClient. EmacsClient is command line accessory that commands existing Emacs sessions to open files. That way you can have Emacs open with your windows arranged the way you like and push in files that you want to work as you go.
In addition, EmacsClient can be used as $EDITOR to cause programs, say
a ‘git commit’ to open a window instead of starting a new editor
session.
On Unix-like systems EmacsClient is typically in
/usr/bin/emacsclient
or /usr/local/bin/emacsclient
. On the Mac, at
least when
built from source,
lives in the application bundle
/Applications/Emacs.app/Contents/MacOS/bin/emacsclient
.
Setup
Before you can use EmacsClient, Emacs needs to be running in “server mode”, there are pleny of ways to do this.
One time - run ‘M-x server-start’ or ‘M-x server-mode’ or, from the
command line, start Emacs with the --daemon
option.
emacs --daemon
Every time - put:
(server-start)
;; or
(server-mode 1)
in (depending on how you roll) your .emacs
. .emacs.el
, or
.emacs.d/init.el
.
Once the daemon process is started, running emacsclient file
will
open that file in the current Emacs window (or “frame” in Emacs-speak)
and wait until you hit C-x #
.
What if Emacs isn’t already running? The default behavior is for
emacsclient
to raise an error. However, if you set the environmental
variable “ALTERNATE_EDITOR” to an empty string:
export ALTERNATE_EDITOR=""
then emacsclient
will launch Emacs in daemon mode and wait for it to
start up. ALTERNATE_EDITOR
can also be set to a different, fallback
editor however, I’ve never found a use case for this.
How I work
Personally, I don’t like the default emacsclient
behavior as it ties
up a shell window and buries the buffer I was last in. Instead, I add
two command-line options, -c
which creates a new frame for the file
and -n
which tells emacsclient
to exit immediately instead of
waiting for me to finish editing. As a bonus, when you use -n
,
closing the window EmacsClient opened has the same effect as C-x #
.
Now when I fire up emacsclient -n -c file
, or ec file
as I like to
alias it, a new frame opens with the file and I’m back at my prompt.
Setting $EDITOR
The EDITOR
(and it’s strange, historical friend, VISUAL
)
environmental variable can be set to emacsclient -c
. Doing this
causes programs that launch an external editor, for example running
git commit
, two open it’s edits in a new frame in your current Emacs
session.
When setting $EDITOR
you do not want to using the -n
flag. If
emacsclient
doesn’t wait, the program that open the editor will
think you exited it. In the case of our git commit
, we would
end up with a blank commit message.
Putting it all together.
My complete configuration looks like this:
if [ -z "$SSH_CONNECTION" ]; then
case $OSTYPE in
darwin*)
export EMACSCLIENT=/Applications/Emacs.app/Contents/MacOS/bin/emacsclient
alias emacsclient=$EMACSCLIENT
;;
*)
export EMACSCLIENT=emacsclient
;;
esac
alias ec="$EMACSCLIENT -c -n"
export EDITOR="$EMACSCLIENT -c"
export ALTERNATE_EDITOR=""
else
export EDITOR=$(type -P emacs || type -P vim || type -P vi)
fi
export VISUAL=$EDITOR
As I only want to use EmacsClient when I am on my desktop, -z
"$SSH_CONNECTION"
is a simple way to check for remote vs local
sessions. I use $OSTYPE
to detect if I am on a Mac and setup it’s
unusual path. The case
statement is overkill, but allows for further
per OS customization.
That is a bit of upfront configuration, but I find one editor to rule them all solves my problem of having half a dozen editors open and not being able to find the one I was just working on.
Comments