Emacs特集の未収録その2 「Emacs で Growl を使ってみる」。

WEB+DB PRESS Vol.58の未収録内容その2です。第2章のコラム「フックについて」で after-save-hook の使い方の例で執筆しました。hook も覚えて、shell-command も覚えれるという個人的には一石二鳥のサンプルでした。
たとえば、MacにGrowlという通知ソフトがありますが、パッケージに同梱されている growlnotify というコマンドラインツールをインストールすると、シェルから Growl を利用できるようになります。
これを利用してEmacsでバッファを保存したときにGrowlによる通知を行うようにしてみましょう。その場合、バッファを保存するタイミングで関数を実行してくれるafter-save-hookを利用します。

;; growlnotifyコマンドが存在する場合のみフックを追加
;; growl に通知するための関数を定義
(when (executable-find "growlnotify")
  (defun growlnotify-after-save-hook ()
    (shell-command
     (format
      "growlnotify -a \"Emacs\" -t \"バッファを保存\" -m \"%s\""
      (buffer-name (current-buffer)))))

  ;; 関数をafter-save-hookに追加する
  (add-hook 'after-save-hook 'growlnotify-after-save-hook))

この設定をinit.elに加えて再起動すると、今後バッファを保存するたびにGrowlによって通知されるようになります。

コマンドの解説。

growlnotity は、以下のような引数でコマンドを実行することで、任意の通知を行なうことができます。なお、-a も -t も -m も省略可能です。

$ growlnotify -a "アイコンを取得したいアプリ" -t "タイトルテキスト" -m "メッセージテキスト"

Emacs では shell-command 関数を使うことで、シェルにコマンドを渡すことが出来ます。上記のサンプルでは、メッセージにバッファ名を使いたいので、format 関数を利用してコマンドとなる文字列を整形してから、shell にコマンドを渡しています。
単に Emacs から Growl による通知をテストしてみたい人は、例えば、Emacs で "C-x C-e" を使って以下の式を評価してみましょう。

(shell-command
 (format
  "growlnotify -a \"Emacs\" -t \"バッファを保存\" -m \"%s\""
  (buffer-name (current-buffer)))) ; ←ここで評価する

なお、ダブルクオート内でダブルクオートを使うにはバックスラッシュでエスケープする必要があります。(buffer-name (current-buffer)) はカレントバッファの名前を取得します。
というわけで、これは下記のコマンドと同意です。

$ growlnotify -a "Emacs" -t "バッファを保存" -m "バッファ名"

growl.el を使って、もっと簡単に Growl を利用する。

elim さんが公開してくれている growl.elを利用すると、簡単に Growl による通知が行なえます。

;; (install-elisp "http://github.com/elim/emacs-growl/raw/master/growl.el")
(require 'growl nil t)

インストールして require すると、(growl "Hello World.") という感じで、growl 関数に文字列を渡すだけで、Growl の通知を利用することができます。