Home

Simple Emacs aliases for macOS

(Updated: )

It seems that launching Emacs from the command line on macOS is a very common problem with overly complex solutions that don’t quite work right. I’ve landed on the following two scripts that are close to ideal for me:

For $EDITOR to be used with git, etc.:

$ cat ~/bin/emc
#!/bin/sh
#
# This is a direct wrapper around `emacsclient` that can be used as a value for
# $EDITOR. It does not use the GUI, and instead always creates a new frame on
# the CLI.
set -o errexit -o nounset

emacsclient --alternate-editor "" \
            --socket-name=cli \
            --tty \
            --quiet "$@" 2>/dev/null

This launches the Emacs daemon if it isn’t already running and opens a new frame on the terminal. It’s also effective as a general replacement for Vim when making quick edits.

Note that this uses a separate Emacs instance via the --socket-name=cli flag. Ideally there would only be one, but that doesn’t seem to be supported well by macOS currently. Most workarounds online result in a headless instance running in the Dock, or have issues with closing/re-opening frames.

For all else:

$ cat ~/bin/em
#!/bin/sh
#
# This is a convenience wrapper to launch or reuse a GUI Emacs instance to open
# a given file. It doesn't wait for it to exit, so can't be used as an $EDITOR.
set -o errexit -o nounset

abspath() {
    python -c "import os, sys; print(os.path.abspath(sys.argv[1]))" "$1"
}

# The --args flag doesn't work when Emacs is already running, so first try
# using emacsclient.
if emacsclient --suppress-output --eval nil 2>/dev/null; then
    emacsclient --no-wait --quiet "$@"

    # Ensure Emacs becomes active even when prompts are shown.
    #
    # env -i is used to avoid polluting $PATH and other environment variables
    # passed to Emacs, which can cause warnings in extensions such as
    # exec-path-from-shell.
    env -i open -a Emacs
elif [ $# -gt 0 ]; then
    env -i open -a Emacs --args "$(abspath "$1")"
else
    env -i open -a Emacs
fi

This requires an Emacs server to be running, via (server-start) in the Emacs config.

An even simpler version of this at first glance would be open -a Emacs, but that unfortunately doesn't work for editing new files.

I’m currently using emacs-mac installed via Homebrew Cask.

If you have a better method or suggested fix, please shoot me an email or comment on the Reddit post.