Let me tell you how Emacs is more and more taking the center stage in my MacBook. In a previous post i explained how i set up Gnus as my mail (and of course, news) reader: i like Gnus so much that it quickly became my default. And, just in case you didn’t know, Emacs can be OS X’s default mail handler too: just go to Mail’s general preferences pane and set it–it’s that easy. (In the image, i’m setting fink’s carbon emacs package, but you’ll see there too CarbonEmacs or Aquamacs if you have them installed.) With that setting in place, OS X will dutifully use Gnus whenever a mail handler is requested (e.g., when following
mailto: URLs, or when using ‘Send this page…’ in Safari).
Unlike Gnus, Emacs is not my default web browser, although i use w3m-el quite a bit (specially for technical manuals). So, every now and then i find myself seeing a page in Safari than i want to open in Emacs. Applescript to the rescue: fire up that ugly Script Editor and type this simple program:
property eclient : "/sw/bin/emacsclient -e "
tell application "Safari"
set this_url to the URL of document 1
do shell script eclient & \
"'(w3m-browse-url \"" & this_url & "\")'"
tell application "Emacs22" to activate
(changing the path to emacsclient and the name of your Emacs as needed). Of course, you’ll also need to start the Emacs server somewhere in your init files with
(start-server), and to save the above script in
~/Library/Scripts/Applications/Safari. I’ve named it ‘Open in Emacs’, and it appears nicely as an entry in my FastScripts menu.
The last, and most interesting, bit is going in the opposite direction: accessing Safari (or any other Cocoa application, for that matter) from Emacs. Or, put in another one, executing AppleScript snippets within Emacs. One possibility is using Emacs’
shell-command in conjunction with OS X’s
osascript, but there’s a sweeter way: the Elisp function
do-applescript. For instance, the function
jao-as-safari-doc below returns the URL and title of the active page in Safari:
(defun jao-as-tell-app (app something)
(let ((res (do-applescript (concat "tell application \""
app "\" to " something))))
;; the string returned is quoted
(substring res 1 -1)))
(defun jao-as-safari-doc ()
(let ((url (jao-as-tell-app "Safari"
"get the URL of document 1"))
(name (jao-as-tell-app "Safari"
"get the name of window 1")))
(cons url name)))
This may seem a bit boring at first, but it can be put to good use: when i see a page worth taking a few notes, i open an org-mode buffer, and type a shortcut bound to the following function:
(defun jao-org-insert-safari-link ()
(let ((l (jao-as-safari-doc)))
(insert (org-make-link-string (car l) (cdr l)))
(message "Link to %s inserted" (car l))))
and (minor) magic happens. I’m sure you can think of many other interesting uses of
do-applescript, can’t you?