hnwの日記

Emacs+Firefox+MozReplでファイルセーブと同時にリロード

Webアプリケーションの開発効率向上のため、Emacsでファイルをセーブすると同時にFirefoxをリロードするような仕組みをMozReplというFirefox拡張を利用して実現しました。毎度おなじみ、数年前に流行ったネタを蒸し返すコーナーです。


MozRepl拡張を使えば、Firefoxを外部から好き放題に操作することができます。理屈としては、この拡張を有効にするとFirefoxlocalhostTCP 4242番ポートで待ち受けるようになり、このポート経由でブラウザレベル(chrome://レベルとでも言うんでしょうか…イマイチうまく言えませんが)の任意のJavaScriptが利用できるというものです。


今回は「Emacsでセーブしたら、Firefoxで見ているページがlocalhostのときだけリロードする」ようにしました。最初はセーブするたびに常にFirefoxをリロードする設定で使っていたのですが、作業中に調べ物をしていた場合など、よそ様のページを無駄にリロードしてしまって迷惑だと考えたためです。


これは.emacsに次のように設定することで実現できます。

;; MozReplを使って、セーブすると同時にFirefoxをリロード
;; http://www.emacswiki.org/emacs/MozRepl#toc2
(when (require 'moz nil t)
    (defun auto-reload-firefox-on-after-save-hook ()
      (add-hook 'after-save-hook
                '(lambda ()
                   (interactive)
                   (comint-send-string
                    (inferior-moz-process)
                    ;; URLのホスト部がlocalhostの場合のみリロード
                    "if (content.location.host == \"localhost\") { BrowserReload(); }"))
                'append 'local)) ; buffer-local

    ;;MozReplのポート番号。MozReplの待ち受けポートを変えた場合に適宜変更してください。
    ;;(setq moz-repl-port 24242)
    (add-hook 'php-mode-hook 'auto-reload-firefox-on-after-save-hook)
    (add-hook 'html-mode-hook 'auto-reload-firefox-on-after-save-hook)
    (add-hook 'css-mode-hook 'auto-reload-firefox-on-after-save-hook))


localhostのときだけ」というリロードの条件は、JavaScriptのif文で記述しています。このようにブラウザに対する指令をJavaScriptで記述できるのはMozReplを使うメリットだと言えるでしょう。他の方法だとリロードさせることはできても、こうした条件分岐をさせるのは難しいのではないでしょうか。


僕はこの自動リロードの仕組みをphp-mode、html-mode、css-modeの3つのモードで有効にしてみました。他にも即座にリロードしたいモードがあれば好きなだけadd-hookすることができます。


ただし、上記.emacsを試すにはmoz.elが必要です。これはMozRepl本家から提供されているEmacs Lispで、EmacsからMozReplを利用するためのものです。まずMozRepl拡張をインストールし、MozReplを有効化し、moz.elをload-pathに設置してからお試しください。


ちなみに、.emacsの最初の1行「(when (require…」の部分で、moz.elのロードに成功したときだけ以降の命令を実行するようにしています。moz.elが無い環境でもエラーを出さずに動くので個人的にお気に入りの書き方なんですが、elを入れたつもりなのに実は無かった、なんてときに混乱の元だったりもします。ご注意ください。