4
votes

Is there a better method to activate a function in Emacs with an applescript instead of opening the minibuffer to launch the function? There is a delay that is needed to take my finger off of the control key to launch the applescript with a keyboard shortcut (so that Emacs doesn't register it as a command), and there is another delay after typing the name of the function into the minibuffer. Ideally, I'd like to tell Emacs under-the-hood to run a particular function without opening the minibuffer. The following is a simple applescript to activate Emacs, and open the minibuffer with M-x, and type the name of the function (dock), and press the return key. The method should work whether Emacs is presently open (hidden or in the front) or closed.

FYI:  For the novice programmers like myself, here is a cheat-sheet for key codes:  https://apple.stackexchange.com/questions/36943/how-do-i-automate-a-key-press-in-applescript/36947#36947?newreg=9adf36816f4245d69f0900ec09588057


EDIT:  A shorter method would be to set up a keyboard shortcut within Emacs that is attached to a function (global-set-key (kbd "<f6>") (lambda () (interactive) (dired "/Applications"))) -- e.g., F6 to activate the function, and then use key code 97 for the F6 key. However, it would still be nice to learn how to specify running an Emacs function by name (with an applescript) without opening the minibuffer.


tell application "System Events"
  tell application "/Users/HOME/.0.data/.0.emacs/Emacs.app/Contents/MacOS/Emacs" to activate
  delay .3
  key code 53 # escape
  key code 7 # x
  key code 2 # d
  key code 31 # o
  key code 8 # c
  key code 40 # k
  delay .1
  key code 36 # return
end tell

or

tell application "System Events"
  tell application "/Users/HOME/.0.data/.0.emacs/Emacs.app/Contents/MacOS/Emacs" to activate
  delay .3
  key code 97 # F6
end tell

EDIT:  Revised draft (based on the answer by @Francesco) -- it requires that (server-start) be inside the Emacs startup file (e.g., init.el). IF Emacs GUI is already running, then run emacsclient without a pause prior thereto; ELSE, launch Emacs GUI (pause 1 second for the server to load) and then run emacsclient.

on is_running(appName)
  tell application "System Events" to (name of processes) contains appName
end is_running
set EmacsRunning to is_running("Emacs")
if EmacsRunning then
  tell application "/Users/HOME/.0.data/.0.emacs/Emacs.app/Contents/MacOS/Emacs" to activate
  do shell script "/Users/HOME/.0.data/.0.emacs/Emacs.app/Contents/MacOS/bin/emacsclient -e '(dired \"/Applications\")'"
else
  tell application "/Users/HOME/.0.data/.0.emacs/Emacs.app/Contents/MacOS/Emacs" to activate
  delay 1
  do shell script "/Users/HOME/.0.data/.0.emacs/Emacs.app/Contents/MacOS/bin/emacsclient -e '(dired \"/Applications\")'"
end if
1

1 Answers

1
votes

I don't know about applescript, but can't you use emacsclient to do this?

Once you have started the server in your existing Emacs instance (M-xserver-startRET), you can run something like :

emacsclient -e "(call-interactively 'dock)"

to evaluate arbitrary lisp code into Emacs.