たとえば、Macだと下記のようなコードをinit.elに放りこんでおくと、dired-modeでWで、指定したファイルをopenコマンドで呼び出してくれる。これはファインダーでダブルクリックしたときと同じ動きをしてくれるもので——pdfファイルだったらpdfビュアーで開いてくれる。これでエクセルのようなEmacsで開いてもしかたがないようなファイルを対応したアプリケーションで開くことができるようになる。
(require 'deferred)
;; diredで外部プロセス起動
(add-hook 'dired-mode-hook
(lambda ()
(define-key dired-mode-map
"W" 'dired-open)))
(defun dired-open ()
(interactive)
(deferred:process "open" (dired-get-filename)))
元々、このコードはMeadowがらみで知った。Meadowにはfiberという、Macのopenコマンドに相当するものが同梱されていたのだ。そのMeadowも今はメンテされていない。
Windowsで動くEmacsはいくつか、あるのだけれど、さすがにfiberはなくてかわりにstartコマンドがある。でもこいつを呼び出すにはどうしたらいいのかなぁ、なんかstartコマンドが見つからないんですけど、と思っていたら内部コマンドだということを知った。そうか。
ところがEmacsのパス構文がちがうため、フルパスでstartコマンドを渡すとうまく動作しない。前記のサイトでもディレクトリの部分をのぞいたファイル名だけにしていた。MeadowはWindowsのパス構文の変換ができた。もしかしたらEmacsに取り込まれているんじゃないか、とelispを漁って、見つけた。
w32-convert-standard-filename
で、前記サイトのコードを元にこうした。
(defun my-x-open (file)
"open file."
(interactive "FOpen File: ")
(message "Opening %s..." file)
(call-process "cmd.exe" nil 0 nil "/c" "start" "" (w32-convert-standard-filename file))
(message "Opening %s...done" file))
これを使ってbookmarkの一覧バッファや、orgのハイパーリンクから外部コマンドで立ち上げることができるようになる。良きことかな。
追記:2016年7月31日(日)
cmd.exeをcall-processなどしなくてw32-shell-executeで呼び出せることが判明……。