*quickfix.txt* For
Vim バージョン 7.3. Last change: 2011 May 10
VIMリファレンスマニュアル by Bram Moolenaar
この話題に関してはユーザーマニュアルの
|30.1|でも紹介されている。
1. QuickFixコマンドの使い方
|quickfix|
2. エラーウィンドウ
|quickfix-window|
3. 複数のエラーリストを使う
|quickfix-error-lists|
4. :makeの使い方
|:make_makeprg|
5. :grepの使い方
|grep|
6. コンパイラを選択する
|compiler-select|
7. エラーフォーマット
|error-file-format|
8. ディレクトリスタック
|quickfix-directory-stack|
9. 具体的なエラーファイルフォーマット
|errorformats|
{これらのコマンドはViには存在しない}
コンパイル時に
|+quickfix|機能が無効にされた場合は、QuickFixコマンドは使えない。
=============================================================================
1. QuickFixコマンドの使い方
*quickfix* *Quickfix* *E42*
Vimには編集-コンパイル-編集のサイクルを加速するための特別なモードがある。これ
はAmigaのManx's Aztec C compilerのquickfixオプションにインスパイアされた。Cコ
ンパイラから出力されたエラーメッセージをファイルに保存し、Vimでそのエラーにジャ
ンプするというアイディアである。エラーメッセージを全部覚えておかなくても、それ
ぞれの問題を検証し、修正することができる。
QuickFixコマンドはより一般的に、ファイル中の位置のリストを作成し、ジャンプする
ために使うことができる。例えば、
|:vimgrep|はパターンにマッチした位置をリストす
る。スクリプト中で
|getqflist()|を使ってこれらの位置を参照することができる。
そのため、編集・コンパイル・修正のサイクル以外にも多くの事に利用できる。
AmigaでManx's Aztec C compilerを使っているなら、Vimと連携させる方法について
|quickfix-manx|を見よ。別のコンパイラを使用するならば、エラーメッセージを一度
ファイルに保存してVimを"vim -q filename"で起動する。これをする簡単な方法の1つ
はコマンド
|:make|である(後述)。各コンパイラからのエラーメッセージを解釈させる
ためには、オプション
'errorformat'をセットする(下の
|errorformat|を参照)。
*location-list* *E776*
ロケーションリストはQuickFixリストに似ていて、ファイル中の位置のリストを保持す
る。ロケーションリストはウィンドウに関連付けられていて、各ウィンドウが別々のロ
ケーションリストを持つことができる。ロケーションリストは1個のウィンドウにだけ
関連付けることができる。ロケーションリストはQuickFixリストとは独立している。
ロケーションリストを持つウィンドウが分割されると、新しいウィンドウはロケーショ
ンリストのコピーを得る。ロケーションリストへの参照がなくなると、そのロケーショ
ンリストは破棄される。
以下のQuickFixコマンドが利用できる。ロケーションリストコマンドはQuickFixコマン
ドに似ていて、QuickFixコマンドのプレフィックス'c'が'l'に置き換わっている。
*:cc*
:cc[!]
[nr] エラー[nr]を表示する。[nr]が省略されると同じエラーが
再度表示される。[!]が無く、現在のバッファに変更が有り
ウィンドウが1つしか無く、
'hidden'も
'autowrite'もoffで
ある場合には、他のバッファへジャンプする事は無い。
[!]を使用して他のバッファに移る時、現在のバッファへの
変更点は、
'hidden'がセットされているか別のウィンドウが
開いているかしない場合、破棄されてしまう。
バッファ移動の際は設定
'switchbuf'が関係してくる。
*:ll*
:ll[!]
[nr] ":cc"と同様だが、QuickFixリストでなくカレントウィンド
ウのロケーションリストが使われる。
*:cn* *:cnext* *E553*
:
[count]cn[ext][!] ファイル名を含むエラーリストで
[count]個後のエラーを表
示する。ファイル名が無かった場合
[count]個後のエラーに
移動する。[!]と
'switchbuf'については
|:cc|を参照。
*:lne* *:lnext*
:
[count]lne[xt][!] ":cnext"と同様だが、QuickFixリストでなくカレントウィン
ドウのロケーションリストが使われる。
:
[count]cN[ext][!]
*:cp* *:cprevious* *:cN* *:cNext*
:
[count]cp[revious][!] ファイル名を含むエラーリストで
[count]個前のエラーを表
示する。ファイル名が無かった場合
[count]個前のエラーに
移動する。[!]と
'switchbuf'については
|:cc|を参照。
:
[count]lN[ext][!]
*:lp* *:lprevious* *:lN* *:lNext*
:
[count]lp[revious][!] ":cNext"と":cprevious"と同様だが、QuickFixリストでな
く、カレントウィンドウのロケーションリストが使われる。
*:cnf* *:cnfile*
:
[count]cnf[ile][!] ファイル名を含むエラーリストで
[count]個後のファイルの
最初のエラーを表示する。ファイル名が無いか後のファイル
が無い場合には、
[count]後のエラーに移動する。[!]と
'switchbuf'については
|:cc|を参照。
*:lnf* *:lnfile*
:
[count]lnf[ile][!] ":cnfile"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
:
[count]cNf[ile][!]
*:cpf* *:cpfile* *:cNf* *:cNfile*
:
[count]cpf[ile][!] ファイル名を含むエラーリストで
[count]個前のファイルの
最後のエラーを表示する。ファイル名が無いか後のファイル
が無い場合には、
[count]個前のエラーに移動する。[!]と
'switchbuf'については
|:cc|を参照。
:
[count]lNf[ile][!]
*:lpf* *:lpfile* *:lNf* *:lNfile*
:
[count]lpf[ile][!] ":cNfile"と":cpfile"と同様だが、QuickFixリストでなく、
カレントウィンドウのロケーションリストが使われる。
*:crewind* *:cr*
:cr[ewind][!]
[nr] [nr]のエラーを表示する。[nr]が省略されると一番最初の
エラーが表示される。
|:cc|を参照。
*:lrewind* *:lr*
:lr[ewind][!]
[nr] ":crewind"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
*:cfirst* *:cfir*
:cfir[st][!]
[nr] ":crewind"と同じ。
*:lfirst* *:lfir*
:lfir[st][!]
[nr] ":lrewind"と同じ。
*:clast* *:cla*
:cla[st][!]
[nr] [nr]のエラーを表示する。[nr]が省略されると一番最後の
エラーが表示される。
|:cc|を参照。
*:llast* *:lla*
:lla[st][!]
[nr] ":clast"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
*:cq* *:cquit*
:cq[uit][!] Vimをエラーとして終了することで、コンパイラが同じ
ファイルをコンパイルする事が無くなる。
警告: ファイルに対する変更はすべて失われる([!] を指定
しなくても)! このコマンドは、システムへの戻り値が非
零であるということ以外 ":qall!"
|:qall| と同じである。
*:cf* *:cfile*
:cf[ile][!]
[errorfile] エラーファイルを読みこみ最初のエラーへ移動する。Vimが
オプション-qで起動された時には自動的に行なわれる。
コンパイルの間Vimを実行したままにしたい時に使うことが
できる。エラーファイルの名前を与えればオプション
'errorfile'に[errorfile]が設定される。[!]については
|:cc|を参照。
*:lf* *:lfile*
:lf[ile][!]
[errorfile] ":cfile"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。コマンドライ
ンオプション-qを使ってロケーションリストを設定すること
はできない。
:cg[etfile]
[errorfile] *:cg* *:cgetfile*
エラーファイルを読み込む。":cfile"に似ているが、最初のエ
ラーに移動しない。
:lg[etfile]
[errorfile] *:lg* *:lgetfile*
":cgetfile"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
*:caddf* *:caddfile*
:caddf[ile]
[errorfile] エラーファイルを読み込み、現在のQuickFixリストにエラー
を追加する。QuickFixリストがまだない場合は、新しいリス
トが作成される。
*:laddf* *:laddfile*
:laddf[ile]
[errorfile] ":caddfile"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
*:cb* *:cbuffer* *E681*
:cb[uffer][!]
[bufnr] カレントバッファからエラーリストを読み込む。[bufnr]を
指定すると、カレントバッファの代わりにそのバッファが使
われる。bufnrには読み込まれているバッファ番号を指定しな
ければならない。範囲を指定すると、読み込む行を指定する
ことができる。範囲指定がないとバッファ全体が使われる。
[!]については
|:cc|を参照。
*:lb* *:lbuffer*
:lb[uffer][!]
[bufnr] ":cbuffer"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
*:cgetb* *:cgetbuffer*
:cgetb[uffer]
[bufnr] カレントバッファからエラーリストを読み込む。":cbuffer"
と同じだが、最初のエラーにジャンプしない点が異なる。
*:lgetb* *:lgetbuffer*
:lgetb[uffer]
[bufnr] ":cgetbuffer"と同様だが、QuickFixリストでなく、カレン
トウィンドウのロケーションリストが使われる。
*:caddb* *:caddbuffer*
:caddb[uffer]
[bufnr] カレントバッファからエラーリストを読み込み、現在の
QuickFixリストにエラーを追加する。QuickFixリストが存在
まだない場合は、新しいリストが作成される。それ以外は
:cbufferと同じ。
*:laddb* *:laddbuffer*
:laddb[uffer]
[bufnr] ":caddbuffer"と同様だが、QuickFixリストでなく、カレン
トウィンドウのロケーションリストが使われる。
*:cex* *:cexpr* *E777*
:cex[pr][!]
{expr} {expr} の結果を使って QuickFix リストを作成し、最初の
エラーにジャンプする。
{expr} が文字列のときは、その文字列を改行コードで区切
り、各行を
'errorformat' のグローバル値に従って解釈
し、結果を QuickFix リストに追加する。
{expr} がリストのときはリストの各文字列要素を解釈し、
QuickFix リストに追加する。リスト中の文字列でない要素
は無視される。
[!]については
|:cc|を参照。
例:
*:lex* *:lexpr*
:lex[pr][!]
{expr} |:cexpr|と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
*:cgete* *:cgetexpr*
:cgete[xpr]
{expr} {expr}の結果を使ってQuickFixリストを作成する。
|:cexpr|
と同様だが、最初のエラーにジャンプしない点が異なる。
*:lgete* *:lgetexpr*
:lgete[xpr]
{expr} |:cgetexpr|と同様だが、QuickFixリストでなく、カレ
ントウィンドウのロケーションリストが使われる。
*:cad* *:caddexpr*
:cad[dexpr]
{expr} {expr}を評価し、結果の行を現在のQuickFixリストに追加す
る。QuickFixリストがまだ無い場合は、新しいリストが作成
される。現在のカーソル位置は変わらない。より詳しくは
|:cexpr|を参照。
例:
*:lad* *:laddexpr*
:lad[dexpr]
{expr} ":caddexpr"と同様だが、QuickFixリストでなく、カレ
ントウィンドウのロケーションリストが使われる。
*:cl* *:clist*
:cl[ist]
[from] [,
[to]]
有効なエラーを全て列挙する
|quickfix-valid|。[from]及び
もしくは[to]で行数を指定された場合、その範囲のエラーが
表示される。負であった場合最後のエラーから数える。-1
が最後のエラーとなる。設定
'switchbuf'がバッファの移動
に関係する。
:cl[ist]!
[from] [,
[to]]
全てのエラーを表示する。
*:lli* *:llist*
:lli[st]
[from] [,
[to]]
":clist"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
:lli[st]!
[from] [,
[to]]
カレントウィンドウのロケーションリストの中身を全部表示
する。
正しいエラーの位置は隠されたマークによって示されているので、例え行を挿入したり
削除したとしても問題はない(Manx's Z editorではそうではない)。時々マークが幾つ
かの理由で消されてしまう事があり、メッセージ"line changed"がその警告となる。
一度Vimを終了し再起動した場合マークは失われ正しいエラー位置は把握できない。
Vimが
|+autocmd|機能つきでビルドされている場合、QuickFixコマンド(':make',
':grep'など)を実行する前後に2つの自動コマンドが利用できる。詳しくは
|QuickFixCmdPre|と
|QuickFixCmdPost|を参照。
*QuickFixCmdPost-example*
'encoding' とロケールが異なる場合、コンパイラのエラーメッセージと Vim 内部のエ
ンコーディングが異なる場合がある。次のようにすれば、このメッセージを変換でき
る:
=============================================================================
2. エラーウィンドウ
*quickfix-window*
*:cope* *:copen* *w:quickfix_title*
:cope[n]
[height] 現在のエラーリストを表示するウィンドウを開く。
[height]が与えられたとき、(余地があれば)ウィンドウの
高さがその値になる。与えられなければウィンドウの高さは
10行になる。
ウィンドウは
'buftype'の値が"quickfix"である特別なバッ
ファを含んでいる。これを変更してはならない。
すでにQuickFixウィンドウがある場合はそれがカレントウィ
ンドウになる。2個目のQuickFixウィンドウを開くことは出
来ない。ウィンドウの w:quickfix_title 変数を設定するこ
とで、エラーリストを生成したコマンドを表示するようなこ
とができる。変数の値は
'statusline' が適切に調整されて
いればステータスラインに表示される。
*:lop* *:lopen*
:lop[en]
[height] カレントウィンドウのロケーションリストを表示するウィン
ドウを開く。カレントウィンドウにロケーションリストが存
在するときだけ動作する。一度に2個以上のロケーションリ
ストを開くことができる。それ以外は":copen"と同様。
*:ccl* *:cclose*
:ccl[ose] QuickFixウィンドウを閉じる。
*:lcl* *:lclose*
:lcl[ose] カレントウィンドウのロケーションリストを表示している
ウィンドウを閉じる。
*:cw* *:cwindow*
:cw[indow]
[height] 認識されたエラーがあるときQuickFixウィンドウを開く。
ウィンドウがすでに開いていて認識されたエラーがない
場合はウィンドウを閉じる。
*:lw* *:lwindow*
:lw[indow]
[height] ":cwindow"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
通常、QuickFixウィンドウはスクリーンの一番下に現れる。垂直分割したウィンドウが
ある場合は、一番右下に現れる。常に最大幅を占めるようにさせたい場合は
:botright cwindow
とする。このウィンドウを
|window-moving|コマンドで移動させることもできる。
例えば、一番上に移動させたければ
CTRL-W Kとする。
'winfixheight'オプションが設定されれば、
'winheight'と
'equalalways'を無視し、た
いていその高さを維持する。高さを手動で変更することも出来る(例えばステータスラ
インをマウスで上へドラッグするなど)。
QuickFixウィンドウには各行に1個ずつエラーが表示される。その行数はエラー番号に
等しい。":.cc"でカーソル下のエラーに移動できる。
<Enter>キーを押すのと行をダブ
ルクリックするのは同じ効果がある。そのエラーを含むファイルがQuickFixウィンドウ
の上に開かれる。そのファイルがすでにウィンドウに開かれていたらそのウィンドウが
アクティブになる。そのウィンドウにあるバッファが変更されていて、そのエラーが別
のファイルにある場合はエラーへの移動は失敗する。まず、そのウィンドウが破棄して
もよいバッファを含んでいることを確かめなければならない。
*CTRL-W_<Enter>* *CTRL-W_<CR>*
CTRL-W <Enter>を使うと、新しいウィンドウを開いてそこでエラーにジャンプできる。
QuickFixウィンドウが一杯になったとき、2つの自動コマンドイベントが発生する。第
一は
'filetype'オプションが"qf"にセットされ、FileTypeイベントが発生する。それか
らBufReadPostイベントが発生する。そのときのバッファ名は"quickfix"となる。これを
使ってエラーリストに対して操作を行うことができる。例:
au BufReadPost quickfix setlocal modifiable
\ | silent exe 'g/^/s//\=line(".")." "/'
\ | setlocal nomodifiable
これは各行に行番号を追加する。文字列の置換":s"コマンドの中で使われている"\="に
注目。これは式を評価するのに使われる。
BufWinEnterイベントも発生する。ここでもバッファ名は"quickfix"になる。
注意:QuickFixウィンドウ内で変更を加えてもエラーのリストには何の影響もない。変
更を防ぐために
'modifiable'がオフになっている。それでも行を削除や挿入した場合
は、テキストとエラー番号の関係がめちゃくちゃになる。本当にエラーリストを変更し
たいのなら、QuickFixウィンドウの内容をファイルに保存し、":cfile"を実行、ファイ
ルをパースさせ、新しいエラーリストとして使うこと。
*location-list-window*
ロケーションリストウィンドウはロケーションリストの中身を表示する。ロケーション
ウィンドウを開くと、カレントウィンドウに下に開かれ、カレントウィンドウのロケー
ションリストが表示される。ロケーションリストはQuickFixウィンドウに似ているが、
一度に2個以上のロケーションリストウィンドウを開ける点が異なる。このウィンドウ
内でロケーションリストコマンドを使うと、表示されているロケーションリストが使わ
れる。
ロケーションリストウィンドウからファイルを選択すると、以下のステップによって、
そのファイルを編集するウィンドウが探される。
1. ロケーションリストウィンドウに表示されているロケーションリストに関連付けら
れているウィンドウがあるなら、そのウィンドウが使われる。
2. 上のステップが失敗した場合、そのファイルが既に他のウィンドウで開かれている
なら、そのウィンドウが使われる。
3. 上のステップが失敗した場合、
'buftype'がセットされていないバッファを表示して
いるウィンドウが存在するなら、そのウィンドウが使われる。
4. 上のステップが失敗した場合、新しいウィンドウでファイルが開かれる。
上の全ての場合において、選択されたウィンドウに対してまだロケーションリストが関
連付けられていなかった場合、ロケーションリストウィンドウに表示されているロケー
ションリストが関連づけられる。
=============================================================================
3. 複数のエラーリストを使う
*quickfix-error-lists*
これまでは一つだけのエラーリストがあると仮定してきた。実際は最後に使った10個
迄のエラーリストが記憶される。新しいリストではじめた時には、以前のリストは自動
的に保存される。古いエラーリストにアクセスするために、2つのコマンドが用意され
ている。これらは存在するエラーリストの内1つを現在のエラーリストに設定する。
*:colder* *:col* *E380*
:col[der]
[count] 古いエラーリストへ移動する。
[count]が与えられると、
その回数繰り返し移動する。既に一番古いエラーリストに
いる場合、エラーメッセージが表示される。
*:lolder* *:lol*
:lol[der]
[count] ":colder"と同様だが、QuickFixリストでなく、カレン
トウィンドウのロケーションリストが使われる。
*:cnewer* *:cnew* *E381*
:cnew[er]
[count] 新しいエラーリストへ移動する。
[count]が与えられると、
その回数繰り返し移動する。既に一番新しいエラーリストに
いる場合、エラーメッセージが表示される。
*:lnewer* *:lnew*
:lnew[er]
[count] ":cnewer"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
新しいエラーリストが追加された時には、それがカレントリストとなる。
":colder"が実行された後で":make"や":grep"が実行され新しいエラーリストが追加さ
れたときは1個新しいリストが上書きされる。これは":grep"
|grep|でブラウジングし
ているときに特に便利である。もっと最近のエラーリストを残しておきたい場合は初め
に":cnewer 99"を行うこと。
=============================================================================
4. :makeの使い方
*:make_makeprg*
*:mak* *:make*
:mak[e][!]
[arguments] 1. vimが
|+autocmd|つきでビルドされているならば、
|QuickFixCmdPre|に関連付けられた自動コマンドが全て
実行される。
2, オプション
'autowrite'がonならば変更のあるバッファは
保存される。
3.
'makeef'からエラーファイルの名前が生成される。
'makeef'が"##"を含まずかつ既に名前が存在する場合
それは削除される。
4. オプション
'makeprg'で与えられたプログラム(省略時
"make")が[argument]をオプションにして実行され、
出力がerrorfileに保存される(Unixではそれも画面に
echoされる)。
5.
'errorformat'を使ってerrorfileが読みこまれる。
6. vimが
|+autocmd|つきでビルドされているならば、
|QuickFixCmdPost|に関連付けられた自動コマンドが全て
実行される。
後述のサンプルを参照。
7. [!]が与えられていないときは最初のエラーに移動する。
8. エラーファイルが削除される。
9.
|:cnext|や
|:cprevious|などのコマンドでエラー間を移動
できる。上を参照。
このコマンドは如何なるコメントも受けつけず、どんな "
という文字もargumentの一部とみなされる。
*:lmak* *:lmake*
:lmak[e][!]
[arguments]
":make"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
コマンド":make"はオプション
'makeprg'で与えられるコマンドを実行する。これは
オプション
'shell'で与えられたシェルにコマンドを渡す事で実行されている。以下を
タイピングするのとほぼ同じである。
":!
{makeprg} [arguments] {shellpipe} {errorfile}".
{makeprg}は
'makeprg'オプションで指定された文字列である。"make"に限らず、どんな
コマンドでも使用できる。'%'と'#'の文字は通常通りコマンドライン中で展開される。
拡張子無しの現在ファイル名を表すのに"%<"、拡張子無しの代替ファイル名を表すのに
"#<"が使える。例えば:
:set makeprg=make\ #<.o
[arguments] ":make"より後に入力した全て。
{shellpipe} オプション
'shellpipe'
{errorfile} オプション
'makeef'。"##"は一意な名前にする
コマンドがargumentsの後にオプションを必要とするならば、
{makeprg}の中で引数リス
トに展開される置換子"$*"が使用できる。$*は引数全てに置換えられる。例:
:set makeprg=latex\ \\\\nonstopmode\ \\\\input\\{$*}
またはより単純に
:let &mp = 'latex \\nonstopmode \\input\{$*}'
"$*"は次の例のように何度でも与える事ができる:
:set makeprg=gcc\ -o\ $*\ $*
オプション
'shellpipe'の省略値はAmiga、MS-DOSとWin32では">"である。これはコンパ
イラの出力が直接ファイルに出力されスクリーンには出力されないことを意味する。
Unixでは"| tee"が使用される。コンパイラがファイルに出力すると同時にスクリーン
にも表示される。使っているシェルに応じて標準エラーへの出力も含めるために
"|& tee"や"2>&1| tee"が省略値となる。
'shellpipe'が空の場合、
{errorfile}が省略される。これはコンパイラ自身がエラー
ファイルを作成する場合(Manx's Amiga C)に便利である。
QuickFixCmdPost を使ってエンコーディングを修正する
ビルドプログラムが出力するメッセージと
'encoding' の値が異なる場合がある。この
例は、Vim がそのエラーメッセージを読み込んだ後でエンコーディングを変換する方法
を示している:
(Faque Cheng による例)
==============================================================================
5. :vimgrepと:grepの使い方
*grep* *lid*
Vimにはパターンを検索する方法が2つある: 内部grepと外部grepである。内部grepの利
点は、全てのシステム上で動作し、Vimの強力な検索パターンを使えることである。内
部grepが目的に合わない場合は外部grepを使うことができる。
内部grepはファイルをメモリに読み込むため、より遅い。利点は:
- ファイルを開くときと同様に改行コードとエンコーディングが自動的に認識される。
- Vimの検索パターンを使う。複数行にわたるパターンが使える。
- プラグインが有効になっていれば、圧縮ファイル、リモートファイルを検索できる。
|gzip| |netrw|
これを行うために、Vimは各ファイルを編集するときと同じように読み込む。そのファ
イルにマッチがなかったら、そのバッファは消去(wiped out)される。多数のファイル
を扱うときのメモリ不足やファイル記述子不足を避けるために、ここではオプション
'hidden'は無視される。しかし、コマンド修飾子
|:hide|が使われたときは、バッファ
が読み込まれたままになる。これによって、同じファイルを続けて検索するのがとても
高速になる。
Note: 検索結果へのリンク一覧を開くには
|:copen| (
|:lgrep| なら
|:lopen|) が使
われる。
|:silent| コマンドを使うことで grep の出力が画面いっぱいに表示されるの
を防ぐことができる。
|:grep| コマンドを ":grep!" 形式で使うと最初のマッチに自動
的にジャンプしなくなる。これらのコマンドを組み合わせて NewGrep コマンドを作る
と次のようになる:
5.1 Vimの内部grepの使い方
*:vim* *:vimgrep* *E682* *E683*
:vim[grep][!] /
{pattern}/[g][j]
{file} ...
ファイル
{file}から
{pattern}を検索し、マッチ位置をエ
ラーリストに追加する。
フラグ'g'がない場合、各行は1度だけ追加される。
'g'がある場合、マッチ位置が毎回追加される。
{pattern}はVimの検索パターンである。/で囲まない場合、
それが
{pattern}中に現れない限り、どんな非ID文字
(
|'isident'|を参照)でも使える。
'ignorecase'が適用される。パターン中に
|/\c|を含めると
大文字小文字を区別しなくなり、
|/\C|を含めると区別する
ようになる。これは
'ignorecase'より優先される。
'smartcase'は適用されない。
このコマンドの前に数字が置かれると、その数が検索する
マッチの最大数となる。":1vimgrep pattern file"とすると
最初のマッチだけを検索する。マッチが存在するかどうかだ
けをチェックしたく、それが見つかったらすぐに終了してほ
しい場合に便利である。
フラグ'j'がない場合、最初のマッチへジャンプする。
'j'がある場合はQuickFixリストが更新されるだけである。
[!]がついた場合、カレントバッファに対する変更は全て失
われる。
進行状況を示すため、1秒程度ごとに検索されたファイル名
が表示される。
例:
"**"の使い方については
|starstar-wildcard|を参照。
:vim[grep][!]
{pattern} {file} ...
上と同様だが、パターンを非ID文字で囲むのでなく、空白
でパターンを区切る。パターンはID文字で始まらねばなら
ない。
例:
*:lv* *:lvimgrep*
:lv[imgrep][!] /
{pattern}/[g][j]
{file} ...
:lv[imgrep][!]
{pattern} {file} ...
":vimgrep"と同様だが、新しくエラーリストを作る代わり
に、現在のリストに追加する。
*:vimgrepa* *:vimgrepadd*
:vimgrepa[dd][!] /
{pattern}/[g][j]
{file} ...
:vimgrepa[dd][!]
{pattern} {file} ...
":vimgrep"と同様だが、QuickFixリストでなく、カレン
トウィンドウのロケーションリストが使われる。
*:lvimgrepa* *:lvimgrepadd*
:lvimgrepa[dd][!] /
{pattern}/[g][j]
{file} ...
:lvimgrepa[dd][!]
{pattern} {file} ...
":vimgrepadd"と同様だが、QuickFixリストでなく、カレン
トウィンドウのロケーションリストが使われる。
5.2 外部grep
Vimはコンパイラに対するのと同じ方法(
|:make|参照)で"grep"やGNU id-utilsなどの
grepライクなプログラムと連携できる。
[Unix豆知識:Unixのコマンド"grep"の名前は":g/re/p"に由来している。"re"はRegular
Expression(正規表現)を意味する。]
*:gr* *:grep*
:gr[ep][!]
[arguments] ":make"と同じようにしかし
'makeprg'の代りに
'grepprg'が
'errorformat'の代りに
'grepformat'が使われる。
'grepprg'が"internal"の場合、
|:vimgrep|と同様に機能す
る。その場合、パターンが区切り文字が囲まれていなければ
ならないことに注意。
*:lgr* *:lgrep*
:lgr[ep][!]
[arguments] ":grep"と同様だが、QuickFixリストでなく、カレントウィ
ンドウのロケーションリストが使われる。
*:grepa* *:grepadd*
:grepa[dd][!]
[arguments]
":grep"と似ているが、新しいエラーリストを作らず、解釈さ
れたエラーが現在のリストに追加される。
Example:
1番目のコマンドは新しい空のエラーリストを作成する。2
番目のコマンドはバッファリスト内の各バッファに対し
"grepadd"を実行する。最初のエラーへジャンプするのを避け
るために!を使っていることに注意。
|:bufdo|でジャンプする
ことはできない。
引数リスト内のファイルに対して実行し、マッチがないファ
イルでのエラーを回避する例:
*:lgrepa* *:lgrepadd*
:lgrepa[dd][!]
[arguments]
":grepadd"と同様だが、QuickFixリストでなく、カレント
ウィンドウのロケーションリストが使われる。
5.3 grepをセットアップする
標準的な"grep"プログラムがインストールされていれば:grepコマンドはデフォルトの
ままで動くだろう。使い方は標準的なコマンドにとてもよく似ている:
:grep foo *.c
これは拡張子.cの全てのファイルの中から部分文字列"foo"を検索する。:grepへの引数
はそのまま"grep"プログラムに渡されるので、その"grep"がサポートするオプションは
なんでも使うことができる。
デフォルトでは:grepはgrepを-nオプションつきで呼び出す(これはファイル名と行番号
を出力させる)。これは
'grepprg'オプションで変更できる。次のような場合に
'grepprg'
を変更する必要があるだろう:
a) "grep"以外の名前のプログラムを使っているとき
b) grepをフルパスで呼ばなければならないとき
c) 他のオプションを自動的に渡したいとき(例:大文字・小文字の無視)
"grep"が実行されると、Vimはその結果を
'grepformat'オプションに従って解釈する。
このオプションは
'errorformat'オプションと同様にはたらくので詳細はそちらを参照
すること。あなたのgrepが標準的でない書式で出力したり、あるいは特別な書式を持つ
他のプログラムを使っている場合は
'grepformat'をデフォルト値から変更する必要が
あるだろう。
結果が解釈されると、
|quickfix|モードにおけるコンパイルエラーと同様に、Vim
はマッチした部分を含む最初のファイルを読み込み、対応した行へジャンプする。その
後は
|:cnext||,||:clist|などのコマンドを使って他のマッチにジャンプすることが出来
る。
5.4 id-utilsと共に:grepを使う
:grepをGNU id-utilsと共に使うにはこのようにする:
:set grepprg=lid\ -Rgrep\ -s
:set grepformat=%f:%l:%m
そして
:grep (regexp)
これで期待通りの動作をする。
(最初にmkidをするのを忘れていなければ)
5.5 :vimgrepや:grepを使ってソースコードをわたり歩く
Vimが保存するエラーリストのスタックを使うことによって、ファイルをわたり歩き、
関数とその関数が呼んでいる関数を探すことができる。例えば、read_file()関数に引
数を加えたいとする。次のようにコマンドを打てばよい:
:vimgrep /\<read_file\>/ *.c
:cnでマッチのリストを巡り、引数を加えることが出来る。またあるとき上位の関数msg
()から新しい引数を得て、それを変更しなければならないとする。ならばこうするとよ
い:
:vimgrep /\<msg\>/ *.c
msg()関数を変更しているときに、上位から引数を得なければならない関数をもう1個
見つけたとする。ならばその関数を見つけるのにまた":vimgrep"を使えばよい。1つの
関数が終わったら、
:colder
とすれば1つ前に戻ることができる。
これはツリーをわたるのに似ている:":vimgrep"が1レベル深く進むにつれて、分岐の
リストが1つ作られる。":colder"は1つ上に戻る。":vimgrep"と":colder"を使ってツ
リーに似た方法ですべての場所をわたることができる。これを一貫して行えば、"todo"
のリストを書き留めることなく、すべての場所に行くことができる。
=============================================================================
6. コンパイラを選ぶ
*compiler-select*
*:comp* *:compiler* *E666*
:comp[iler][!]
{name} コンパイラ
{name}を使うときに機能するオプション
を設定する。"!"オプションがない場合は現在の
バッファに対して設定される。"!"がある場合はグ
ローバルオプションが設定される。
"file.foo"で":compiler foo"とし、その後別の
バッファで":compiler! bar"としたとき、Vimは
"file.fo o"では"foo"を使い続ける。
{
|+eval|機能なしでコンパイルされた場合には使用
できない}
"compiler"ディレクトリ内にあるVimプラグインによって、選択されたコンパイラを使
うためのオプションが設定される。":compiler"はローカルオプションを設定し、"compi
ler!"はグローバルオプションを設定する。
*current_compiler*
Vimの古いバージョンをサポートするために、それらのプラグインは常に"b:current_com
piler"でなく"current_compiler"を使う。このコマンドが実際に行うことは次の通り:
- 変数"current_compiler"と"b:current_compiler"を削除する
- ユーザーコマンド"CompilerSet"を定義する。"!"がついた場合は":set"を行い、"!"が
無い場合は":setlocal"を実行する。
- ":runtime! compiler/
{name}.vim"を実行する。このプラグインは"CompilerSet"に伴
うオプションを設定し、変数"current_compiler"をそのコンパイラの名前に設定する
と期待される。
- ユーザーコマンド"CompilerSet"を削除する。
- "b:current_compiler"を"current_compiler"の値に設定する。
- "!"が無い場合は"current_compiler"の元の値を復元する。
コンパイラプラグインを書くためには
|write-compiler-plugin|を参照せよ。
GCC *quickfix-gcc* *compiler-gcc*
GCC用に設定できる変数は1つある:
g:compiler_gcc_ignore_unmatched_lines
GCC用に定義されたどのパターンにもマッチしない
行を無視する。makeから起動されたコマンドの出力
のせいで誤検出(false positive)が発生してしまう
ときに有用である。
MANX AZTEC C *quickfix-manx* *compiler-manx*
Amiga上でManx's Aztec C compilerとともにVimを使うには次のようにする:
- 環境変数CCEDITを次のコマンドで設定する:
mset "CCEDIT=vim -q"
- -qfオプションをつけてコンパイルする。もしコンパイラがエラーを見つけたらVimが
カーソルを最初のエラーの上に置いた状態で起動する。エラーメッセージは最後の行
に表示される。上で述べたコマンドを使って他のエラーへ移動することができる。エ
ラーを修正し、ファイルを保存できる。
- Vimを普通に終了するとコンパイラが同じファイルを再コンパイルする。:cqコマンド
で終了した場合はコンパイラは終了する。エラーを修正できないときや、まず他の
ファイルをコンパイルする必要があるときはそうするとよい。
AmigaにおけるQuickfixモードには他にも制限がある。コンパイラは最初の25個のエ
ラーしか出力しない(Manx'sのドキュメントにはそれ以上出力する方法が書かれていな
い)。それ以上のエラーを探したいのならば、幾つかのエラーを修正しエディタを抜け
る必要がある。再コンパイルの後残り25個のエラーが出てくる
Vimがコンパイラから起動された場合、:shやいくつかの:!コマンドは機能しない。Vim
がコンパイラと同じプロセスの中で動いているため、標準出力が利用できないからで
ある。
PERL *quickfix-perl* *compiler-perl*
Perl コンパイラプラグインはコンパイルはしないが、Perl 内部の構文チェック機能を
呼び出し、その出力を解析してエラーを QuickFix モードで修正できるようにする。
チェックするファイルの中に "no warnings" または "$^W = 0" と書いてあっても関係
なく警告が表示される。これを無効にするには g:perl_compiler_force_warnings に 0
を代入する。例:
PYUNIT COMPILER *compiler-pyunit*
これは実際にはコンパイラではなく、Python言語用のユニットテストフレームワークで
ある。PYUNITはバージョン2.0からPython標準ディストリビューションに含まれるよう
になった。それより古いバージョンは
http://pyunit.sourceforge.net
で入手できる。
フレームワークの助けを借りてテストを走らせるとき、エラーがあればVimによって解
釈され、QuickFixモードで表示される。
残念ながら、テストを走らせる標準的な方法はない。alltests.pyスクリプトがよく使
われると思われるが、それだけである。
よって、
'makeprg'に対する実用的な値は
setlocal makeprg=./alltests.py " テストスイートを走らせる
setlocal makeprg=python % " 1つのテストケースを走らせる
となる。
次も参照。
http://vim.sourceforge.net/tip_view.php?tip_id=280.
TEX COMPILER *compiler-tex*
ディストリビューションに含まれているTeX用のコンパイラスクリプト($VIMRUNTIME/com
piler/tex.vim)は、可能ならmakeコマンドを使う。コンパイラがカレントディレクトリ
に"Makefile"または"makefile"というファイルを見つけたら、*TeXファイルをmakeを
使って処理しようとし、そのmakefile通りの動作をする。この場合コンパイラ
は'errorfor mat'を*TeX出力用にセットし、
'makeprg'は触らずにそのままにしてお
く。"Makefie"も" makefile"も見つからない場合はコンパイラはmakeを使わない。
makefileを無視するように指定することもできる。変数b:tex_ignore_makefileかg:tex_
ignore_makefileを設定すればよい(これらは存在するかのみチェックされる)。
コンパイラがmakeを使わないことになったら、コンパイラは入力を処理するプログラム
を選択する。変数b:tex_flavorかg:tex_flavor(この順で探される)が存在すれば、そ
れが:makeコマンドのためのオプションを定義する。もし両方とも存在しなければ、既
定値"latex"になる。例えば、AMS-TeXで書かれたmypaper.texから\input-ed chapter2.t
exを編集中に
[editing...]
処理するファイルの名前を引数に指定しなければならないことに注意(\input-edか\inc
lude-edファイルを編集中に正しいファイルを処理するため;%を引数なしに置換する
ポータブルな方法もよい)。これはソースではなく、ターゲットを指定するというmake
の意味論ではないが、拡張子".tex"を除いたファイル名を指定してもよい。その場合、
「"filename.dviまたはfilename.pdfまたは filename.some_result_extension
をメイクしろ」ということを意味する。
注意:tex コマンドライン文法はMikTex(Srinath Avadhanulaによって提案された)とte
TeX(Artem Chuprinaによってチェックされた)の両方で使えるように設定されている。
|errorformat-LaTeX|からの提案は他のシェルやOSで動かせるようにするには複雑すぎる
し、他のTeXオプションを使うことも許さない。もしあなたのTeXが"-interaction=nonst
opmode"をサポートしていなければ、コマンドラインから\nonstopmodeを表現する他の
方法とともにその旨を報告してください。
=============================================================================
7. エラーフォーマット
*error-file-format*
*errorformat* *E372* *E373* *E374*
*E375* *E376* *E377* *E378*
'errorformat'オプションは認識されるエラーフォーマットのリストを指定する。その
中からエラーメッセージにマッチした最初のフォーマットが使われる。複数のフォーマッ
トを指定して、数種類のメッセージに対応したり、複数のコンパイラに対応したりする
ことができる。
|efm-entries|を参照。
'errorformat'の各要素は、scanfに似たフォーマットを記述する文字列である。はじめ
に、scanfがどのようにはたらくか知る必要がある。Cコンパイラのドキュメントを読ん
でください。以下はVimが理解する%の項目である。他は無効になる。
'errorformat'中の特別な文字はコンマとバックスラッシュである。それがどう扱われ
るかは
|efm-entries|を参照。"%%"はリテラル"%"にマッチする。よってこれはバック
スラッシュでエスケープしない。
注意:デフォルトでは大文字と小文字の違いは無視される。もし大文字・小文字の区別
をしたいなら"\C"をパターンに付け加える
|/\C|。
基本要素
%f ファイル名(文字列を検索)
%l 行番号(数字を検索)
%c 桁番号(エラーの桁を表す数字(
<Tab>1個は1桁と数える))
%v 画面上の桁番号(エラーの画面上の桁を表す番号(
<Tab>1個
はスクリーン上8桁と数える)
%t エラーの種類(1文字を検索)
%n エラー番号(数字を検索)
%m エラーメッセージ(文字列を検索)
%r その行の残り全部 %O/%P/%Q
%p ポインタ行('-', '.', ' 'の列を検索し、その長さを桁
番号とする)
%*
{conv} scanfに割り当てられない変換
%% 1個のリテラル'%'
%s テキスト検索 (文字列を検索)
"%f"の変換は現在の
'isfname'の設定に依存する。"~/"はホームディレクトリ名に展開
され、環境変数も展開される。
変換"%f"と"%m"はその文字列の終端を検出しなければならない。通常は、後に続く文字
と要素がマッチすれば、そこが終端になる。もし後に続く要素がなかったら、その行の
残りの部分がマッチする。"%f"の後に'%'かバックスラッシュが続いているなら、それ
は
'isfname'文字の列を検索する。
MS-DOS, MS-Windows and OS/2では、"C:"で始まる部分は"%f"に含まれる。"%f:"と指定
したときでもそうなる。これはアルファベット1文字の名前のファイルは検出されない
ことを意味する。
"%p"の後には通常"^"をつける。これは、以下のような出力によってエラーの桁を示す
コンパイラ用に使える:
または
これは複数行のエラーメッセージでも使える。実用的なサンプルとしては
|errorformat-javac|を参照。
"%s"はエラー行の位置を探すためのテキストを指定する。そのテキストは文字列リテ
ラルして使われる。検索テキストに正確にマッチするエラー行を探すために、"^"と"$"
がテキストに加えられる。また、テキストの先頭に"\V"が追加され、"very nomagic"と
される。"%s"はエラー出力中の行番号がない行を探すために使うことができる。シェル
コマンド"grep"の出力のように。
パターンがある場合は行番号は使われない。
ディレクトリを変更する
次の大文字の変換文字は、特別なフォーマット文字列のタイプを指定する。これらのう
ち高々1つをコンマ区切りのフォーマットパターンの先頭につけることができる。
"%f"によって読まれるファイル名の前につけたす必要があるディレクトリ名を出力する
コンパイラがある(例:GNU make)。以下のコードはそれらのディレクトリ名を解釈す
るのに使われる。そのディレクトリ名は内部のディレクトリスタックに保存される。
*E379*
%D "enter directory" フォーマット文字列。これ以下の%fはそ
のディレクトリ名を検索する。
%X "leave directory" フォーマット文字列。これ以下の%fは
ディレクトリスタックの1つ前のディレクトリを検索する。
"enter directory"や"leave directory"フォーマットを定義する場合、"%D"や"%X"は部
分文字列の最初に置かれなけれならない。Vimはディレクトリ変更を追跡し
相対パスによって指定されたファイル名の前にカレントディレクトリ名をつけたす。
Tipsや制限など詳細は
|quickfix-directory-stack|を参照。
複数行にわたるメッセージ
*errorformat-multi-line*
複数行メッセージにわたるメッセージを解釈することも可能である。取りうるプリ
フィックスは:
%E 複数行エラーメッセージの開始
%W 複数行警告メッセージの開始
%I 複数行情報メッセージの開始
%A 複数行メッセージの開始(種類指定なし)
%> 現在と同じパターンで始まっている次行
|efm-%>|
%C 複数行メッセージの継続
%Z 複数行メッセージの終了
これらに対して'+'と'-'をつけることもできる。
|efm-ignore|を参照。
パターンに"\n"を含めても、複数行のメッセージにはマッチしない。
例:コンパイラが次のフォーマットでエラーを出力したとする。
(行頭の行番号は実際の出力の一部ではない):
1 Error 275
2 line 42
3 column 3
4 ' ' expected after '--'
適切なエラーフォーマット文字列はこのようになる:
:set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
すると、このエラーに対し
|:clist|が表示するエラーメッセージはこのようになる:
1:42 col 3 error 275: ' ' expected after '--'
別の例:次のエラーメッセージを出力するPythonインタープリタを考える。
(行頭の行番号は実際の出力の一部ではない):
1 ==============================================================
2 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
3 --------------------------------------------------------------
4 Traceback (most recent call last):
5 File "unittests/dbfacadeTest.py", line 89, in testFoo
6 self.assertEquals(34, dtid)
7 File "/usr/lib/python2.2/unittest.py", line 286, in
8 failUnlessEqual
9 raise self.failureException, \
10 AssertionError: 34 != 33
11
12 --------------------------------------------------------------
13 Ran 27 tests in 0.063s
このメッセージに関する情報だけを
|:clist|で表示させたいところだろう。
このように:
5 unittests/dbfacadeTest.py:89: AssertionError: 34 != 33
そのためにはエラーフォーマット文字列を次のように定義する:
:set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
"%C"を"%A"の前に置いていることに注意:' %.%#'(これは正規表現' .*'を意味する)
がスペースで始まるすべての行にマッチするので、それが7行目を以降を隠してくれ
る。そうでないと7行目は別のエラーメッセージの始まりと解釈されてしまう。エラー
フォーマットは常に、リストの中から1つ1つ、最初のマッチが起こるまで試されてい
く。
*efm-%>*
要素%>は
'errorformat'の最初の方に出てくるパターンを試すのを避けるために使え
る。これはほとんど何にでもマッチするパターンに便利である。例えば、エラーが
このようなら:
Error in line 123 of foo.c:
unknown variable "i"
これは以下でマッチできる:
ここで"xxx"には2番目の行にもマッチするパターンが入るとする。
重要: エラーフォーマットのどの部分が以前にマッチしたかは記憶されていない。すな
わち、エラーファイルの各行が毎回エラーフォーマットの各行に対してテストされる。
例えば、次のようになっているとする:
ここでaa, bbなどはエラーフォーマット文字列とする。エラーファイルの各行がパター
ンaa,次にbb,次にcc…とテストされる。ccがエラーの1つ前の行にマッチしたからといっ
て、ddが現在行に対して最初にテストされるということにはならない。ccとddが複数行
エラーフォーマット文字列だったとしても、である。
ファイル名を分割する
*errorformat-separate-filename*
1度現れたファイル名を複数のメッセージが参照する場合には、これらのプリフィック
スが有効である。
%O 1行ファイルメッセージ:マッチ部分を読み込む(それ以前
に記憶されていたものは消去される)
%P 1行ファイルメッセージ:ファイル%fをスタックにプッシュ
する。
%Q 1行ファイルメッセージ:スタックから最後のファイル名を
ポップする。
例:次のエラーログファイルを出力するコンパイラがあるとする(行番号は実際の出力
ではない)
1 [a1.tt]
2 (1,17) error: ';' missing
3 (21,2) warning: variable 'z' not defined
4 (67,3) error: end of file found before string ended
5
6 [a2.tt]
7
8 [a3.tt]
9 NEW compiler v1.1
10 (2,2) warning: variable 'x' not defined
11 (67,3) warning: 's' already defined
このログファイルは[...]で囲まれたファイルに対し複数のメッセージを示している。
これは次のエラーフォーマットで適切に解釈できる:
:set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
|:clist|を呼ぶとこれらをファイル名とともに適切に表示してくれる。:
2 a1.tt:1 col 17 error: ';' missing
3 a1.tt:21 col 2 warning: variable 'z' not defined
4 a1.tt:67 col 3 error: end of file found before string ended
8 a3.tt:2 col 2 warning: variable 'x' not defined
9 a3.tt:67 col 3 warning: 's' already defined
行全体にマッチする他のプリフィックスとは違い、%P, %Q, %Oは同一行の複数のパター
ンにマッチさせるのに使える。それゆえ、次のようにファイルがネストした場合を解釈
することも出来る:
{"file1" {"file2" error1} error2 {"file3" error3 {"file4" error4 error5}}}
%Oはファイル名情報のプッシュ・ポップを含まない文字列を解釈する。発展例について
は
|errorformat-LaTeX|を参照。
メッセージ全体を無視する・使う
*efm-ignore*
'+','-'は大文字の指定文字と組み合わせて使う。'%+A'や'%-G'のように指定文字の前
につける。
%- 複数行のマッチを含まない。
%+ エラー文字列%m中でマッチした行全体
プリフィックス%Gだけは'+'か'-'と組み合わせたときのみ意味を持つ。これはコンパイ
ラバージョンのような一般的な情報を含む行か、無視するべきヘッダを読み込む。
%-G このメッセージを無視する
%+G 一般的なメッセージ
パターンマッチング
古いバージョンのVimとの下位互換性の為にscanf()と同じ"%*[]"という記法がサポート
されている。しかし、フォーマット文字列にVimがサポートするほぼ全ての正規表現を
用いる事も可能である。正規表現言語のメタ文字は普通の文字列やファイル検索の一部
と重なってしまうから(従って内部的にはエスケープされる必要がある)、メタシンボル
は'%'を付加して表記される必要がある:
%\ 単体の'\'という文字。これは":set errorformat="の定義の
中ではエスケープされて("%\\")書かれなければならない。
%. 単体の'.'という文字。
%# 単体の'*'(!)という文字。
%^ 単体の'^'という文字。注意: これなしでも行頭にはマッチ
するので、これは特に便利ではない。
%$ 単体の'$'という文字。注意: これなしでも行末にはマッチ
するので、これは特に便利ではない。
%[ 単体の'['という文字。文字の範囲[]のために使われる。
%~ 単体の'~'という文字。
表現の中でキャラクタクラスを使用する場合(概要は
|/\i|を参照)、数量子"\+"を含む
語はscanf()の中に"%*"という記法で書くことができる。例:"%\\d%\\+" ("\d\+",
"どんな数(字)でも")は"%*\\d"と等価である。重要:\(...\)のグループ表現は、内部
変換に使うため予約されているからフォーマット指定内では使用することができない。
'errorformat'内の複数の要素
*efm-entries*
複数のコンパイラからの出力を見つけることを可能にするために、カンマで区切って
複数のフォーマットパターンを
'errorformat'に設定することができるだろう(注:
カンマ直後の空白は無視される)。完全にマッチした最初のパターンが採択される。
マッチするものが無い場合、最後にマッチした部分が使われるが、ファイルネームは
除外されエラーメッセージは全体のメッセージとして設定される。複数のコンパイラ
からの出力メッセージにマッチしてしまうパターンがあった(しかし正確には
一致しない)時には、より制限されたもの(訳注:他のメッセージにマッチし難いもの)
の後に置く。パターンの先頭にカンマを含めるにはバックスラッシュ(コマンドset中
では2度タイプするべきだ)を添える。バックスラッシュを含めるためには2つ与える
(つまりコマンドsetの中では4つタイプする)。また、":set"コマンド内のスペースの前
にはバックスラッシュを置く必要がある。
有効なマッチ
*quickfix-valid*
もし
'errorformat'に完全には一致しない行が現れた場合、エラーメッセージ全体が
表示され、エントリーは無効とされコマンド":cn"や":cp"使用時にはスキップされる
(有効なエントリーが全く無い場合で無い限り)。エラーメッセージの全てはコマンド
":cl!"で表示する事ができる。
エラーフォーマットがファイル名を含んでいないとVimは正しいファイルへジャンプ
することができない。手動でやる必要がある。
例
Aztec compilerのファイルの書式は:
ファイル名>行:列:エラータイプ:識別番号:メッセージ
ファイル名 エラーが見つかったファイルの名前
行 エラーが見つかった行の通し番号
列 エラーが見つかった場所の列数(行先頭からの文字数)
タイプ エラーの種類、通常は一文字で'E'か'W'
識別番号 エラーの番号(マニュアルの検索用)
メッセージ エラーの説明
これは
'errorformat'をこのように設定すればマッチできる:
%f>%l:%c:%t:%n:%m
単行エラーを出力するCコンパイラのための幾つかの例:
%f:%l:\ %t%*[^0123456789]%n:\ %m Manx/Aztec C エラーメッセージ
(scanf()は[0-9]を理解しない)
%f\ %l\ %t%*[^0-9]%n:\ %m SAS C用
\"%f\"\\,%*[^0-9]%l:\ %m generic C compilers用
%f:%l:\ %m GCC用
%f:%l:\ %m,%Dgmake[%*\\d]:\ Entering\ directory\ `%f',
%Dgmake[%*\\d]:\ Leaving\ directory\ `%f'
GCC with gmake用(行を連結すること!)
%f(%l)\ :\ %*[^:]:\ %m old SCO C compiler (pre-OS5)
%f(%l)\ :\ %t%*[^0-9]%n:\ %m idem, エラーの種類と番号つき
%f:%l:\ %m,In\ file\ included\ from\ %f:%l:,\^I\^Ifrom\ %f:%l%m
いくつかの拡張つきGCC
複数行メッセージを扱うために拡張した例が次の所で与えられる。
|errorformat-Jikes|と
|errorformat-LaTeX|を参照。
:setコマンドで使うときにはスペースとダブルクォートの前にバックスラッシュが必要
なことに注意。コンマの前には2つのバックスラッシュを置く。1つは:setコマンド
のため、もう1つはコンマがエラーフォーマットの区切りと認識されるのを避けるため
である。
メッセージをフィルタリングする
もしコンパイラがフォーマットに合わないエラーメッセージを作成する場合、エラー
メッセージをこのフォーマットに変換するプログラムを書く方法もある。その時は
コマンド":make"によって起動されるプログラムオプション
'makeprg'を変更することで
指定できる。例:
> :set mp=make\ \\\|&\ error_filter
パイプ(|)の前のバックスラッシュはコマンドセパレータとして認識されないために
必要。コマンド"set"では空白の前にバックスラッシュが必要。
=============================================================================
8. ディレクトリスタック
*quickfix-directory-stack*
Quickfixはmakeの出力を解釈し、使われたディレクトリ全てをスタックで保持する。
GNU-Makeではディレクトリに入ったり出たりすると常に絶対パスで表示されるので、
これはむしろシンプルである。これはmakefile中のcdコマンドか、起動パラメータ
"-C dir"(makefileの読みこみ前にディレクトリを変更)なのかには因らない。GNU-Make
に強制的に処理の前後にワーキングディレクトリを表示されるためにスイッチ"-w"を
使用するのは便利かもしれない。
GNU-makeを使用しない場合、正しいディレクトリを管理する事はもっと複雑になる。
例えばAIX-makeはワーキングディレクトリに関してなんの情報も表示しない。
よってmakefileに細工が必要となる。LessTifのmakefileには"Making
{target} in
{dir}"と表示するコマンドがある。ここにはディレクトリを出る時の情報とその相対
パスが表示されないという重要な問題もある。
パスの関係とメッセージ"leave directory"が現れない問題のためにVimでは次の
アルゴリズムで対処している:
1) 与えられたディレクトリがカレントディレクトリの子か調べる。真ならばそれを
カレントディレクトリとする。
2) カレントディレクトリの子ディレクトリでなかった場合、上のディレクトリの子
ディレクトリか(つまり兄弟ディレクトリ)を調べる。
3) まだディレクトリが見つからない場合、これはVimのカレントディレクトリの子
ディレクトリだと仮定される。
付け加えて、全てのファイルについて認識されたディレクトリに実際に存在するのか調
べられる。もしもなければディレクトリスタックの中の全てのディレクトリ(サブディ
レクトリではない)について探す。これでも見つからなければVimのカレントディレクト
リにあるものと仮定される。
このアルゴリズムには制限がある。この例はmakeがディレクトリに入った時に
"Making all in dir"の形で情報を表示すると仮定している。
1) 次のようなディレクトリとファイルがあったとする
./dir1
./dir1/file1.c
./file1.c
カレントディレクトリの前にmakeが"./dir1"を処理し"./file1.c"にエラーがあると
Vimは"./dir1/file.c"をロードしてしまう。
これはメッセージ"leave directory"があれば解決する事ができる。
2) 次のようなディレクトリとファイルがあったとする
./dir1
./dir1/dir2
./dir2
次のようになる:
Makeの出力 Vimが解釈するディレクトリ
------------------------ ----------------------------
Making all in dir1 ./dir1
Making all in dir2 ./dir1/dir2
Making all in dir2 ./dir1/dir2
これはメッセージ"enter directory"に相対パスが記述されるか、メッセージ
"leave directory"が表示されれば解決される。
この問題を避けるため、ディレクトリの絶対パスとメッセージ"leave directory"
が表示されるようにすればよい。
Makefileの例:
Unix:
libs:
for dn in $(LIBDIRS); do \
(cd $$dn; echo "Entering dir '$$(pwd)'"; make); \
echo "Leaving dir"; \
done
上の出力を取り扱うために
%DEntering\ dir\ '%f',%XLeaving\ dir
を
'errorformat'につけ加える。
注意:Vimはメッセージ"leave directory"の中のディレクトリ名がカレント
ディレクトリかどうかはチェックしない。これが何故メッセージ"Leaveing dir"だけで
良いかの理由だ。
=============================================================================
9. 具体的なエラーファイルフォーマット
*errorformats*
*errorformat-Jikes*
IBM Researchによって公開されているJavaコンパイラーJikes(TM)はシンプルなマルチ
ラインエラーメッセージを出力する。
このメッセージにマッチする
'errorformat'の文字列を下に示す。これをユーザの
|vimrc|に書くことでVimがデフォルトで認識するフォーマットを上書きする事が
できる。またデフォルトに追加インストールする方法は
|:set+=|を参照。
:set efm=%A%f:%l:%c:%*\\d:%*\\d:,
\%C%*\\s%trror:%m,
\%+C%*[^:]%trror:%m,
\%C%*\\s%tarning:%m,
\%C%m
Jikes(TM)はオプション"+E"とともに起動されたときは1行エラーメッセージを出力す
る。これは次によってマッチできる。
:setl efm=%f:%l:%v:%*\\d:%*\\d:%*\\s%m
*errorformat-javac*
この
'errorformat'は、エラーの桁を示すのに"^"の行を出力するjavac用にうまく動作
すると報告されている:
または:
Michael F. Lambが考案した別の方法を以下に示す。これはUnix用で、最初にエラーを
フィルタリングする:
以下の行を"vim-javac-filter"というファイルに書いて、PATHの通ったディレクトリ(
例えば~/bin)に置き、実行可能にしておく必要がある:
訳注: BSD sed では動作しないようです。GNU sed では動作します。
このsedスクリプトを言葉で説明すると次のようになる:
- 1つのタブを1つのスペースに置換し、
- ファイル名・行番号・エラーメッセージを含む行をポインタ行("^"の行のこと)の直
後に移動する。これによって、エラーメッセージ行とポインタ行の間の使われないテ
キストが無視され、vimの「複数行メッセージ」の記法にマッチするようになり、ま
た、それを「複数行メッセージの継続」として含めなくてもよいようになる。
*errorformat-ant*
ant(
http://jakarta.apache.org/)用には、各javacの出力行の前につく[javac]を受け
取るために、上のエラーフォーマットを修正しなければならない:
:set efm=%A\ %#[javac]\ %f:%l:\ %m,%-Z\ %#[javac]\ %p^,%-C%.%#
javacやjikesとantをともに扱うためにこの
'errorformat'を調整することができる。jik
esを使っているなら、jikesの+Eコマンドラインスイッチを使うことをantに教えなけれ
ばならない(このスイッチはjikesに1行エラーメッセージを生成させる)。これがbuil
d.xmlファイルの2行目が行っていることである:
<property name = "build.compiler" value = "jikes"/>
<property name = "build.compiler.emacs" value = "true"/>
javac、jikesと組み合わせたantを扱う
'errorformat'はこうである:
:set efm=\ %#[javac]\ %#%f:%l:%c:%*\\d:%*\\d:\ %t%[%^:]%#:%m,
\%A\ %#[javac]\ %f:%l:\ %m,%-Z\ %#[javac]\ %p^,%-C%.%#
<
*errorformat-jade*
jade (
http://www.jclark.com/参照)のエラーを解釈するのは簡単である:
:set efm=jade:%f:%l:%c:%t:%m
*errorformat-LaTeX*
次のは複数行に渡ってエラーメッセージを表示する(La)TeXタイプセッティング
システム用の
'errorformat'文字列を指定する一つの例である。":clist"や":cc"
等々のコマンドは先行する空白を削除して複数行のものを一行にまとめて表示する。
以下のLaTeX用errorformatはマルチラインエラーを出力する他のコンパイラへ応用する
のは簡単だろう。
コマンドは
|vimrc|ファイルか別のVimスクリプトファイルに書ける。例えばLaTeXに
関連した内容を含むスクリプトをLaTeXソースの編集時にだけ読みこまれるようにする。
サンプルの全行をコピーしたことを確認する(順番もそのまま)。行の始まりに見ること
のできる'\'の表記は
|line-continuation|を参照。
まず
'makeprg'をLaTeXが最初のエラーで止まることなく複数のエラー
を返すように準備する。
:set makeprg=latex\ \\\\nonstopmode\ \\\\input\\{$*}
マルチラインエラーメッセージの始まり:
:set efm=%E!\ LaTeX\ %trror:\ %m,
\%E!\ %m,
マルチライン警告メッセージの始まり;最初の2つは行番号も含んで
いる。幾つかの正規表現の意味:
- "%.%#" (".*") 文字列(空文字列も含む)にマッチ
- "%*\\d" ("\d\+") matches a number
エラー/警告メッセージが続く可能性;最初の一つは行番号も含んで
いる:
次のパターンにマッチする行には重要な情報は含まれていない;
よってメッセージに含まないようにする。
通常、空白文字だけの行は表示しない:
LaTeXの出力ログには個々のライン毎にエラーのあったファイル名が
特定(記述)されているわけではない;ログのあらゆる所で与えられ、
括弧にくくられている。
続くパターンはそれらの名前を取り出し内部スタックに保存しようと
試みる。パターンは時として一つの行を複数回走査(一つ目を
見つけた後、同じ行に次のを発見しようと)するので、パターンの
末尾の"%r"が行の残りの部分が次の試行で解釈の対象になることと、
行の末尾に達するまでそれが繰り返されることを示す。
'('...')'でくくられたファイル名を読み飛ばす;明らかにエラーを
含まないファイルはスタックに積まない:
ファイル名をスタックに積む。名前は'('の後に与えられる。
')'が見つかったらファイル名をスタックから取り崩す。
幾つかのケースにおいてLaTeXの出力したログの中のファイル名を正確に取り出す事が
できないことに注意。括弧の対応が正しくつかない時パーサは混乱してしまう。上記の
サンプルはもっとも一般的なケースだけ検出できるようにしてある。目的に合わせて
このサンプルを変える事はできる。例えば全てのいまいましい"Overfull ..."という
警告メッセージがエラーとして認識されてしまう事を防ぐ事ができる。
付け加えてLaTeXコンパイラの出力をフィルタリングするには、[La]TeXコンパイラに
よって生成されるファイル*.logを直接読むことも可能である。これは起こる可能性の
あるエラーについてより便利な情報を沢山含んでいる。しかしそのように複雑な
ファイルを正確に解釈するには、外部フィルタを使うほうが良い。そのようなVimに
識別されるフィルタの作り方はずっと以前に述べたので参照。
*errorformat-Perl*
$VIMRUNTIME/tools にefm_perl.plスクリプトがある。これはPerlのエラーメッセー
ジをフィルタし、QuickFixモードが理解できるフォーマットに変換する。使い方は
ファイルの先頭を参照。(このスクリプトはもう非推奨で、今は
|compiler-perl| を参
照のこと)
vim:tw=78:ts=8:ft=help:norl: