このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

Windows上の Emacs dired で任意のファイルを開く

Emacsのdiredを使っているとき、.pdfとか.pptのファイルに対して[e]キー(dired-find-file)を押すと、嬉しくないことになります。生のバイナリを目で見てもねぇー。

バッファ内でテキストファイル/画像ファイル以外も表示する仕組みにViewDocとかあるようですが、ファイル拡張子に対応するプログラムの起動でいいとしましょう。dired-open.elなんて、それようのパッケージもあるんですが、ここは[!](dired-do-shell-command)で間に合わせます。

Windowsにはstartというコマンドがあって、エクスプローラーからファイルをクリックしたのと同じ動作をします。「start」の5文字は長いので、1文字名前のバッチファイル s.bat を作れば、[!][s][RET]の3ストロークでいけそう。

@echo off
rem This is s.bat
echo Starting %1
start %1

これ、ダメでした。

diredは、クォートしたファイル名をコマンドに渡します。ファイル名がreport.pdfなら、start "report.pdf" というコマンドラインが実行されるわけです。

startはたいへんにおバカさんで、クォート文字があるとファイル名を認識しないのです。それでクォート文字を取り除くことにしました。

@echo off
rem This is s.bat
setlocal
set arg1=%1
set arg=%arg1:"=%
echo Starting %1
start %arg%
endlocal

%arg1:"=% という部分がクォート文字を空に置換する記法です。バッチファイルでもこんなことが出来るようになっていたんですね、知らんかったわ。

これでうまくいった、と思ったら、空白が入ったファイル名がダメになりました。例えば、"report draft.pdf" のようなファイルがあると、start report draft.pdf だと動かないのです。もちろん、start "report draft.pdf" もダメ。

startコマンド、使えねーヤツだなー、と思っていたら裏技がありまして、start "" "report draft.pdf" なら動くんだそうです。

@echo off
rem This is s.bat
echo Starting %1
start "" %1

なーんだ、空文字列「""」を付け足しておけば良かったんだ。

これでよし、と思っていたら日本語のファイル名でダメ。ウーム。diredバッファはutf-8設定にしているので、日本語ファイル名がutf-8でコマンドに渡されてしまいます。dired側のcoding設定を変えればいいんですが、意地になってバッチファイル側で対処するぞ、と。

MinGW/MSYSのiconvがあるので、echo %1 | iconv -f utf-8 -t sjis の標準出力を文字列にしてstartの引数に渡せばいいのです。でも、バッチファイルでは、`echo %1 | iconv -f utf-8 -t sjis` とか $(echo %1 | iconv -f utf-8 -t sjis) なんてのは出来ないですねー。

http://qiita.com/alucky0707/items/4dd7146440885ec4e189予想外の方法が書いてあったので、これを使うことにします。for文の/Fオプションとシングルクォートを使うんだそうです。シングルクォート内でパイプが使えないので、中間ファイルを作ることになりました。

@echo off
rem This is s.bat
echo %1> %TEMP%\%USERNAME%_s_bat.tmp
for /F %%x in ('iconv -f utf-8 -t sjis %TEMP%\%USERNAME%_s_bat.tmp') do (
    echo Starting %%x
    start "" %%x
)

日本語ファイル名だと、echo %1 のリダイレクトの段階で文字化けを起こすことがありますが、それは稀なので「もういいや」という感じです。このバッチファイルひとつだけで、[!][s][RET]がまーまー実用的に使えるようになりました。