κeenのHappy Hacκing Blog | Lispエイリアンの狂想曲

Emacsのdired-modeを使い易くする

Emacsの標準ライブラリdired.elを読んでたら色々発見があったのでメモ兼dired-modeとはなんじゃらほいって方にも一から解説してみます。

とは言ってもいきなり解説しなくて申し訳ないのですが、最初に

(ffap-bindings)

を設定しておきましょう。C-x C-fが非常に便利になります。だいたいの方が設定してるかと思いますが、まだという方はinit.elに書いて保存し、最後の)の後にカーソルを持っていってC-x C-eしましょう。設定が反映されます。この設定でC-x C-fの入力がファイル以外も受け付けてくれますし、カーソルにポイントされてるファイルやURLをデフォルトで開こうとしてくれます。

…よし。じゃあ解説始めますよ。C-x C-f ~/してみて下さい。上の設定をしていたらディレクトリでも開ける筈です。するとホームディレクトリがls -alされた感じのバッファが出てくると思います。

私のホームはちょっとマズいのがあったので.emacs.dのスクリーンショット

これがdired-modeです。これは普通にn(C-nでも可)やp(C-pでも可)で移動して、Enterでそのファイルやディレクトリを開けます。これだけでも十分便利なのですが、ここからさらにファイル操作までできます。

適当なファイルにカーソルを合わせてCするとコピー先を聞かれるので、入力してあげるとコピーしてくれます。複数ファイルをコピーしたいなら、コピーしたいファイル上でmしてマークを付けて、Cすれば一括でコピーできます。

勿論、他にもコマンドはあります。同じような使い方のできる代表的なものを挙げると、

コマンド 操作(実行されるLinuxコマンド)
C コピー(cp)
R リネーム/移動 (mv)
D 削除(rm)
M 権限操作(chmod)
G グループ変更(chgrp)
O 所有権変更(chown)
Z 圧縮/展開(compress/uncompress/gunzip/bunzip/unzip)
B (*.elファイルの)バイトコンパイル
! 任意のコマンドの実行。デフォルトで空気読んだコマンドになってる。

他にも無数に操作はありますがファイル操作はこんなものでしょう。あとはバッファを閉じるqや親ディレクトリに移動する^、バッファの更新を行なうg、マークを外すu(Uで全解除)を覚えていれば操作には困らない筈です。

が、頻繁に使っているとより良く使いたくなります。そこで今回見付けた設定を紹介します。

まず

(add-hook 'dired-load-hook (lambda ()
                  (define-key dired-mode-map "r" 'wdired-change-to-wdired-mode)))

から。これはdired-modeでrするとバッファがエディタブルになり、ファイル名を普通に変更できます。そのままC-x C-sすればリネームの終了です。
普通にEmacsの編集コマンドが使えるので M-%とかで一括拡張子変更とかC-x r tでファイル名にプリフィクスつけたり自由自在です。

次に

(setq dired-listing-switches (purecopy "-Ahl"))

Emacsがdired-modeを表示するとき、実際に裏で ls -alを走らせているのですが、そのときのオプションを変更できます。但し内部で-lの結果を利用してるのでこれは必須です。しかしそれ以外は自由に設定できます。因みにWindowsでもEmacsがエミュレートしてくれるので設定可能ですが、一部未実装のものもあるそうです。

頻繁に使うなら

(setq dired-dwim-target t)

もお勧めです。

これを設定しておくと、ウィンドウを分割して左右にdiredバッファを開いているとき、RCのデフォルトの宛先がもう片方のディレクトリになります。伝わりますかね?

分割した両方のWindowでdired-modeを実行した状態。

のようにdiredでディレクトリA, Bを開いてるときにディレクトリAでファイルのコピーやら移動やらをするときにデフォルトでBに移動やコピーを行なうようになります。いくつかのファイルをディレクトリ間で移動させるときに非常に便利ですね。

あ、C-x C-f /ftp:user@ftp-server:/path/to/dirでFTPサーバーのディレクトリ/ファイルにもアクセスできるのは御存じですよね?これと組合せるとEmacsが割と使い易いFTPクライアントに大変身!

あとは私がどうしても欲しかったtarballですね。

(defun dired-tar (tarname files &optional arg)
  “A dired-mode extension to archive files marked. With prefix argument, the tarball is gziped.”
  (interactive (let ((files (dired-get-marked-files)))

 (list (read-string "Tarball name: " (concat (file-relative-name (car files)) ".tar.gz"))
           files "P")))

(let ((tar (if arg

 (if dired-guess-shell-gnutar
         (concat dired-guess-shell-gnutar " zcf %s %s")
       "tar cf - %2s | gzip > %1s")
       "tar cf %s %s")))
(shell-command (format tar tarname (mapconcat 'file-relative-name files " ")))))

(add-hook ‘dired-load-hook (lambda () (define-key dired-mode-map “T” ‘dired-tar)))

これでtarballにまとめたいファイルをマークしてTすればまとめてくれます。C-u Tするとgzip圧縮までしてくれます。因みに解凍/展開はファイル上で!するとデフォルトコマンドが展開(tar xzvfなど)になってるので専用コマンドは必要ありません。補足ですが個人用なのでテストとかしてません。一旦御自身で動作テストなどをされてから実行されることをお勧めします。

他にも色々なコマンドがたくさんあったので興味のある方は探求してみて下さい。

Written by κeen