viを使い倒す

01/06/25 Naoto Hashimura

vi (ブイアイ)は、UNIXの標準エディタです。 emacs? ンなものは rm しましょう。 (ウソ)
シンプルで、かつ考えられた viを 極めてみませんか?

★バッファを知る

vi には 英字バッファ数字バッファ と呼ばれる、とても便利なバッファがあります。

-------------------------------------------------------------------------------
編集バッファ
┌────────────────┐	英字バッファ (aからzの26個)
|これは、画面に見えている、編集中|	a┌───────┐
|の内容です。          |	 └───────┘		
│                │ 	b┌───────┐
│                │	 └───────┘
│                │	        ...
│                │
│                │	数字バッファ (1から9の9個)    
│                │	1┌───────┐
│                │	 └───────┘
│                │	2┌───────┐	
│                │	 └───────┘	
│                │	        ...
│                │
└────────────────┘
-------------------------------------------------------------------------------
英字バッファ
普通にコピーや削除したら、再びコピー・削除した場合、前のが消えます。
英字バッファという、aからzの26個のバッファがあります。これを使えば、ずっと取っておくことが可能です。

普通のコピーや削除のコマンドの前に "a〜"z を付けます。
例えば、英字バッファa に カーソルの乗っている行をコピーするには "aY、 取り出すには "ap とします。

英字バッファは、次元を超えて・・・ 複数のファイル間で共有されます。
通常、複数ファイルの同時編集で :n で次のファイルに移動した場合、英字でないバッファの内容は失われてしまいます。が、英字バッファだけは残っているのです。 詳しくは後ほど。


数字バッファ
編集バッファで1行以上の削除をすると、数字バッファ1 へその内容が保存されます。
次にまた 1行以上の削除をすると、それが数字バッファ1 へ、そして前に数字バッファ1 にあったものが数字バッファ2 へ移ります。

例えば、
aiueo
kakikukeko
sasisuseso
という 3行を、上から dd していきます。このとき、
数字バッファ1 … sasisuseso
数字バッファ2 … kakikukeko
数字バッファ3 … aiueo
と、新しく dd したものから順に、数字バッファ1、2、3に入っているのです。
ここで、
"1p とすると、1回前に dd した、数字バッファ1 の内容が、
"2p とすると、2回前に dd した、数字バッファ2 の内容が取り出されます。
便利でしょう?
ちなみに、数字バッファへのコピーはできません。 (できる vi もある)


ところで、何回前に dd したか、覚えてれば良いのですが、忘れたら?
"1p でバッファ1 を取りだしてみて、違ったら消し、"2p でバッファ2を取り出してみて、違ったら消し、… を繰り返すのか? とっておきのテクがあります!
"1p         ←数字バッファ1を取り出す
u           ←取り出したのを やっぱ取り消す
.           ←なぜか数字バッファ2が取り出される
u           ←取り出したのを やっぱ取り消す
.           ←なぜか数字バッファ3が取り出される

(見つかるまで u と . を繰り返す)
このテクは、どんな vi でも通用するはずです。
vi の種類でも、vim と呼ばれるやつは、exコマンド :dis でバッファの内容が見れますから、このテクを知る必要ないんですが・・・


★exコマンドを編集バッファに書いて実行しよう!

例えば、コマンドモードで、苦労して長〜〜い置換コマンドを入力、実行しました。で、一部間違ってて、置換に失敗しました。すると、始めからもう一度入力し直すの? そんな・・・

そこで @コマンド!
@コマンドは、英字バッファの内容を exコマンドとして実行するものです。

viの入力モードで、
:s/Section \([1-9][0-9]*\.[1-9][0-9]*\)/セクション \1/
のように、exコマンドとして実行したい命令をそのまま書きます。
(ちなみに上の置換コマンドは、「Section 3.8」 みたいな文字列を 「セクション 3.8」 のようにするものです)

この文字列の上で、コマンドモードに入ります。そこで、
"aY
と入力し、この行を 英字バッファa に保存します。
そして、これを実行したい行で
@a
とすると。。。英字バッファa の内容がコマンドとして実行されるのです!
もし失敗したら、上の文字列を直して、再度 "aY、@a をすれば良いのです。

このテクを覚えたら、もぅ、数倍は作業効率がアップします。


いくつもの exコマンドを複数行に書いて、"a4Y のように、複数行をバッファにコピー、実行すると、一気に実行できます。


★タグファイルとは何か

あるC言語のソースファイルを編集していて、
「あり〜? 関数 hoge はどこで定義されてたっけ?」
とか、
「関数 bar の戻り値って何型だっけ?」
ということがよくありませんか?

そういう場合、作業ディレクトリに tags というファイルを作り、次のような内容を書きます。
-------------------------------------------------------------------------------
hoge    okok.c  /^void hoge(/
bar     main.c  /^long bar(/
-------------------------------------------------------------------------------
1番目に任意のキーワード(関数名とか)、2番目にファイル名、3番目に検索パターンを書きます。文字列間はタブで区切ります。

viのコマンドモードで、
:ta hoge
とすると。。。
tagsファイルが viにより勝手に参照され、okok.cが開かれ、/^void hoge(/ にマッチした行に飛んでくれます。

編集していたファイルに戻るには、
:po
とします。
:ta で飛んだ先でまた :ta して… を繰り返したら、その分 :po をして戻ります。

で! 自分で tagsファイルを作るのも良いのですが、(C言語などの)ソースファイルから、自動的に
関数名	ファイル名	/パターン/
という具合に列挙し、それを “tags” というファイル名で保存してくれるコマンドがあります。
-------------------------------------------------------------------------------
$ ctags *.c
-------------------------------------------------------------------------------
このctagsコマンド、C言語のソース以外にも、C++やPascalのソースファイルでもうまくタグファイルを作ってくれます。 (Perlはさすがに無理か?)

ところで、この tagsファイルは、プログラムのソースファイル以外の目的で使うのも全然良いですし、また、3番目には パターンに限らず exコマンド(コロンは除く)であれば何でも良いみたいです。

例えば、tagsファイルに
-------------------------------------------------------------------------------
hoge_20     hogehoge.txt    20
hoge_end    hogehoge.txt    $
-------------------------------------------------------------------------------
:ta hoge_20 とすると、hogehoge.txt の20行目に飛び、
:ta hoge_end とすると、hogehoge.txt の最後の行に飛びます。


★終わりに

とりあえず暫定公開しましたが、まだまだ書くことはあります。
更新するのはいつになるやら・・・


このページの先頭 | 前のページに戻る