Why?

As part of my new job as a software engineer at PagerDuty, I’ve been given a shiny new Macbook Pro with OS X Yosemite. I’ve been running Linux – whether it was Fedora, Arch, Ubuntu, Gentoo, or OpenSUSE – for a long time 1. Thankfully, most of the programs I use can be used unchanged on OS X (see here for specifics), but Emacs and package management itself is a little different. I’m going to briefly describe how to get Emacs up and running in a consistent way.

Homebrew

The first step is to install the Homebrew package manager for OS X. Homebrew is sort of a combination of the ports system from FreeBSD and the APT or RPM package systems. Things are compiled from source by default, but pre-compiled binary packages are available for the most-recent versions of packages. Packages are installed in a dedicated directory (like /usr/local/Cellar/emacs) and symbolic links are placed intelligently in /usr/local similar to how GNU Stow would do it.

I’m not going to cover the specifics of Homebrew installation. Follow the directions on the website.

Git

I use Git to manage lots of software configuration, so it’s typically the first thing I install:

$ brew install git

Managing configuration (“dot”) files with GNU Stow

My system for managing all of the miscellanious configuration files that one collects is to create a dedicated directory for each program in a Git repository and then use GNU Stow to place the files that I want in my home directory. I’m not the first one to use the approach: the idea comes from many blogs that have come before. I’ll use an example to demonstrate.

  1. Clone the repository for all the configuration files:

    $ git clone git@github.com:hakuch/HomeConfig.git ~/src/home-config
    
  2. Look at the directories in this repository:

    ~/src/home-config$ ls 
    total 0 
    drwxr-xr-x  4 jhaberku  staff   136B 23 Jan 09:54 bash 
    drwxr-xr-x  3 jhaberku  staff   102B 23 Jan 09:55 bash-osx-emacs 
    drwxr-xr-x  3 jhaberku  staff   102B 13 Jan 12:19 clang 
    drwxr-xr-x  3 jhaberku  staff   102B 13 Jan 12:19 gdb 
    ...
    

    We want to bring in the configuration files for bash, namely

    ~/src/home-config$ ls -a bash
    total 16
    drwxr-xr-x   4 jhaberku  staff   136B 23 Jan 09:54 .
    drwxr-xr-x  16 jhaberku  staff   544B 15 Jan 10:23 ..
    -rw-r--r--   1 jhaberku  staff   287B 23 Jan 09:54 .bash_profile
    -rw-r--r--   1 jhaberku  staff   1.1K 15 Jan 13:25 .bashrc
    

    into the home directory.

  3. To do this, we can execute GNU Stow as follows:

    ~/src/home-config$ stow -t ~ bash
    

    and the result in the home directory is:

    $ ls -a
    ...
    lrwxr-xr-x   1 jhaberku  staff    34B 13 Jan 12:20 .bash_profile -> src/home-config/bash/.bash_profile
    lrwxr-xr-x   1 jhaberku  staff    28B 13 Jan 12:20 .bashrc -> src/home-config/bash/.bashrc
    ...
    

Emacs

I use GNU Emacs for miscellaneous text editing tasks and also for the plethora of fantastic tools that are available on the platform.

Emacs running in a graphical window.

Emacs running as a terminal application in iTerm2.

I’m going to outline some instructions for running Emacs one of two ways: as a graphical application that can be launched from the dock, and as a background process that can be connected to near-instantaniously (like one might launch vim) from the terminal. A lot of credit for these steps comes from this blog, but I’ve made some simplifying changes.

  1. I keep all of my Emacs configuration files as a Git repository. By cloning the repository directly into ~/.emacs.d, I can be up an running instantly.

    $ git clone git@github.com:hakuch/EmacsConfig.git ~/.emacs.d
    
  2. Install Emacs via Homebrew, making sure to enable Cocoa support for the graphical window.

    $ brew install emacs --cocoa
    $ brew linkapps emacs
    

    The second command will create links to the Homebrew-installed emacs from the /Applications directory.

  3. We’re going to write an Applescript file which starts Emacs as a server. This script will then be added as a login item so that the server is always running.

    Open the Applescript editor and add the following contents:

    do shell script "/Applications/Emacs.app/Contents/MacOS/Emacs --daemon"
    

    As per the blog I linked to above, create a directory Development in /Applications and save the script as an application. I called mine “Emacs Daemon”.

  4. Now, add the Emacs Daemon application as a login item for yourself in the “Users & Groups” sub-menu of the Yosemite system preferences.

  5. We’re going to create three shell script helpers to launch Emacs. I put these scripts in ~/bin, which I’ve also added to my PATH.

    • The first, et, will connect to the Emacs server and launch in a terminal window (like vi), or start a new terminal instance of the server is not running.

      #!/bin/h
      
      ##
      ## et
      ##
      ## Start a terminal Emacs client or fall back to a new terminal instance.
      
      set -e
      EMACSCLIENT=/usr/local/bin/emacsclient
      exec $EMACSCLIENT -t -a emacs "$@"
      
    • The second, ec, will do the same as et but open in a new graphical window.

      #!/bin/sh
      
      ##
      ## ec
      ##
      ## Start a graphical Emacs client or fall back to a new graphical instance.
      
      set -e
      EMACSCLIENT=/usr/local/bin/emacsclient
      exec $EMACSCLIENT -c -a emacs-cocoa "$@"
      
    • The third, emacs-cocoa, will start a brand new graphical instance.

      #!/bin/sh
      
      ##
      ## emacs-cocoa
      ##
      ## Start a new graphical instance of Emacs.
      
      set -e
      /Applications/Emacs.app/Contents/MacOS/Emacs "$@"
      
  6. This is where things get a bit confusing. Opening graphical Emacs instances and connecting to the Emacs server at the same time seems to result in multiple Emacs icons in the dock and an inability to close the running Emacs instance. My solution to this problem is as follows:

    • Create a new applescript launcher that manually invokes emacs-cocoa:

      do shell script "~/bin/emacs-cocoa"
      

      and save it – also in /Applications/Development – as an application called “Emacs”.

    • Launch the new Emacs application you created, and you’ll see an icon in the dock with a generic script image and also an Emacs icon.

    • Right click the application in the dock with the Emacs logo (not the one with the generic script icon) and choose to save it do the dock.

    • You can now launch a new graphical instance of Emacs from the icon in the dock.

  7. To automatically use the new et script for all editing hooks in programs like Git, set a definition in ~/.bashrc:

    export EDITOR='et'
    

Footnotes

  1. Albeit, more recently as a virtual machine on top of a Thinkpad running Windows 8.1 as the host. I do this for the sake of drivers for graphics, power management, and networking.