2011-02-16

EmacsのバッファやDiredでカーソル位置のファイル(URL)をFinder(ウェブブラウザ)で開く

Finder でダブルクリックした時と同じ動作をさせたい場合、 Mac OS X には open という便利なコマンドがあるのでそれを使う。

;; カーソル位置のファイルや URL を open で開く
(defun my-open-at-point ()
  "Ask /usr/bin/open to open the thing at or before point."
  (interactive)
  (require 'ffap)
  (let ((file (or (ffap-url-at-point)
                  (ffap-file-at-point))))
    (unless (stringp file)
      (error "No file or URL found"))
    (when (file-exists-p (expand-file-name file))
      (setq file (expand-file-name file)))
    (message "Open: %s" file)
    (start-process "open_ps" nil "open" file)))

(global-set-key "\C-co" 'my-open-at-point)
;; double click
(global-set-key [double-mouse-1] 'my-open-at-point)
(global-set-key [double-down-mouse-1] 'ignore) ; mouse-drag-region

キーバインドは一例ですが、ダブルクリックにも割り当ててます。
以下のようなURLやファイルに対応します。

http://www.google.co.jp/
~/Library
/usr/include/stdio.h
#include <stdio.h>

注意点として、 (require 'hoge) のような文字列に対して実行すると、 hoge.el.gz というファイルが開き、 .gz が解凍されてしまう場合があります。この辺の挙動は y-or-n-p とか使って確認してから開く、という風に変えてもいいかもしれない。

以下 Dired の設定。

;; カーソル位置のファイルを open で開く
(defun my-dired-do-open (&optional arg)
  "In dired, invoke /usr/bin/open on the marked files.
If no files are marked or a specific numeric prefix arg is given,
the next ARG files are used.  Just \\[universal-argument] means the current file."
  (interactive "P")
  (let ((files (dired-get-marked-files nil arg)))
    (apply 'start-process "open_ps" nil "open" files)))

(eval-after-load "dired"
  '(define-key dired-mode-map "\C-co" 'my-dired-do-open))

動作確認: Mac OS X 10.6, GNU Emacs 22