Skip to content

Instantly share code, notes, and snippets.

@dlukes
Last active December 10, 2018 04:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dlukes/1288778748d8f99652a7 to your computer and use it in GitHub Desktop.
Save dlukes/1288778748d8f99652a7 to your computer and use it in GitHub Desktop.
AppleScript wrapper app around Emacs for running it conveniently as a daemon on OS X
(* SETUP
1. Create an Application in Automator.
2. Add a Run AppleScript action.
3. Paste the content of this gist instead of the provided script skeleton.
4. Save the app, drag it to your dock and/or set it as the default app for
the filetypes of your choice using the Open With dialog in Finder.
NOTES ON USAGE
TODO
TESTED ON OS X 10.9 MAVERICKS with EMACS 24.3 installed via HOMEBREW
*)
on run {input, parameters}
-- alter the paths to point to your copies of the `emacs` and `emacsclient` binaries
-- use full paths preferably, as OS X comes with its own (obsolete) copy of Emacs
-- do not alter the command line switches!
set ED to "/usr/local/bin/emacs --daemon "
set EC to "/usr/local/bin/emacsclient --no-wait -c -a \"\" "
set thereAreInputFiles to false
-- if there are files in the input, then open each of them in a separate frame...
repeat with eachFile in input
set filePath to quoted form of POSIX path of eachFile
-- tell me to display alert EC & filePath & " || (" & ED & " && " & EC & filePath & ")"
do shell script EC & filePath & " || (" & ED & " && " & EC & filePath & ")"
set thereAreInputFiles to true
end repeat
-- ... and return
if thereAreInputFiles then
tell application "Emacs" to activate
return -- RETURN POINT IF THERE WERE FILES IN THE INPUT
end if
-- if there are no files in the input, then either focus an existing frame or create a new one if there are no existing ones (i.e. if (frame-list) is of length 1, for some reason, not 0)
-- if Emacs is running, determine whether there are any open frames using emacsclient
try
-- can't `tell application "System Events" to count windows of process "Emacs"` because for some reason, the result is always zero
set NumberOfEmacsWindows to do shell script "/usr/local/bin/emacsclient --eval '(length (frame-list))'"
on error
-- if there's an error, then Emacs daemon wasn't running; spawn it, connect to it, focus the frame and return
do shell script ED & " && " & EC
tell application "Emacs" to activate
return -- RETURN POINT IF THERE WERE NO INPUT FILES AND DAEMON WASN'T RUNNING
end try
-- the list of Emacs frames seems to be always at least one; only with 2+ frames are there any that you can actually see in the GUI
if NumberOfEmacsWindows as integer > 1 then
-- at this point, we're sure that Emacs is running, that it is in daemon mode and that there are frames to maximize/switch to
tell application "Emacs"
reopen
activate
end tell
-- RETURN POINT IF THERE WERE NO INPUT FILES, DAEMON WAS RUNNING AND THERE WERE PREEXISTING FRAMES
else
-- Emacs daemon is running, but no frame has been spawned → spawn a new one and focus it
do shell script EC
tell application "Emacs" to activate
-- RETURN POINT IF THERE WERE NO INPUT FILES, DAEMON WAS RUNNING AND THERE WERE NO PREEXISTING FRAMES
end if
end run
@dlukes
Copy link
Author

dlukes commented Jan 20, 2017

For the record, I eventually came up with a much better solution than this horrible mess: http://dlukes.github.io/emacs-daemon-osx.html.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment