「男は黙って Vim をフルスクリーン」、Vim 使いの「ブイ」(仮名)です。一部の方には人気(?)があるこの連載もついに 7 回目です。応援してくれている皆さんには感謝しています。今回のテーマは「QuickFix」です。Vim には QuickFix という機能がありますが、この機能こそ Vim が開発者のためのエディタである、ということを表しているのではないかと思います。
1 QuickFix¶
QuickFix とは、エラー結果や grep の結果が表示される専用のウインドウ領域のことです [1]。Visual Studio や Eclipse といった IDE に存在する、ビルド結果が表示されるウインドウによく似ています。ただし QuickFix はビルド結果専用というわけではなく、grep の結果の表示などにも使用されます。
QuickFix のメリットは、毎回 Vim を終了したりプログラムを切り替えなくてもビルドエラーの確認や grep の結果確認が可能ということです。普通、ソースコードの編集とビルド、grep による検索というのは開発中に何度も繰り返し行われるものです。ビルドするときや grep を行うときに Vim を終了する (または切り替える)コストというのは、かなり大きなものになります。さらに、もしコンパイルエラーがあったとして、コンパイラのエラー行からエラーのあったファイルと行番号を目視で参照するのは至難の技です。しかし、Vim を使用すれば Vim がエラーのある行や grep の結果を解析してくれるのでその手間を省くことができます。
2 :make と QuickFix¶
まずは :make
におけるQuickFix の利用です。:make
とは、Vim におけるビルドコマンドのことです。このコマンドを実行すると開いているソースファイルに対し、ファイルタイプに応じたビルド用コマンドが呼び出され
[2]、結果が QuickFix に表示されます。
今回の題材としては、Vim のソースコードを使用します。
$ hg clone https://vim.googlecode.com/hg/ vim
$ cd vim; ./configure
$ vim src/eval.c
ソースコードにエラーがない場合で試してみましょう。”src/eval.c” を開いている状態で :make
を実行します [3]。この make にはかなり時間がかかります。
エラーが出てこないと思いますが、さらに :copen
を実行しましょう。メッセージが大量に表示されていますが、コンパイルエラーは表示されないはずです。
次にエラーがある場合で試します。”src/eval.c” の先頭付近にある #include 文を次のようにコメントアウトします。
/*#include "vim.h"*/
今度は大量のエラーが出力されるはずです。さらに、:copen
を実行します。エラーを起こしたファイル名と行番号、エラーメッセージが一覧表示されます。ここで <Enter>
キーを押します。エラーを起こした行に飛んだはずです。ちなみに、QuickFix ウインドウは :cclose
で閉じることができます。
3 grep と QuickFix¶
Vim は Vim の中で grep を呼び出し、結果を QuickFix に表示する機能を備えています。grep というのはプログラム開発のなかで頻繁に利用するコマンドです。この機能を利用すれば、わざわざ grep の結果を参照するためだけに Vim を終了したり、シェルに切り替えるといった作業をしなくて済みます。
Vim の grep には、内部 grep と外部 grep の二種類があります。内部 grep は Vim 7.0 以降で追加された Vim 自身が行う grep です。日本語の文字コードも正しく認識することができます。ただし、対象ファイルを全て Vim のバッファに読み込むので、対象ファイルが多い場合にはとても遅いです。文字コードが混在していて、外部grep ではうまく認識されない場合や grep が標準ではインストールされていない環境(Windows) では内部 grep を使用するのがよいでしょう。外部 grepは、外部コマンドの grep を用いる grep です。シェルで実行するときのgrep とほぼ同等の結果を得ることができます。ただし、当然外部コマンドのgrep が必要です。マルチバイトを検索するためには、使用する grep がマルチバイトに対応している必要があります。
まず、内部 grep について解説します。内部 grep には、:vimgrep
というコマンドを用います。下記のコマンドを実行してみましょう。
:vimgrep /vim *.vim
:vimgrep
のコマンドは、:vimgrep /{pattern}/{flag} {file} ...
という構文になっています。{pattern}
とは、検索するパターンのことで、上記の例では “vim” です。{flag}
は検索時の動作を制御します。今回は {flag}
は省略されているのでありません。{file}
の部分には、検索対象のファイルを複数指定できます。今回の例のように、ワイルドカードも使用することができます。:vimgrep
の実行後は、:copen
コマンドを実行すると、検索結果の一覧を見ることができます。
:vimgrep
コマンドでは、{flag}
を省略した場合に最初の検索結果にジャンプしてしまいます。:make
のときならともかく、:vimgrep
の場合はこの仕様は邪魔になる場合が多いと思います。このジャンプを無効にする場合は、次のようにコマンドを実行します。
:vimgrep /vim/j *.vim
今回は “j” フラグを指定しており、最初にマッチした位置にジャンプ しな
い という意味になります。いちいち “j” フラグを付けるのが面倒な場合、:vimgrep
をラップした新たなコマンドを定義すると良いでしょう。
次に、外部 grep について解説します。外部 grep には、:grep
というコマンドを用います。下記のコマンドを実行してみましょう。
:silent grep! vim *.vim
:grep
のコマンドは、:grep {pattern} {file}...
という構文になっています。引数は、シェルから呼び出す grep と同じです。:grep
の代わりに :grep!
を使用することで [4]、最初に見つかった行に自動的に移動しないようになります。:grep
の実行後は、:copen
コマンドを実行すると、検索結果の一覧を見ることができます。
:grep
で使用する grep コマンドは、”grepprg” オプションで変更することができます。grep の引数の空白をエスケープすることに注意してください。
set grepprg=grep\ -nH
次のように、”grepprg” オプションの値を “internal” とすると、:grep
は :vimgrep
と同じになります。
set grepprg=internal
次回は「テキストオブジェクト」について解説する予定です。
[1] | Vim には QuickFixの他にロケーションリストというものもあり、QuickFix はグローバル(ひとつの Vim でひとつのみ)ですが、ロケーションリストはウインドウ毎に用意されています。 |
[2] | 今回の例では C 言語なので、”Makefile” がディレクトリ内に存在すれば動作します。しかし、ファイルタイプによっては、手動でビルド用のコマンドを指定しなければなりません。ビルド用のコマンドを指定するには、:compiler {コンパイラ名} というコマンドを使用します。詳しくは、:help compiler を参照してください。 |
[3] | コマンドの出力が邪魔な場合、:make の代わりに :silent
make を使用すると良いでしょう。 |
[4] | grep コマンドに限らず、Vim の場合はコマンド名の最後に !
(bang) を付加すると、元々の挙動を微妙に変えるようになっています。バッファをファイルに保存しなくても Vim を終了させる、:quit! コマンドが代表的です。 |