Skip to main content

Emacs 26 and macOS Mojave

In preparation for moving to Mojave, I'm updating my GNU Emacs installation process.

Server Mode?

Using emacs in server mode reduces startup time dramatically. It also makes sharing content between various frames much nicer (e.g., M-w in one frame can be yanked via C-y in another).

Create an Emacs Server Application

Previously, I would tell emacsclient to start a server if one was not present via the -a "" option, but having macOS start a server at login is actually nicer, I think.

Open the AppleScript editor and paste in the following:

tell application "Terminal"
   do shell script "/Applications/ --daemon"
end tell

Compile it and save it as an application (Emacs in ~/Applications/Development.

You can add the GNU Emacs icon to your new application by:

  • Select /Applications/ and press ⌘i.
  • Click the icon in the top left, then press ⌘c to copy it.
  • Select /Applications/Development/Emacs and press ⌘i.
  • Click the icon in the top left, then press ⌘v to paste it.

Start the Emacs Server at Login

For your user id:

  • Access System -> User & Groups -> Login Items
  • Press + and choose /Applications/Development/Emacs

You may, of course, double click on Emacs to start it now, rather than logging out/in.

Create an Emacs Client Application

We now need the ability to open a new frame on the server. Use the AppleScript Editor again to create a script containing:

tell application "Terminal"
        do shell script "/Applications/ -c -n &"
        tell application "Emacs" to activate
    on error
        do shell script "/Applications/"
    end try
end tell

Compile it and save it as /Applicaitons/Development/Emacs

This ensures that Emacs will appear as the first item in spotlight because 'Development' sorts before 'Emacs', and 'Client' sorts before 'Server'.

File Associations

I also configure macOS to use Emacs Client as the default application for a number of file types (e.g., .py, .txt, .md, ...) so that double-clicking on those files opens them for editing with Emacs.

Add Emacs Client to the Dock

Drag the app to the dock.

The Dock

With the above complete, Emacs Server will always appear in the dock. Clicking on it in the dock will raise any frames, if they exist. If no frames exist, clicking on it does nothing.

Clicking on Emacs Client in the dock will create a new frame on the server and raise the window.

This isn't a perfect scenario, but it's about the best that can be done with macOS.

bash Scripts

Create a few bash scripts to complement what's been done so far. I put these in my ~/bin, which is at the front of my $PATH.


When run from the command line, this uses emacsclient to open a GUI new window (frame) containing a buffer for the file specified as the argument. The script returns immediately, making the command line available for continued use.

#!/usr/bin/env bash

# Open a new frame GUI using emacsclient.  Return immediately.

# -n    --> Return immediately, don't wait for edit to complete
# -a "" --> If emacs is not running in server mode, start it
# -c    --> create a new frame instead of using existing frame

/Applications/ -n -a "" -c "$@"


This is similar to ec, except that the script does not exit until the buffer being edited is closed via C-x #.

#!/usr/bin/env bash

# Open a new frame GUI using emacsclient.  Return when buffer is exited.

# -a "" --> If emacs is not running in server mode, start it
# -c    --> create a new frame instead of using existing frame

/Applications/ -a "" -c "$@"


This runs a new character-based Emacs instance, independent of any emacs server, in the current terminal session. The script does not return until Emacs is exited (e.g., via C-x C-s or C-x C-c).

#!/usr/bin/env bash

# Open a new character-based emacs process in the current terminal.
# This does not connect to an emacs server.

/Applications/ "$@"


When working at the command line, I usually edit files via ec foo, which opens the file foo in a new window for editing. Because emacsclient returns immediately, I can keep issuing cli commands.

Some commands use the $EDITOR environment variable to determine the editor to run. Generally, these commands assume that when the editor exits, the edit is complete. Clearly, ~/bin/ec is not suitable for this purpose; I use ~/bin/emacs in this situation.

Emacs Anywhere

Ever need to edit text within another application but you'd much prefer to edit the text with Emacs? Now you can. This is based on the Vim Anywhere post on HN. There are two components.

Automator Workflow

Create an Automator Workflow comprised of two parts and saved as ~/Library/Services/EmacsOnSelection.workflow.


on run {input, parameters}  
    tell application "EmacsMac" to activate
    tell application "System Events"
        repeat until visible of process "Emacs" is true
            delay 0.5
        end repeat
    end tell
    return input
end run

Bash Script

#!/usr/bin/env bash
tmp=$(mktemp -t EmacsSelection)
cat > "$tmp"
until [ $($ec -q -e '(server-running-p)' 2>/dev/null) == t ]; do
    sleep 1
$ec -q -c "$tmp"
cat "$tmp"
echo 'khe'
if [ $rv -ne 0 ]; then
    echo "Something went wrong.  Please find your text in"
    echo "$tmp"
    rm "$tmp"

Resulting Workflow

Within the Applescript Editor, the workflow should end up looking like this:

MacOS Keybinding

Once the workflow is complete, assign it to a key sequence (I chose Ctl-⌘-E) here: SystemPreferences -> Keyboard -> Shortcuts -> Services -> Emacs Anywhere.