Using Elixir 1.5's open command with Emacs.app
August 28, 2017
If you are a user of Emacs, you may have seen Chris McCord’s post
on the Dockyard blog last week about using Elixir 1.5’s new open
command in IEx with terminal Emacs.
Being an Emacs user, but preferring Emacs.app generally to the terminal Emacs, I decided to investigate applying his work to my own workflow. I promised to write it up if I succeeded, so here we are!
The first thing we need to do is place some scripts (or symlink them) in /usr/local/bin
. These scripts will be
used by Elixir to open Emacs.app to the location of the module or module/function we want. Since Chris already wrote
up the reasons for these scripts, I’m going to keep this short and focus on the contents, where to place them, and the changes I made.
First, we have to ensure ELIXIR_EDITOR
is exported in our environment, since I use fish
, this is how I did that in my
~/.config/fish/config.local.fish
file:
set -x ELIXIR_EDITOR "~/bin/emacs +__LINE__ __FILE__"
This tells Elixir to execute ~/bin/emacs
with the line and file of the thing we’re opening as arguments.
That script looks like so:
#!/usr/bin/env sh
EMACSPATH=/Applications/Emacs.app/Contents/MacOS
EMACSCLIENT="$(which emacsclient)"
# Check if an emacs server is available
# (by checking to see if it will evaluate a lisp statement)
if ! ("${EMACSCLIENT}" --eval "t" 2> /dev/null > /dev/null ); then
# There is no server available so,
# Start Emacs.app detached from the terminal
# and change Emac's directory to PWD
nohup "${EMACSPATH}/Emacs" --chdir "${PWD}" "${@}" 2>&1 > /dev/null &
else
# The emacs server is available so use emacsclient
ARGS="${@}"
if [ -z "$ARGS" ]; then
# There are no arguments, so
# tell emacs to open a new window
"${EMACSCLIENT}" --eval "(list-directory \"${PWD}\")"
else
# There are arguments, so
# tell emacs to open them
"${EMACSCLIENT}" --no-wait "${@}"
fi
# Bring emacs to the foreground
${EMACSCLIENT} --eval "(x-focus-frame nil)"
fi
Make sure that script is set as executable with chmod +x path/to/script
.
You’re all set! Now you can test open
in IEx:
> iex -S mix
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> open MyApp.Supervisor
This should either open a new instance of Emacs.app, or open the file containing MyApp.Supervisor
in the currently open
instance. Have fun!