Netrwを使いこなす

VimにはNetrwという、非常に便利なファイルブラウザがあります。
SSHでサーバーにアクセスしてファイルを編集するなど、ターミナル上で作業をする人は、"ls"とか"cd"コマンドを駆使して作業をしていると思います(Emacsを使ってる人はともかく)。これはこれでいいのですが、やはりいちいちコマンドを打たないとファイルが見れない、カレントディレクトリを変更できないなど不便な点があります。ところが、Vimのファイルブラウザを使うと、GUIで作業しているかのようにディレクトリを移動したりファイルを開いたりできるのです。もちろんVim上なのでシェルコマンドも実行できます。
というわけで、その使い方をメモ程度に記します。

ブラウジングを始める


以下のコマンドを打てば、ファイルブラウザが起動します。現在のバッファが編集中(保存していない)の場合は、水平方向に分割して表示されます。

:Explorer

これ以外にもいろいろあるので、まとめておきます。

:Explorer 現在のバッファでブラウジングを開始(編集中なら水平に分割)
:Explorer! 上と同じ。ただし編集中の場合に垂直分割
:Hexplorer 横方向に分割して下のウィンドウでブラウジングを開始
:Hexplorer! 上と同じ。ただし上のウィンドウでブラウジングを開始
:Vexplorer 縦方向に分割して左のウィンドウでブラウジングを開始
:Vexplorer! 上と同じ。ただし右のウィンドウでブラウジングを開始
:Texplorer 新しいタブでブラウジングを開始

一応、Sexplorerというものもあるのですが、Hexplorer、Vexplorerで十分なので省略します。
ちなみに、このブラウジング画面は、ディレクトリを指定してVimを開いたときにも表示されます。

ファイルを開く・カレントディレクトリの移動


まず、最低限必要な、ファイルの編集、およびディレクトリの移動についてまとめます。

Enter ファイルを開く or ディレクトリを移動する
o 上と同じ。ただし、水平方向に分割する
v 上と同じ。ただし、垂直方向に分割する
t 上と同じ。ただし、新しいタブに表示する
p 上と同じ。ただし、プレビューウィンドウに表示する
–(ハイフン) 上の階層へ移動する
u 前にいたディレクトリに戻る(アンドゥ的な)
U uで戻る前のディレクトリに移動する(リドゥ的な)
c このバッファのカレントディレクトリを、現在開いているディレクトリに変更

注意してほしいのですが、Enterや–で階層を変更しても、Vimの(厳密に言えばこのバッファの)カレントディレクトリが変わるわけではないということです。ファイルブラウザではどれだけ階層を変更したとしても、ブラウザを開いた時点でのカレントディレクトリが変更されることはありません*1

ディレクトリの作成と削除


ファイルを開く方法は上に記したので、ディレクトリの作成と削除について記します。

d ディレクトリを作成
D ファイル・ディレクトリを削除(ディレクトリに関しては、中が空の場合のみ)

作成と削除だけなのでこれだけです。「ファイルを作成」というコマンドは用意されていないのですが、単に":e <ファイル名>"コマンドを実行すればファイルを作成して編集することができます。ただし、上記の"c"コマンドでカレントディレクトリを移しておかないと、想定外の場所に作られてしまうのでご注意を・・・。ちなみに、この2つのコマンド、というかNetrwのキーマップで呼ぶコマンドの場合はカレントディレクトリを変更する必要はありません。
あと、"D"コマンドについて、中にファイルがあるディレクトリを削除できないと書きましたが、これはVimが"rmdir"を実行しているためです。この設定は、g:netrw_local_rmdirに依存するので、これを"rm -rf"に変更すれば中にファイル・ディレクトリがあっても削除することができます。もっとも危険ではありますが
もちろん、Vimからシェルスクリプトを呼ぶこともできるので、":!rm -rf hoge"でも削除できます。ただし、カレントディレクトリをきちんと変更しておかないと、場合によっては惨いことになるのでご注意をw

ファイルのマーク


さて、ここに来て謎の“マーク”という単語が出てきましたが・・・。これは特に怪しい(?)ものではなくて、要は“ファイルを選択する”というようなものです。選択してどうするのか?というと、もちろん選択したら移動とかコピーをしますよね。
というわけで、まずマークの仕方についてまとめます。

mf カーソル上のファイルをマークする/マークを解除
mr ワイルドカードを指定してファイルをマークする
mu すべてのマークを解除

ただし、"mr"について、ドキュメントには以下のように書いてあります。

Note: 使用できるのはVim正規表現です (|regexp|)。シェルのものとは違います。なので例えば *.c と入力しても期待どおりにはならないでしょう。

ですが、実際に試してみたところどう見てもワイルドカードでした本当に(ry
もっとも環境によるのかもしれませんが、少なくともMacPortsで入れたVim、およびWindowsに入れたKaoriYa版のVimでもワイルドカードになっていたので、ドキュメントの間違いかと思われます。

ファイルのコピー・移動


マークが終わったら次はコピーです。“終わったら”って表現も妙ですが。。

mt コピー・移動先のディレクトリを、カーソル下のディレクトリに設定する
mc マークしたファイルをコピーする
mm マークしたファイルを移動する
D マークしたファイルを削除する

コピー・移動を行う際には、まず移動先のディレクトリを指定する必要があります。“カーソル下の”というのがミソで、ディレクトリ上にカーソルがある場合はそのディレクトリに、ファイル上あるいは関係ないところにある場合は現在のディレクトリ(カレントディレクトリではない)になります。
あとは、"mf"、"mr"でファイルをマークして、"mc"、"mm"コマンドでコピー・移動ができます。なお、マークしたファイルに対するコピー・移動操作は、現在のディレクトリ上にあるファイルにしか適用されないようなので、複数ディレクトリにあるファイルをまとめてコピー・移動するようなことはできないようです。
あと、ここでも"D"コマンドが出てきましたが、このコマンドは、マークしたファイルがある場合には、マークしたファイルを削除するようになります。前述の、適用されるマークファイルの範囲など、地味な罠があるので、"D"コマンドを打つ場合には、表示される確認プロンプトでファイル名を確認した方がいいと思われます。
なお、マーク、およびコピー・移動はディレクトリに対しては行えません。なので、ディレクトリをコピーしたいときは、シェルコマンドを打つしかなさそうです。

その他のファイル操作


マークしたファイルに行える操作のうち、上に記していないものを書きます。

mx シェルコマンドを実行。コマンド中の"%"がファイル名に置換される
md vimdiffを実行。ファイルは3つまでで、現在のディレクトリに関わらず、すべてのマークファイルが対象になる
mg vimgrepで検索。現在のディレクトリに関わらず、すべてのマークファイルが対>象になる
mh マークしたファイルと同じ拡張子を持つファイルを隠す

マークしていないファイルについても、以下のような操作が行えます。

qf ファイルの情報を表示する。"ls -l"で表示される項目
R ファイル・ディレクトリの名前を変更する(2010/6/4 追加)

Rコマンドはファイルのフルパスを変更するので、これによってファイルの場所を変更することもできます(2010/6/4 追記)。

表示をいじる

ファイル操作は以上で終わりで、次は表示に関するコマンドをまとめたいと思います。
まずはソートについて。


r ソートの順番を逆にする
s ソートの種類を変更(名前 -> 時間 -> ファイルサイズ)

名前によるソートは、g:netrw_sort_sequenceにパターンを設定することで、変更することができます。
次に、いらないファイルの表示・非表示について。

a すべて表示 -> 隠しファイル非表示 -> 隠しファイルのみ表示
gh ドットで始まるファイルの表示・非表示を切り替える
mh 前述

少しややこしいので説明します。まず、ファイルブラウザの表示状態には、「すべて表示」「隠しファイルを非表示」「隠しファイル"のみ"表示」という3つの表示状態があります。"a"コマンドはこれらの状態を切り替えるものです。そして、"gh"や"mh"コマンドは、指定したファイルを隠しファイルにする/元に戻すという操作を行うだけで、実際に表示されるかどうかは、前述の表示状態に依存します。
なお、g:netrw_list_hideにパターンを設定すれば、自動で隠しファイルと判断してくれるようになります。というか、"gh"、"mh"コマンドは、単にここにパターンを追加しているだけだったり。

外部との通信


Netrwで最も面白いと思ったのは、この外部との通信機能です。こう書くとよくわからないかもしれませんが、要するにscpやftpのクライアントとして使えるよ、ということです。ローカル環境で作業をするのであれば、GUIのクライアントを使った方が便利な場合が多いのですが、SSHで接続してるリモート環境で、さらに別のサーバーとファイルの送受信を行いたいときなんかにはかなり役に立つと思います。まあ、そんな状況がそうそうあるかどうかはともかく。。


ftpは触ったことがないので、とりあえずscpだけ記しておきます。
接続方法は簡単で、


:Explorer scp://user@host/path

を打つだけです。これで、パスワードを求められると思うので、認証が通ればリモートのファイルが表示されるようになります。
ただし、これには不便な点があって、ディレクトリを移動したりファイルを開くたびにパスワードを求められてしまいます。これでは単なるストレッサーにしかならないので、もうちょっと便利に使えるようにします。結論を言うと、要するに認証は最初だけで、一度つなげば自動的に認証してくれるようにする、ということです。
パスワードを毎回求められるのを防ぐためには、鍵認証を行う必要があります。パスワード認証を使っている場合は、先に鍵認証を導入してください。こちらのサイトに書かれています。
まずはUnix環境から。ssh-agentを使って鍵を追加します。以下のコマンドを実行してください。

$ eval `ssh-agent`
$ ssh-add ~/.ssh/hoge.pem

秘密鍵にパスワードを設定している場合は、このタイミングでパスワードが求められると思います。鍵を追加できれば、あとは先ほどの方法でサーバーに接続すれば、パスワードなしでローカル環境のようにアクセスできるようになります。
なお、鍵ファイルにパスワードを設定していないのであれば、鍵ファイルを .ssh/id_rsa という名前にすれば ssh_agentを用いなくても接続できます。パスワードを設定しているのであれば、やはり ssh-agentを使ってください。


次にWindows環境なのですが、これがどうも厄介なことにファイルを編集することができないようです。ファイル一覧を見ることはできるので、その手順だけ説明します。
まず、PuTTYをインストールします。アーカイブ版でも問題ないです。
次に、vimrcに以下の設定を追加します。

let g:netrw_scp_cmd='C:/putty/pscp.exe -q -batch'
let g:netrw_ssh_cmd='C:/putty/plink.exe'

PuTTYの置き場はどこでもいいのですが、スペースを含むパスの場合にうまく動かないようなので、スペースを含まないパスを指定してください。
次に、'C:\tmp'ディレクトリを作成します。なくても動くのですが、これがないといちいち".swpファイルを作れないよ"というメッセージを出してきて鬱陶しいので、作っておいた方がいいです。
あとは、Unix環境と同様のコマンドでサーバーに接続します。念のため、こちらにも。


:Explorer scp://user@host/path

で、ファイルを開いてもらうと分かるのですが、たぶん何も表示されないと思います。確認してみたところ、Vimはどうやらpscp(というよりcmd.exe)に対して、シングルクォーテーションでパラメータを囲んで、渡しているようなのです。Windowsではダブルクォーテーションを用いるのが普通なので、このせいでうまく動かないようです。何てことしやがる

リモートとローカルとでファイルをコピー・移動する


最後に、リモートからローカルに、あるいはローカルからリモートにファイルをコピー・移動する方法を説明します。
と言っても、その手順は前述した通りで、「移動先を指定」「ファイルをマーク」「コピー・移動」を行うだけです。ただし、リモートからファイルを持ってくる場合に、そのままだとエラーが出るので、リモートバッファ上で以下のコマンドを打っておきます。

:let b:netrw_islocal=0

この辺自動的にやってくれても良さそうなものなのですが、なぜか手動でやらないとうまく動かないようです。ディレクトリを移るたびに、これを実行しないといけないので地味に面倒くさいです。逆に、ローカルからリモートに関しては、特に何もせずにコピーできるようです。
なお、それ以外の操作(ディレクトリの作成、削除など)に関しても、前述したコマンドで実行できます。


以上、ファイルブラウザの使い方について、ざっと書いてみました。ここに書いていないものもありますので、それらについてはドキュメントを参照してください。

*1:g:netrw_keepdirで設定を変更できます。