quickfix.txt For Vim バージョン 8.2. Last change: 2021 Dec 03
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
10. Quickfix ウィンドウのカスタマイズ quickfix-window-function
コンパイル時に+quickfix機能が無効にされた場合は、quickfixコマンドは使えない。
=============================================================================
1. QuickFixコマンドの使い方 quickfix Quickfix E42
Vimには編集-コンパイル-編集のサイクルを加速するための特別なモードがある。これ
はAmigaのManx's Aztec C compilerのquickfixオプションにインスパイアされた。Cコ
ンパイラから出力されたエラーメッセージをファイルに保存し、Vimでそのエラーに
ジャンプするというアイデアである。エラーメッセージを全部覚えておかなくても、そ
れぞれの問題を検証し、修正することができる。
quickfixコマンドはより一般的に、ファイル中の位置のリストを作成し、ジャンプする
ために使うことができる。例えば、:vimgrepはパターンにマッチした位置をリストす
る。スクリプト中でgetqflist()を使ってこれらの位置を参照することができる。
そのため、編集・コンパイル・修正のサイクル以外にも多くの事に利用できる。
ファイルにエラーメッセージがあるなら "vim -q filename" で起動する:
Vim の中でコマンドを実行し結果を得る方法の一つに:makeコマンドがある (後述)。
各コンパイラからのエラーメッセージを解釈させるためには、オプション
'errorformat' をセットする (下のerrorformatを参照)。
quickfix-ID
各quickfixリストはquickfix IDと呼ばれる一意な識別子を持ち、この番号はVimセッ
ションの中で変わらない。getqflist() 関数はリストに割り当てられた識別子の取得
に使用できる。quickfixリスト番号もある。この番号は、10個以上のリストがquickfix
スタックに追加されるたびに変更される可能性がある。
location-list E776
locationリストはウィンドウローカルなquickfixリストである。:vimgrep, :grep,
:helpgrep, :make などのコマンドはquickfixリストを作成するが、それらに対応
する :lvimgrep, :lgrep, :lhelpgrep, :lmake などのコマンドを使うことで
locationリストを得ることができる。
location-list-file-window
locationリストはウィンドウに関連付けられていて、各ウィンドウが別々のlocationリ
ストを持つことができる。locationリストは1個のウィンドウにだけ関連付けることが
できる。locationリストはquickfixリストとは独立している。
locationリストを持つウィンドウが分割されると、新しいウィンドウはlocationリスト
のコピーを得る。locationリストへの参照が全てなくなると、そのlocationリストは破
棄される。
quickfix-changedtick
全てのquickfixリストとlocationリストはそのリストに行われた変更の総数を追跡する
読み込み専用のchangedtick変数を持つ。quickfixリストが変更されるたびに、この総
数はインクリメントされる。これは、リストが変更されたときだけアクションを実行す
ることに使用できる。getqflist() および getloclist() 関数は changedtickの現
在の値を問い合わせるのに使用できる。changedtick変数を変更することはできない。
以下のquickfixコマンドが利用できる。locationリストコマンドはquickfixコマンドに
似ていて、quickfixコマンドのプリフィックス 'c' が 'l' に置き換わっている。
E924
locationリストコマンドで処理されているにもかかわらず現在のウィンドウが
autocommand により閉じられる場合、それは中断される。
E925 E926
locationリストコマンドで処理されているにもかかわらず現在のquickfixまたは
locationリストが autocommand に変更される場合、それは中断される。
:cc
:cc[!] [nr] エラー [nr]を表示する。[nr]が省略されると同じエラーが
:[nr]cc[!] 再度表示される。[!]が無く、現在のバッファに変更が有り
ウィンドウが1つしか無く、'hidden' も 'autowrite' もoff
である場合には、他のバッファへジャンプする事は無い。
[!]を使用して他のバッファに移る時、現在のバッファへの
変更点は、'hidden' がセットされているか別のウィンドウ
が開いているかしない場合、破棄されてしまう。
バッファ移動の際は設定 'switchbuf' が関係してくる。
quickfixウィンドウで使用するときは、現在行の "." や 最
終行の "$" を含む行番号を使用できる。
:ll
:ll[!] [nr] ":cc" と同様だが、quickfixリストでなくカレントウィンド
:[nr]ll[!] ウのlocationリストが使われる。
:cn :cne :cnext E553
:[count]cn[ext][!] ファイル名を含むエラーリストで[count]個後のエラーを表
示する。ファイル名が無かった場合[count]個後のエラーに
移動する。[!]と 'switchbuf' については:ccを参照。
:lne :lnext
:[count]lne[xt][!] ":cnext" と同様だが、quickfixリストでなくカレントウィ
ンドウのlocationリストが使われる。
:[count]cN[ext][!] :cp :cprevious :cprev :cN :cNext
:[count]cp[revious][!] ファイル名を含むエラーリストで[count]個前のエラーを表
示する。ファイル名が無かった場合[count]個前のエラーに
移動する。[!]と 'switchbuf' については:ccを参照。
:[count]lN[ext][!] :lp :lprevious :lprev :lN :lNext
:[count]lp[revious][!] ":cNext" と ":cprevious" と同様だが、quickfixリストで
なく、カレントウィンドウのlocationリストが使われる。
:cabo :cabove
:[count]cabo[ve] カレントバッファの現在行の [count] 上のエラーに移動す
る。[count] を省略すると、1が使用される。エラーがない
場合は、エラーメッセージが表示される。quickfixリストの
エントリは、バッファ番号と行番号でソートされていると仮
定する。同じ行に複数のエラーがある場合は、最初のエント
リだけが使用される。[count] が現在の行より上のエントリ
の数を超えると、ファイル内の最初のエラーが選択される。
:lab :labove
:[count]lab[ove] quickfixリストの代わりにカレントウィンドウのlocationリ
ストが使用されることを除けば、":cabove" と同じ。
:cbel :cbelow
:[count]cbel[ow] カレントバッファの現在行の [count] 下にあるエラーに移
動する。[count] を省略すると、1が使用される。エラーが
ない場合は、エラーメッセージが表示される。quickfixリス
トのエントリは、バッファ番号と行番号でソートされている
と仮定する。同じ行に複数のエラーがある場合は、最初のエ
ントリだけが使用される。[count] が現在の行より下のエン
トリの数を超えると、ファイル内の最後のエラーが選択され
る。
:lbel :lbelow
:[count]lbel[ow] quickfixリストの代わりにカレントウィンドウのlocationリ
ストが使用されることを除けば、":cbelow" と同じ。
:cbe :cbefore
:[count]cbe[fore] カレントバッファ内の現在のカーソル位置の [count] 前の
エラーに移動する。[count] を省略すると、1が使用される。
エラーがない場合は、エラーメッセージが表示される。
quickfixリストのエントリは、バッファ、行番号および桁番
号でソートされていると仮定する。[count] が現在位置より
前のエントリ数を超えると、ファイル内の最初のエラーが選
択される。
:lbe :lbefore
:[count]lbe[fore] quickfixリストの代わりにカレントウィンドウのlocationリ
ストが使用されることを除けば、":cbefore" と同じ。
:caf :cafter
:[count]caf[ter] カレントバッファ内の現在のカーソル位置の [count] 後の
エラーに移動する。[count] を省略すると、1が使用される。
エラーがない場合は、エラーメッセージが表示される。
quickfixリストのエントリは、バッファ、行番号および桁番
号でソートされていると仮定する。[count] が現在位置以降
のエントリ数を超えると、ファイル内の最後のエラーが選択
される。
:laf :lafter
:[count]laf[ter] quickfixリストの代わりにカレントウィンドウのlocationリ
ストが使用されることを除けば、":cafter" と同じ。
:cnf :cnfile
:[count]cnf[ile][!] ファイル名を含むエラーリストで[count]個後のファイルの
最初のエラーを表示する。ファイル名が無いか後のファイル
が無い場合には、[count]後のエラーに移動する。[!]と
'switchbuf' については:ccを参照。
:lnf :lnfile
:[count]lnf[ile][!] ":cnfile" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:[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リストでな
く、カレントウィンドウのlocationリストが使われる。
:crewind :cr
:cr[ewind][!] [nr] [nr]のエラーを表示する。[nr]が省略されると一番最初のエ
ラーが表示される。:ccを参照。
:lrewind :lr
:lr[ewind][!] [nr] ":crewind" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
: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リストでなく、カレント
ウィンドウのlocationリストが使われる。
:cq :cquit
:cq[uit][!]
:{N}cq[uit][!]
:cq[uit][!] {N} Vim をエラーコード {N} で終了する。{N} の既定は 1。
Vim がほかのプログラムから呼ばれたときに有用である:
例、コンパイラが同じファイルを再度コンパイルする事が無
くなる、git commit がコミット処理を中断する、fc
(bash や zsh のようなシェルの組み込みコマンド) がコマ
ンドを起動しない、など。
{N} を 0 にすることもできる。その場合はVimは通常終了す
る。
警告: ファイルに対する変更はすべて失われる ([!] を指定
しなくても)! このコマンドは、システムへの戻り値が非零
であるということ以外 ":qall!" :qall と同じである。
:cf :cfile
:cf[ile][!] [errorfile] エラーファイルを読みこみ最初のエラーへ移動する。Vimが
オプション -q で起動された時には自動的に行われる。コン
パイルの間Vimを実行したままにしたい時に使うことができ
る。エラーファイルの名前を与えればオプション
'errorfile' に [errorfile]が設定される。[!]について
は :cc を参照。
エラーファイルのエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lf :lfi :lfile
:lf[ile][!] [errorfile] ":cfile" と同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。コマンドラインオプ
ション -q を使ってlocationリストを設定することはできな
い。
:cg[etfile] [errorfile] :cg :cgetfile
エラーファイルを読み込む。":cfile" に似ているが、最初
のエラーに移動しない。
エラーファイルのエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lg[etfile] [errorfile] :lg :lge :lgetfile
":cgetfile" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:caddf :caddfile
:caddf[ile] [errorfile] エラーファイルを読み込み、現在のquickfixリストにエラー
を追加する。quickfixリストがまだない場合は、新しいリス
トが作成される。
エラーファイルのエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:laddf :laddfile
:laddf[ile] [errorfile] ":caddfile" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cb :cbuffer E681
:cb[uffer][!] [bufnr] カレントバッファからエラーリストを読み込む。[bufnr] を
指定すると、カレントバッファの代わりにそのバッファが使
われる。bufnrには読み込まれているバッファ番号を指定し
なければならない。範囲を指定すると、読み込む行を指定す
ることができる。範囲指定がないとバッファ全体が使われ
る。
[!]については:ccを参照。
:lb :lbuffer
:lb[uffer][!] [bufnr] ":cbuffer" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cgetb :cgetbuffer
:cgetb[uffer] [bufnr] カレントバッファからエラーリストを読み込む。":cbuffer"
と同じだが、最初のエラーにジャンプしない点が異なる。
:lgetb :lgetbuffer
:lgetb[uffer] [bufnr] ":cgetbuffer" と同様だが、quickfixリストでなく、カレン
トウィンドウのlocationリストが使われる。
:cad :cadd :caddbuffer
:cad[dbuffer] [bufnr] カレントバッファからエラーリストを読み込み、現在の
quickfixリストにエラーを追加する。quickfixリストがまだ
存在しない場合は、新しいリストが作成される。それ以外は
":cbuffer" と同じ。
:laddb :laddbuffer
:laddb[uffer] [bufnr] ":caddbuffer" と同様だが、quickfixリストでなく、カレン
トウィンドウのlocationリストが使われる。
:cex :cexpr E777
:cex[pr][!] {expr} {expr} の結果を使って quickfix リストを作成し、最初の
エラーにジャンプする。
{expr} が文字列のときは、その文字列を改行コードで区切
り、各行を 'errorformat' のグローバル値に従って解釈
し、結果を quickfix リストに追加する。
{expr} がリストのときはリストの各文字列要素を解釈し、
quickfix リストに追加する。リスト中の文字列でない要素
は無視される。
[!]については:ccを参照。
例:
:lex :lexpr
:lex[pr][!] {expr} :cexprと同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。
:cgete :cgetexpr
:cgete[xpr] {expr} {expr}の結果を使ってquickfixリストを作成する。:cexpr
と同様だが、最初のエラーにジャンプしない点が異なる。
:lgete :lgetexpr
:lgete[xpr] {expr} :cgetexprと同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cadde :caddexpr
:cadde[xpr] {expr} {expr}を評価し、結果の行を現在のquickfixリストに追加す
る。quickfixリストがまだ無い場合は、新しいリストが作成
される。現在のカーソル位置は変わらない。より詳しくは
:cexprを参照。
例:
:lad :addd :laddexpr
:lad[dexpr] {expr} ":caddexpr" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cl :clist
:cl[ist] [from] [, [to]]
有効なエラーを全て列挙するquickfix-valid。[from] 及
び/もしくは [to] で行数を指定された場合、その範囲のエ
ラーが表示される。負であった場合最後のエラーから数え
る。-1が最後のエラーとなる。設定 'switchbuf' がバッファ
の移動に関係する。
:filter コマンドは、指定されたパターンに一致する
quickfixのエントリだけを表示するために使用できる。パ
ターンは、エントリのファイル名、モジュール名、パターン
およびテキストと照合される。
:cl[ist]! [from] [, [to]]
全てのエラーを表示する。
:lli :llist
:lli[st] [from] [, [to]]
":clist" と同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。
:lli[st]! [from] [, [to]]
カレントウィンドウのlocationリストの中身を全部表示す
る。
正しいエラーの位置は隠されたマークによって示されているので、例え行を挿入したり
削除したとしても問題はない (Manx's Z editorではそうではない)。時々マークが幾つ
かの理由で消されてしまう事があり、メッセージ "line changed" がその警告となる。
一度Vimを終了し再起動した場合マークは失われ正しいエラー位置は把握できない。
quickfixコマンド (':make', ':grep' など) を実行する前後に2つの自動コマンドが利
用できる。詳しくは QuickFixCmdPre と QuickFixCmdPost を参照。
QuickFixCmdPost-example
'encoding' とロケールが異なる場合、コンパイラのエラーメッセージと Vim 内部のエ
ンコーディングが異なる場合がある。次のようにすれば、このメッセージを変換できる:
quickfix-title
すべてのquickfixリストとlocationリストはタイトルを持つ。デフォルトではタイトル
はそのリストを作成したコマンドに設定される。getqflist() と getloclist() 関
数はそれぞれquickfixリストとlocationリストのタイトルを取得するために使われる。
setqflist() と setloclist() 関数はそれぞれquickfixリストとlocationリストの
タイトルを変更するために使われる。例:
quickfix-index
いずれかのquickfixコマンド(例えば :cc, :cnext, :cprev 等)を使用して
quickfix/locationリストエントリに移動すると、そのエントリが現在選択されている
エントリになる。quickfix/locationリストで現在選択されているエントリのインデッ
クスは、getqflist()/getloclist()関数を使って取得できる。例:
新しいquickfixリストの場合、最初のエントリが選択され、インデックスは1になる。
すべてのquickfix/locationリスト内のすべてのエントリは、setqflist()関数を使用し
て現在選択されているエントリとして設定できる。例:
quickfix-size
quickfixリストとlocationリストの中の項目の数をそれぞれ getqflist() と
getloclist() 関数を使用して取得できる。例:
quickfix-context
任意のVimの型はquickfixリストまたはlocationリストとのコンテキストとして関連付
けることができる。setqflist() と setloclist() 関数はコンテキストをquickfix
とlocationリストにそれぞれ関連付けることに使用できる。getqflist() と
getloclist() 関数はそれぞれquickfixとlocationリストのコンテキストの取得に使
用できる。これは複数のquickfix/locationリストを取り扱うVimプラグインにとって便
利である。
例:
quickfix-parse
getqflist() 関数を使用してquickfixリストを作成または変更せずに、'errorformat'
を使用して行のリストをパースできる。例:
書を返す。以下は 'errorformat' オプションを変更せずにカスタム 'errorformat' を
使って行をパースする方法を示している。
quickfixリストやlocationリスト中のバッファに対してコマンドを実行:
:cdo
:cdo[!] {cmd} quickfix リスト中の有効な各項目に対して {cmd} を実行す
る。以下の操作と同様に動作する:
えられない場合、このコマンドは失敗する。
次のエントリへの移動が失敗すると、実行は停止する。
最後のバッファ (またはエラーが起こったバッファ) がカレ
ントウィンドウになる。
{cmd} の中では '|' で複数のコマンドを連結できる。
quickfixリスト中の有効な項目のみが使われる。
「範囲」を指定して項目を選択することができる。例:
Note: このコマンドを実行している間、Syntax 自動コマン
ドイベントが 'eventignore' に追加され、無効化される。
これは各バッファの編集を大幅にスピードアップさせる。
:bufdo、:tabdo、:argdo、:windo、:ldo、
:cfdo、:lfdo も参照。
:cfdo
:cfdo[!] {cmd} quickfixリスト中の各ファイルに対して {cmd} を実行する。
以下の操作と同様に動作する:
:ldo
:ld[o][!] {cmd} カレントウィンドウのlocationリスト中の有効な各項目に対
して {cmd} を実行する。
以下の操作と同様に動作する:
それ以外は :cdo の場合と同様である。
:lfdo
:lfdo[!] {cmd} カレントウィンドウのlocationリスト中の各ファイルに対し
て {cmd} を実行する
以下の操作と同様に動作する:
QUICKFIX または LOCATIONリストのフィルタリング:
cfilter-plugin :Cfilter :Lfilter
quickfixリストのエントリ数が多すぎる場合は、cfilterプラグインを使用してエント
リ数を減らすことができる。プラグインをロードする:
その後で、以下のコマンドを使って、quickfix/locationリストをフィルタすることが
できる:
:Cfilter コマンドは、現在のquickfixリストの {pat} に一致するエントリから新し
いquickfixリストを作成する。{pat} はVimの正規表現 regular-expression パター
ンである。ファイル名とエントリのテキストの両方が {pat}と照合される。オプション
の ! が指定された場合、{pat} と一致しないエントリが使用される。パターンは、次
のいずれかの文字を使用して任意に囲むことができる: ', ", /。パターンが空の場合
は、最後に使用された検索パターンが使用される。
:Lfilter コマンドは :Cfilter と同じ動作をするが、カレントlocationリストを
操作する。
=============================================================================
2. エラーウィンドウ quickfix-window
:cope :copen w:quickfix_title
:cope[n] [height] 現在のエラーリストを表示するウィンドウを開く。
[height]が与えられたとき、(余地があれば) ウィンドウの
高さがその値になる。[height] を省略したときはウィンド
ウの高さは 10 行になる。
すでにquickfixウィンドウがある場合はそれがカレントウィ
ンドウになる。2 個目のquickfixウィンドウを開くことはで
きない。[height] が指定されたとき、既存のウィンドウは
その高さにリサイズされる。
quickfix-buffer
ウィンドウは 'buftype' の値が "quickfix" である特別な
バッファを含んでいる。これを変更してはならない。
ウィンドウは w:quickfix_title 変数を持っている。この変
数はquickfixリストを生成したコマンドを示している。変数
の値は 'statusline' が適切に調整されていればステータス
ラインに表示される。このバッファがquickfixコマンドまた
は関数により変更されるたびに、b:changedtick 変数はイ
ンクリメントされる。このバッファにおける変数の値は
getqflist() や getloclist() 関数を用い 'qfbufnr'
アイテムを通して取得できる。locationリストの場合は、
locationリストが削除されるときに、このバッファも削除さ
れる。
:lop :lopen
:lop[en] [height] カレントウィンドウのlocationリストを表示するウィンドウ
を開く。カレントウィンドウにlocationリストが存在すると
きだけ動作する。一度に2個以上のlocationリストを開くこ
とができる。それ以外は ":copen" と同様。
:ccl :cclose
:ccl[ose] quickfixウィンドウを閉じる。
:lcl :lclose
:lcl[ose] カレントウィンドウのlocationリストを表示しているウィン
ドウを閉じる。
:cw :cwindow
:cw[indow] [height] 認識されたエラーがあるときquickfixウィンドウを開く。
ウィンドウがすでに開いていて認識されたエラーがない場合
はウィンドウを閉じる。
:lw :lwindow
:lw[indow] [height] ":cwindow" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cbo :cbottom
:cbo[ttom] quickfix ウィンドウの最後の行にカーソルを移動し、見え
る様にスクロールする。これは非同期コールバックでエラー
を追加するのに便利である。
大量の更新に伴う多くの再描画を避けるには一度限り呼び出
すこと。
:lbo :lbottom
:lbo[ttom] 現在のウィンドウに関するlocationリストが表示されている
ウィンドウである事を除いて ":cbottom" と同じ。
通常、quickfixウィンドウはスクリーンの一番下に現れる。垂直分割したウィンドウが
ある場合は、一番右下に現れる。常に最大幅を占めるようにさせたい場合は
例えば、一番上に移動させたければCTRL-W Kとする。
'winfixheight' オプションが設定されれば、'winheight' と 'equalalways' を無視
し、たいていその高さを維持する。高さを手動で変更することもできる (例えばステー
タスラインをマウスで上へドラッグするなど)。
quickfixウィンドウには各行に1個ずつエラーが表示される。その行数はエラー番号に
等しい。現在の項目はQuickFixLineハイライティングでハイライトされる。あなたはそ
れをあなたの好みに変更することができる。例:
":.cc" でカーソル下のエラーに移動できる。
<Enter>キーを押すのと行をダブルクリックするのは同じ効果がある。そのエラーを含
むファイルがquickfixウィンドウの上に開かれる。そのファイルがすでにウィンドウに
開かれていたらそのウィンドウがアクティブになる。そのウィンドウにあるバッファが
変更されていて、そのエラーが別のファイルにある場合はエラーへの移動は失敗する。
まず、そのウィンドウが破棄してもよいバッファを含んでいることを確かめなければな
らない。
CTRL-W_<Enter> CTRL-W_<CR>
CTRL-W <Enter>を使うと、新しいウィンドウを開いてそこでエラーにジャンプできる。
quickfixウィンドウが一杯になったとき、2つの自動コマンドイベントが発生する。第
一は 'filetype' オプションが "qf" にセットされ、FileTypeイベントが発生する
(qf.vim も参照)。それからBufReadPostイベントが発生する。そのときのバッファ名
は "quickfix" となる。これを使ってエラーリストに対して操作を行うことができる。
例:
に注目。これは式を評価するのに使われる。
BufWinEnterイベントも発生する。ここでもバッファ名は "quickfix" になる。
Note: 存在する quickfix リストに追加される場合、autocommand イベントは発生しま
せん。
Note: quickfixウィンドウ内で変更を加えてもエラーのリストには何の影響もない。変
更を防ぐために 'modifiable' がオフになっている。それでも行を削除や挿入した場合
は、テキストとエラー番号の関係がめちゃくちゃになる。本当にエラーリストを変更し
たいのなら、quickfixウィンドウの内容をファイルに保存し、":cfile" を実行、ファ
イルをパースさせ、新しいエラーリストとして使うこと。
location-list-window
locationリストウィンドウはlocationリストの中身を表示する。locationリストウィン
ドウを開くと、カレントウィンドウの下に開かれ、カレントウィンドウのlocationリス
トが表示される。locationリストはquickfixウィンドウに似ているが、一度に2個以上
のlocationリストウィンドウを開ける点が異なる。このウィンドウ内でlocationリスト
コマンドを使うと、表示されているlocationリストが使われる。
locationリストウィンドウからファイルを選択すると、以下のステップによって、その
ファイルを編集するウィンドウが探される。
1. locationリストウィンドウに表示されているlocationリストに関連付けられている
ウィンドウがあるなら、そのウィンドウが使われる。
2. 上のステップが失敗した場合、そのファイルが既に他のウィンドウで開かれている
なら、そのウィンドウが使われる。
3. 上のステップが失敗した場合、'buftype' がセットされていないバッファを表示し
ているウィンドウが存在するなら、そのウィンドウが使われる。
4. 上のステップが失敗した場合、新しいウィンドウでファイルが開かれる。
上の全ての場合において、選択されたウィンドウに対してまだlocationリストが関連付
けられていなかった場合、locationリストウィンドウに表示されているlocationリスト
が関連づけられる。
quickfix-window-ID
getqflist() と getloclist() 関数を使用して、quickfixウィンドウとlocationリ
ストウィンドウのウィンドウIDをそれぞれ取得できる(もしあれば)。例:
getqflist-examples
getqflist() 関数と getloclist() 関数は、それぞれquickfixとlocationリストの
さまざまな属性を取得するのに使用できる。これらの関数の使用例を以下に示す:
setqflist-examples
setqflist() 関数と setloclist() 関数は、それぞれquickfixとlocationリストの
さまざまな属性を設定するのに使用できる。これらの関数の使用例を以下に示す:
=============================================================================
3. 複数のエラーリストを使う quickfix-error-lists
これまでは一つだけのエラーリストがあると仮定してきた。実際は最後に使った10個
迄のエラーリストが記憶される。新しいリストではじめた時には、以前のリストは自動
的に保存される。古いエラーリストにアクセスするために、2つのコマンドが用意され
ている。これらは存在するエラーリストの内1つを現在のエラーリストに設定する。
:colder :col E380
:col[der] [count] 古いエラーリストへ移動する。[count]が与えられると、そ
の回数繰り返し移動する。既に一番古いエラーリストにいる
場合、エラーメッセージが表示される。
:lolder :lol
:lol[der] [count] :colder と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cnewer :cnew E381
:cnew[er] [count] 新しいエラーリストへ移動する。[count]が与えられると、
その回数繰り返し移動する。既に一番新しいエラーリストに
いる場合、エラーメッセージが表示される。
:lnewer :lnew
:lnew[er] [count] :cnewer と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:chistory :chi
:[count]chi[story] エラーリストの一覧を表示する。現在のリストは ">" でマー
クされる。出力は以下の様になる:
error list 1 of 3; 43 errors :make
> error list 2 of 3; 0 errors :helpgrep tag
error list 3 of 3; 15 errors :grep ex_help *.c
[count] が与えられると、count番目のquickfixリストがカ
レントリストになる。例:
:lhistory :lhi
:[count]lhi[story] locationリストの一覧を表示する。:chistory の様に。
新しいエラーリストが追加された時には、それがカレントリストとなる。
":colder" が実行された後で ":make" や ":grep" が実行され新しいエラーリストが追
加されたときは1個新しいリストが上書きされる。これは ":grep" grep でブラウジ
ングしているときに特に便利である。もっと最近のエラーリストを残しておきたい場合
は初めに ":cnewer 99" を行うこと。
quickfixやlocationリストのスタック数を取得するには、特別な値 '$' に設定された
リスト番号でそれぞれ、getqflist() 関数と getloclist() 関数を使用できる。例:
=============================================================================
4. :makeの使い方 :make_makeprg
:mak :make
:mak[e][!] [arguments] 1. QuickFixCmdPre に関連付けられた自動コマンドが全て
実行される。
2. オプション 'autowrite' がonならば変更のあるバッファ
は保存される。
3. 'makeef' からエラーファイルの名前が生成される。
'makeef' が "##" を含まずかつ既に名前が存在する場合
それは削除される。
4. オプション 'makeprg' で与えられたプログラム (省略時
"make") が [argument]をオプションにして実行され、出
力がerrorfileに保存される (Unixではそれも画面にecho
される)。
5. 'errorformat' を使ってerrorfileが読みこまれる。
6. QuickFixCmdPost に関連付けられた自動コマンドが全
て実行される。後述のサンプルを参照。
7. [!]が与えられていないときは最初のエラーに移動する。
8. エラーファイルが削除される。
9. :cnextや:cprevious などのコマンドでエラー間を移
動できる。上を参照。
このコマンドは如何なるコメントも受けつけず、どんな "
という文字もargumentの一部とみなされる。
プログラム出力のエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lmak :lmake
:lmak[e][!] [arguments]
":make" と同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。
コマンド ":make" はオプション 'makeprg' で与えられるコマンドを実行する。これは
オプション 'shell' で与えられたシェルにコマンドを渡す事で実行されている。以下
をタイピングするのとほぼ同じである。
":!{makeprg} [arguments] {shellpipe} {errorfile}".
{makeprg}は 'makeprg' オプションで指定された文字列である。"make" に限らず、ど
んなコマンドでも使用できる。'%' と '#' の文字は通常通りコマンドライン中で展開
される。拡張子無しの現在ファイル名を表すのに "%<"、拡張子無しの代替ファイル名
を表すのに "#<" が使える。例えば:
[arguments] ":make" より後に入力した全て。
{shellpipe} オプション 'shellpipe'
{errorfile} オプション 'makeef'。"##" は一意な名前にする
コマンドがargumentsの後にオプションを必要とするならば、{makeprg}の中で引数リス
トに展開される置換子 "$*" が使用できる。$*は引数全てに置換えられる。例:
オプション 'shellpipe' の省略値はAmigaでは ">" で、Win32では ">%s 2>&1" であ
る。これはコンパイラの出力が直接ファイルに出力されスクリーンには出力されないこ
とを意味する。Unixでは "| tee" が使用される。コンパイラがファイルに出力すると
同時にスクリーンにも表示される。使っているシェルに応じて標準エラーへの出力も含
めるために "|& tee" や "2>&1| tee" が省略値となる。
'shellpipe' が空の場合、{errorfile}が省略される。これはコンパイラ自身がエラー
ファイルを作成する場合 (Manx's Amiga C) に便利である。
QuickFixCmdPost を使ってエンコーディングを修正する
ビルドプログラムが出力するメッセージと 'encoding' の値が異なる場合がある。この
例は、Vim がそのエラーメッセージを読み込んだ後でエンコーディングを変換する方法
を示している:
(Faque Cheng による例)
代わりに 'makeencoding' オプションを使うこともできる。
==============================================================================
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][f] {file} ...
ファイル{file}から{pattern}を検索し、マッチ位置をエラー
リストに追加する。'wildignore' にマッチしたファイルは
無視される。'suffixes' にマッチしたファイルは最後に検
索される。
{pattern}はVimの検索パターンである。/ で囲まない場合、
それが{pattern}中に現れない限り、どんな非ID文字
('isident' を参照) でも使える。
'ignorecase' が適用される。パターン中に/\cを含めると
大文字小文字を区別しなくなり、/\Cを含めると区別する
ようになる。これは 'ignorecase' より優先される。
'smartcase' は適用されない。
{pattern} が空のときは(つまり // が指定されたときは)、
最後に使われた検索パターンが使用される。last-pattern
フラグ:
'g' フラグ 'g' がない場合、各行は一度だけ追加され
る。'g' がある場合は全てのマッチが追加される。
'j' フラグ 'j' がない場合、Vim は最初のマッチへジャン
プする。'j' がある場合は quickfix リストが更新さ
れるだけである。[!] を付けるとカレントバッファに
対する変更は全て失われる。
'f' フラグ 'f' を指定するとファジー文字列マッチで一致
する行が検索される。この場合 {pattern} は正規表現
ではなくリテラル文字列として扱われる。文字列への
ファジーマッチについての詳細は fuzzy-match を参
照。
QuickFixCmdPre と QuickFixCmdPost がトリガーされ
る。
マッチのために開かれたファイルはバッファ番号を使用する
が、バッファ番号の消費を避けるために、可能であれば再利
用される。
:{count}vim[grep] ...
このコマンドの前に数字が置かれると、その数が検索する
マッチの最大数となる。":1vimgrep pattern file" とする
と最初のマッチだけを検索する。マッチが存在するかどうか
だけをチェックしたく、それが見つかったらすぐに終了して
ほしい場合に便利である。
進行状況を示すため、1秒程度ごとに検索されたファイル名
が表示される。
例:
:vim[grep][!] {pattern} {file} ...
上と同様だが、パターンを非ID文字で囲むのでなく、空白で
パターンを区切る。パターンはID文字で始まらねばならな
い。
例:
:lv :lvimgrep
:lv[imgrep][!] /{pattern}/[g][j][f] {file} ...
:lv[imgrep][!] {pattern} {file} ...
":vimgrep" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:vimgrepa :vimgrepadd
:vimgrepa[dd][!] /{pattern}/[g][j][f] {file} ...
:vimgrepa[dd][!] {pattern} {file} ...
":vimgrep" と同様だが、新しくエラーリストを作る代わり
に、現在のリストに追加する。
:lvimgrepa :lvimgrepadd
:lvimgrepa[dd][!] /{pattern}/[g][j][f] {file} ...
:lvimgrepa[dd][!] {pattern} {file} ...
":vimgrepadd" と同様だが、quickfixリストでなく、カレン
トウィンドウのlocationリストが使われる。
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と
同様に機能する。その場合、パターンが区切り文字で囲まれ
ていなければならないことに注意。
プログラム出力のエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lgr :lgrep
:lgr[ep][!] [arguments] ":grep" と同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。
:grepa :grepadd
:grepa[dd][!] [arguments]
":grep" と似ているが、新しいエラーリストを作らず、解釈
されたエラーが現在のリストに追加される。
例:
目のコマンドはバッファリスト内の各バッファに対し
"grepadd" を実行する。最初のエラーへジャンプするのを避
けるために ! を使っていることに注意。:bufdo でジャン
プすることはできない。
引数リスト内のファイルに対して実行し、マッチがないファ
イルでのエラーを回避する例:
プログラム出力のエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lgrepa :lgrepadd
:lgrepa[dd][!] [arguments]
":grepadd" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
5.3 grepをセットアップする
標準的な "grep" プログラムがインストールされていれば :grep コマンドはデフォル
トのままで動くだろう。使い方は標準的なコマンドにとてもよく似ている:
これは拡張子.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と共に使うにはこのようにする:
そして
これで期待通りの動作をする。
(最初にmkidをするのを忘れていなければ)
5.5 :vimgrepや:grepを使ってソースコードをわたり歩く
Vimが保存するエラーリストのスタックを使うことによって、ファイルをわたり歩き、
関数とその関数が呼んでいる関数を探すことができる。例えば、read_file()関数に引
数を加えたいとする。次のようにコマンドを打てばよい:
":cn" でマッチのリストを巡り、引数を加えることができる。またあるとき上位の関数
msg()から新しい引数を得て、それを変更しなければならないとする。ならばこうする
とよい:
msg()関数を変更しているときに、上位から引数を得なければならない関数をもう1個見
つけたとする。ならばその関数を見つけるのにまた ":vimgrep" を使えばよい。1つの
関数が終わったら、
とすれば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.foo" では "foo" を使い続ける。
{+eval機能なしでコンパイルされた場合には使用
できない}
"compiler" ディレクトリ内にあるVimプラグインによって、選択されたコンパイラを使
うためのオプションが設定される。:compiler はローカルオプションを設定し、
:compiler! はグローバルオプションを設定する。
current_compiler
Vimの古いバージョンをサポートするために、それらのプラグインは常に
"b:current_compiler" でなく "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を次のコマンドで設定する:
カーソルを最初のエラーの上に置いた状態で起動する。エラーメッセージは最後の行
に表示される。上で述べたコマンドを使って他のエラーへ移動することができる。エ
ラーを修正し、ファイルを保存できる。
- 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\ %:S " 1つのテストケースを走らせる
となる。
次も参照。
http://vim.sourceforge.net/tip_view.php?tip_id=280.
TEX COMPILER compiler-tex
ディストリビューションに含まれているTeX用のコンパイラスクリプト
($VIMRUNTIME/compiler/tex.vim) は、可能ならmakeコマンドを使う。コンパイラがカ
レントディレクトリに "Makefile" または "makefile" というファイルを見つけたら、
*TeXファイルをmakeを使って処理しようとし、そのmakefile通りの動作をする。この場
合コンパイラは 'errorformat' を*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された
chapter2.texを編集中に
処理するファイルの名前を引数に指定しなければならないことに注意 (\inputか
\includeされたファイルを編集中に正しいファイルを処理するため; %を引数なしに置
換するポータブルな方法もよい)。これはソースではなく、ターゲットを指定するとい
うmakeの意味論ではないが、拡張子 ".tex" を除いたファイル名を指定してもよい。そ
の場合、「filename.dviまたはfilename.pdfまたは filename.[コンパイラに応じた何
らかの結果の拡張子] をメイクしろ」ということを意味する。
Note: tex コマンドライン文法はMikTex (Srinath Avadhanulaによって提案された) と
teTeX (Artem Chuprinaによってチェックされた) の両方で使えるように設定されてい
る。errorformat-LaTeXからの提案は他のシェルやOSで動かせるようにするには複雑
すぎるし、他のTeXオプションを使うことも許さない。もしあなたのTeXが
"-interaction=nonstopmode" をサポートしていなければ、コマンドラインから
\nonstopmodeを表現する他の方法とともにその旨を報告してください。
=============================================================================
7. エラーフォーマット error-file-format
errorformat E372 E373 E374
E375 E376 E377 E378
'errorformat' オプションは認識されるエラーフォーマットのリストを指定する。その
中からエラーメッセージにマッチした最初のフォーマットが使われる。複数のフォーマッ
トを指定して、数種類のメッセージに対応したり、複数のコンパイラに対応したりする
ことができる。efm-entriesを参照。
'errorformat' の各要素は、scanfに似たフォーマットを記述する文字列である。はじ
めに、scanfがどのように働くか知る必要がある。Cコンパイラのドキュメントを読むこ
と。以下はVimが理解する%の項目である。他は無効になる。
'errorformat' 中の特別な文字はコンマとバックスラッシュである。それがどう扱われ
るかはefm-entriesを参照。"%%" はリテラル "%" にマッチする。よってこれはバッ
クスラッシュでエスケープしない。
:makeと :grep の出力のすべての NUL 文字は SOH (0x01) に置換されるので注
意。
Note: デフォルトでは大文字と小文字の違いは無視される。もし大文字・小文字の区別
をしたいなら "\C" をパターンに付け加える/\C。
Vimは任意の長さの行を読み取るが、最初の4095バイトのみが使用され、残りは無視さ
れる。要素の長さは1023バイトまでである。
基本要素
%f ファイル名 (文字列を検索)
%o モジュール名 (文字列を検索)
%l 行番号 (数字を検索)
%c 桁番号 (エラーの桁を表す数字。バイトインデックス。
<Tab>1個は1桁と数える)
%v 画面上の桁番号 (エラーの画面上の桁を表す番号 (<Tab>1個
はスクリーン上8桁と数える))
%t エラーの種類 (1文字を検索):
e - エラーメッセージ
w - 警告メッセージ
i - 情報メッセージ
n - ノートメッセージ
%n エラー番号 (数字を検索)
%m エラーメッセージ (文字列を検索)
%r その行の残り全部 %O/%P/%Q
%p ポインタ行 ('-', '.', ' ' またはタブの列を検索し、その
長さを桁番号とする)
%*{conv} scanfに割り当てられない変換
%% 1個のリテラル '%'
%s テキスト検索 (文字列を検索)
"%f" の変換は現在の 'isfname' の設定に依存する。"~/" はホームディレクトリ名に
展開され、環境変数も展開される。
変換 "%f" と "%m" はその文字列の終端を検出しなければならない。通常は、後に続く
文字と要素がマッチすれば、そこが終端になる。もし後に続く要素がなかったら、その
行の残りの部分がマッチする。"%f" の後に '%' かバックスラッシュが続いているな
ら、それは 'isfname' 文字の列を検索する。
MS-Windowsでは、"C:" で始まる部分は "%f" に含まれる。"%f:" と指定したときでも
そうなる。これはアルファベット1文字の名前のファイルは検出されないことを意味す
る。
"%p" の後には通常 "^" をつける。これは、以下のような出力によってエラーの桁を示
すコンパイラ用に使える:
errorformat-javacを参照。
"%s" はエラー行の位置を探すためのテキストを指定する。そのテキストは文字列リテ
ラルして使われる。検索テキストに正確にマッチするエラー行を探すために、"^" と
"$" がテキストに加えられる。また、テキストの先頭に "\V" が追加され、"very
nomagic" とされる。"%s" はエラー出力中の行番号がない行を探すために使うことがで
きる。シェルコマンド "grep" の出力のように。
パターンがある場合は行番号は使われない。
"%o" はQuickfix項目の中のモジュール名を指定する。もし指定があればそれがファイ
ル名の代わりにQuickfixエラーウィンドウの中で使われる。モジュール名は結果を表示
するためだけに使われ、ファイル名はそのファイルにジャンプするときに使われる。
ディレクトリを変更する
次の大文字の変換文字は、特別なフォーマット文字列のタイプを指定する。これらのう
ち高々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 複数行情報メッセージの開始
%N 複数行ノートメッセージの開始
%A 複数行メッセージの開始 (種類指定なし)
%> 現在と同じパターンで始まっている次行 efm-%>
%C 複数行メッセージの継続
%Z 複数行メッセージの終了
これらに対して '+' と '-' をつけることもできる。efm-ignoreを参照。
パターンに "\n" を含めても、複数行のメッセージにはマッチしない。
例: コンパイラが次のフォーマットでエラーを出力したとする。
(行頭の行番号は実際の出力の一部ではない):
1 Error 275
2 line 42
3 column 3
4 ' ' expected after '--'
適切なエラーフォーマット文字列はこのようになる:
すると、このエラーに対し: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
そのためにはエラーフォーマット文字列を次のように定義する:
"%C" を "%A" の前に置いていることに注意: ' %.%#' (これは正規表現 ' .*' を意味
する) がスペースで始まるすべての行にマッチするので、それが7行目を以降を隠して
くれる。そうでないと7行目は別のエラーメッセージの始まりと解釈されてしまう。エ
ラーフォーマットは常に、リストの中から1つ1つ、最初のマッチが起こるまで試されて
いく。
efm-%>
要素 %> は 'errorformat' の最初の方に出てくるパターンを試すのを避けるために使
える。これはほとんど何にでもマッチするパターンに便利である。例えば、エラーが
このようなら:
Error in line 123 of foo.c:
unknown variable "i"
これは以下でマッチできる:
重要: エラーフォーマットのどの部分が以前にマッチしたかは記憶されていない。すな
わち、エラーファイルの各行が毎回エラーフォーマットの各行に対してテストされる。
例えば、次のようになっているとする:
ン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
このログファイルは[...]で囲まれたファイルに対し複数のメッセージを示している。
これは次のエラーフォーマットで適切に解釈できる:
: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' に設定することができるだろう (note:
コンマ直後の空白は無視される)。完全にマッチした最初のパターンが採択される。マッ
チするものが無い場合、最後にマッチした部分が使われるが、ファイルネームは除外さ
れエラーメッセージは全体のメッセージとして設定される。複数のコンパイラからの出
力メッセージにマッチしてしまうパターンがあった (しかし正確には一致しない) 時に
は、より制限されたもの {訳注: 他のメッセージにマッチし難いもの} の後に置く。パ
ターンの先頭にコンマを含めるにはバックスラッシュ (":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" では空白の前にバックスラッシュが必要。
=============================================================================
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+=を参照。
Jikes(TM)はオプション "+E" とともに起動されたときは1行エラーメッセージを出力す
る。これは次によってマッチできる。
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]を受
け取るために、上のエラーフォーマットを修正しなければならない:
javacやjikesとantをともに扱うためにこの 'errorformat' を調整することができる。
jikesを使っているなら、jikesの+Eコマンドラインスイッチを使うことをantに教えな
ければならない (このスイッチはjikesに1行エラーメッセージを生成させる)。これが
build.xmlファイルの2行目が行っていることである:
javac、jikesと組み合わせたantを扱う 'errorformat' はこうである:
errorformat-jade
jade (http://www.jclark.com/ 参照) のエラーを解釈するのは簡単である:
errorformat-LaTeX
次のは複数行に渡ってエラーメッセージを表示する (La)TeX タイプセッティング
システム用の 'errorformat' 文字列を指定する一つの例である。":clist" や ":cc"
等々のコマンドは先行する空白を削除して複数行のものを一行にまとめて表示する。
以下のLaTeX用errorformatはマルチラインエラーを出力する他のコンパイラへ応用する
のは簡単だろう。
コマンドはvimrcファイルか別のVim scriptファイルに書ける。例えばLaTeXに関連し
た内容を含むスクリプトをLaTeXソースの編集時にだけ読みこまれるようにする。
サンプルの全行をコピーしたことを確認する (順番もそのまま)。行の始まりに見るこ
とのできる '\' の表記はline-continuationを参照。
まず 'makeprg' をLaTeXが最初のエラーで止まることなく複数のエ
ラーを返すように準備する。
マルチラインエラーメッセージの始まり:
いる。幾つかの正規表現の意味:
- "%.%#" (".*") 文字列 (空文字列も含む) にマッチ
- "%*\\d" ("\d\+") 数字にマッチ
いる:
よってメッセージに含まないようにする。
特定(記述)されているわけではない;ログのあらゆる所で与えられ、
括弧にくくられている。
続くパターンはそれらの名前を取り出し内部スタックに保存しようと
試みる。パターンは時として一つの行を複数回走査 (一つ目を
見つけた後、同じ行に次のを発見しようと) するので、パターンの
末尾の "%r" が行の残りの部分が次の試行で解釈の対象になることと、
行の末尾に達するまでそれが繰り返されることを示す。
'('...')' でくくられたファイル名を読み飛ばす;明らかにエラーを
含まないファイルはスタックに積まない:
幾つかのケースにおいてLaTeXの出力したログの中のファイル名を正確に取り出す事が
できないことに注意。括弧の対応が正しくつかない時パーサーは混乱してしまう。上記
のサンプルはもっとも一般的なケースだけ検出できるようにしてある。目的に合わせて
このサンプルを変える事はできる。例えば全てのいまいましい "Overfull ..." という
警告メッセージがエラーとして認識されてしまう事を防ぐ事ができる。
付け加えてLaTeXコンパイラの出力をフィルタリングするには、[La]TeXコンパイラに
よって生成されるファイル*.logを直接読むことも可能である。これは起こる可能性の
あるエラーについてより便利な情報を沢山含んでいる。しかしそのように複雑なファイ
ルを正確に解釈するには、外部フィルタを使うほうが良い。そのようなVimに識別され
るフィルタの作り方はずっと以前に述べたので参照。
errorformat-Perl
$VIMRUNTIME/tools にefm_perl.plスクリプトがある。これはPerlのエラーメッセージ
をフィルタし、quickfixモードが理解できるフォーマットに変換する。使い方はファイ
ルの先頭を参照。(このスクリプトはもう非推奨で、今は compiler-perl を参照のこ
と)
=============================================================================
10. Quickfix ウィンドウのカスタマイズ quickfix-window-function
quickfix ウィンドウおよび location リストウィンドウ内で各行を表示するデフォル
トのフォーマットは:
<filename>|<lnum> col <col>|<text>
各行で表示されるのは getqflist() 関数が返す、"bufnr", "lnum", "col", "text"
の各フィールドに相当する値。
いくつかの quickfix/location リストでは、表示テキストのカスタマイズが必要。例
えば、quickfixのエントリにファイル名のみが存在し、ファイル名の後にあるフィール
ド区切りの2つの "|" が不要な場合。あるいはファイル名をカスタマイズしてパスを表
示する場合。デフォルトでは、ファイルについてカレントディレクトリ以下ではなく、
完全なパス (長すぎるかもしれない) が表示される。ファイルのパスは共通の親ディレ
クトリについてシンプル化の必要があるかもしれない。
表示するテキストは 'quickfixtextfunc' オプションに Vim の関数を設定することで
カスタマイズできる。この関数は辞書を引数として呼ばれ、quickfix か location ウィ
ンドウで表示される文字列のリストを返さなくてはならない。引数の辞書は以下の
フィールドを持っている:
quickfix quickfix リストを呼ぶときは1が設定され、location リストのとき
は0が設定される。
winid location リストの時、そのウィンドウIDが設定される。quickfix
リストの時、0が設定される。getloclist() で location リストの項
目を取得するのに使える。
id quickfix か location リストの識別子
start_idx 返されたテキストの最初の項目のインデックス
end_idx 返されたテキストの最後の項目のインデックス
関数は項目の start_idx から end_idx について quickfix ウィンドウに表示する単一
の行の表示テキストを返さなくてはならない。関数は項目の情報を getqflist() 関
数から quickfix リストを識別する識別子 "id" で取れる。location リストの時は、
'winid' 引数付きで getloclist() 関数を使う。空のリストが返された場合、全エント
リの表示にデフォルトのフォーマットが使われる。返されたリストの項目が空文字列の
場合、そのエントリに一致する項目の表示にデフォルトのフォーマットが使われる。
もし quickfix か location リストで固有のカスタマイズが必要ならば、利用する
setqflist() か setloclist() 関数で 'quickfixtextfunc' 属性をリストに設定
できる。これは 'quickfixtextfunc' を上書きする。
下の例では履歴ファイル (v:oldfiles) を quickfix ウィンドウに表示している。そ
こでは各項目の行番号、カラム番号、関連するエラーのテキストはなく、
'quickfixtextfunc' の関数はファイル名だけを返している。
例:
vim:tw=78:ts=8:noet:ft=help:norl:
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
10. Quickfix ウィンドウのカスタマイズ quickfix-window-function
コンパイル時に+quickfix機能が無効にされた場合は、quickfixコマンドは使えない。
=============================================================================
1. QuickFixコマンドの使い方 quickfix Quickfix E42
Vimには編集-コンパイル-編集のサイクルを加速するための特別なモードがある。これ
はAmigaのManx's Aztec C compilerのquickfixオプションにインスパイアされた。Cコ
ンパイラから出力されたエラーメッセージをファイルに保存し、Vimでそのエラーに
ジャンプするというアイデアである。エラーメッセージを全部覚えておかなくても、そ
れぞれの問題を検証し、修正することができる。
quickfixコマンドはより一般的に、ファイル中の位置のリストを作成し、ジャンプする
ために使うことができる。例えば、:vimgrepはパターンにマッチした位置をリストす
る。スクリプト中でgetqflist()を使ってこれらの位置を参照することができる。
そのため、編集・コンパイル・修正のサイクル以外にも多くの事に利用できる。
ファイルにエラーメッセージがあるなら "vim -q filename" で起動する:
vim -q filename
Vim の中でコマンドを実行し結果を得る方法の一つに:makeコマンドがある (後述)。
各コンパイラからのエラーメッセージを解釈させるためには、オプション
'errorformat' をセットする (下のerrorformatを参照)。
quickfix-ID
各quickfixリストはquickfix IDと呼ばれる一意な識別子を持ち、この番号はVimセッ
ションの中で変わらない。getqflist() 関数はリストに割り当てられた識別子の取得
に使用できる。quickfixリスト番号もある。この番号は、10個以上のリストがquickfix
スタックに追加されるたびに変更される可能性がある。
location-list E776
locationリストはウィンドウローカルなquickfixリストである。:vimgrep, :grep,
:helpgrep, :make などのコマンドはquickfixリストを作成するが、それらに対応
する :lvimgrep, :lgrep, :lhelpgrep, :lmake などのコマンドを使うことで
locationリストを得ることができる。
location-list-file-window
locationリストはウィンドウに関連付けられていて、各ウィンドウが別々のlocationリ
ストを持つことができる。locationリストは1個のウィンドウにだけ関連付けることが
できる。locationリストはquickfixリストとは独立している。
locationリストを持つウィンドウが分割されると、新しいウィンドウはlocationリスト
のコピーを得る。locationリストへの参照が全てなくなると、そのlocationリストは破
棄される。
quickfix-changedtick
全てのquickfixリストとlocationリストはそのリストに行われた変更の総数を追跡する
読み込み専用のchangedtick変数を持つ。quickfixリストが変更されるたびに、この総
数はインクリメントされる。これは、リストが変更されたときだけアクションを実行す
ることに使用できる。getqflist() および getloclist() 関数は changedtickの現
在の値を問い合わせるのに使用できる。changedtick変数を変更することはできない。
以下のquickfixコマンドが利用できる。locationリストコマンドはquickfixコマンドに
似ていて、quickfixコマンドのプリフィックス 'c' が 'l' に置き換わっている。
E924
locationリストコマンドで処理されているにもかかわらず現在のウィンドウが
autocommand により閉じられる場合、それは中断される。
E925 E926
locationリストコマンドで処理されているにもかかわらず現在のquickfixまたは
locationリストが autocommand に変更される場合、それは中断される。
:cc
:cc[!] [nr] エラー [nr]を表示する。[nr]が省略されると同じエラーが
:[nr]cc[!] 再度表示される。[!]が無く、現在のバッファに変更が有り
ウィンドウが1つしか無く、'hidden' も 'autowrite' もoff
である場合には、他のバッファへジャンプする事は無い。
[!]を使用して他のバッファに移る時、現在のバッファへの
変更点は、'hidden' がセットされているか別のウィンドウ
が開いているかしない場合、破棄されてしまう。
バッファ移動の際は設定 'switchbuf' が関係してくる。
quickfixウィンドウで使用するときは、現在行の "." や 最
終行の "$" を含む行番号を使用できる。
:ll
:ll[!] [nr] ":cc" と同様だが、quickfixリストでなくカレントウィンド
:[nr]ll[!] ウのlocationリストが使われる。
:cn :cne :cnext E553
:[count]cn[ext][!] ファイル名を含むエラーリストで[count]個後のエラーを表
示する。ファイル名が無かった場合[count]個後のエラーに
移動する。[!]と 'switchbuf' については:ccを参照。
:lne :lnext
:[count]lne[xt][!] ":cnext" と同様だが、quickfixリストでなくカレントウィ
ンドウのlocationリストが使われる。
:[count]cN[ext][!] :cp :cprevious :cprev :cN :cNext
:[count]cp[revious][!] ファイル名を含むエラーリストで[count]個前のエラーを表
示する。ファイル名が無かった場合[count]個前のエラーに
移動する。[!]と 'switchbuf' については:ccを参照。
:[count]lN[ext][!] :lp :lprevious :lprev :lN :lNext
:[count]lp[revious][!] ":cNext" と ":cprevious" と同様だが、quickfixリストで
なく、カレントウィンドウのlocationリストが使われる。
:cabo :cabove
:[count]cabo[ve] カレントバッファの現在行の [count] 上のエラーに移動す
る。[count] を省略すると、1が使用される。エラーがない
場合は、エラーメッセージが表示される。quickfixリストの
エントリは、バッファ番号と行番号でソートされていると仮
定する。同じ行に複数のエラーがある場合は、最初のエント
リだけが使用される。[count] が現在の行より上のエントリ
の数を超えると、ファイル内の最初のエラーが選択される。
:lab :labove
:[count]lab[ove] quickfixリストの代わりにカレントウィンドウのlocationリ
ストが使用されることを除けば、":cabove" と同じ。
:cbel :cbelow
:[count]cbel[ow] カレントバッファの現在行の [count] 下にあるエラーに移
動する。[count] を省略すると、1が使用される。エラーが
ない場合は、エラーメッセージが表示される。quickfixリス
トのエントリは、バッファ番号と行番号でソートされている
と仮定する。同じ行に複数のエラーがある場合は、最初のエ
ントリだけが使用される。[count] が現在の行より下のエン
トリの数を超えると、ファイル内の最後のエラーが選択され
る。
:lbel :lbelow
:[count]lbel[ow] quickfixリストの代わりにカレントウィンドウのlocationリ
ストが使用されることを除けば、":cbelow" と同じ。
:cbe :cbefore
:[count]cbe[fore] カレントバッファ内の現在のカーソル位置の [count] 前の
エラーに移動する。[count] を省略すると、1が使用される。
エラーがない場合は、エラーメッセージが表示される。
quickfixリストのエントリは、バッファ、行番号および桁番
号でソートされていると仮定する。[count] が現在位置より
前のエントリ数を超えると、ファイル内の最初のエラーが選
択される。
:lbe :lbefore
:[count]lbe[fore] quickfixリストの代わりにカレントウィンドウのlocationリ
ストが使用されることを除けば、":cbefore" と同じ。
:caf :cafter
:[count]caf[ter] カレントバッファ内の現在のカーソル位置の [count] 後の
エラーに移動する。[count] を省略すると、1が使用される。
エラーがない場合は、エラーメッセージが表示される。
quickfixリストのエントリは、バッファ、行番号および桁番
号でソートされていると仮定する。[count] が現在位置以降
のエントリ数を超えると、ファイル内の最後のエラーが選択
される。
:laf :lafter
:[count]laf[ter] quickfixリストの代わりにカレントウィンドウのlocationリ
ストが使用されることを除けば、":cafter" と同じ。
:cnf :cnfile
:[count]cnf[ile][!] ファイル名を含むエラーリストで[count]個後のファイルの
最初のエラーを表示する。ファイル名が無いか後のファイル
が無い場合には、[count]後のエラーに移動する。[!]と
'switchbuf' については:ccを参照。
:lnf :lnfile
:[count]lnf[ile][!] ":cnfile" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:[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リストでな
く、カレントウィンドウのlocationリストが使われる。
:crewind :cr
:cr[ewind][!] [nr] [nr]のエラーを表示する。[nr]が省略されると一番最初のエ
ラーが表示される。:ccを参照。
:lrewind :lr
:lr[ewind][!] [nr] ":crewind" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
: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リストでなく、カレント
ウィンドウのlocationリストが使われる。
:cq :cquit
:cq[uit][!]
:{N}cq[uit][!]
:cq[uit][!] {N} Vim をエラーコード {N} で終了する。{N} の既定は 1。
Vim がほかのプログラムから呼ばれたときに有用である:
例、コンパイラが同じファイルを再度コンパイルする事が無
くなる、git commit がコミット処理を中断する、fc
(bash や zsh のようなシェルの組み込みコマンド) がコマ
ンドを起動しない、など。
{N} を 0 にすることもできる。その場合はVimは通常終了す
る。
警告: ファイルに対する変更はすべて失われる ([!] を指定
しなくても)! このコマンドは、システムへの戻り値が非零
であるということ以外 ":qall!" :qall と同じである。
:cf :cfile
:cf[ile][!] [errorfile] エラーファイルを読みこみ最初のエラーへ移動する。Vimが
オプション -q で起動された時には自動的に行われる。コン
パイルの間Vimを実行したままにしたい時に使うことができ
る。エラーファイルの名前を与えればオプション
'errorfile' に [errorfile]が設定される。[!]について
は :cc を参照。
エラーファイルのエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lf :lfi :lfile
:lf[ile][!] [errorfile] ":cfile" と同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。コマンドラインオプ
ション -q を使ってlocationリストを設定することはできな
い。
:cg[etfile] [errorfile] :cg :cgetfile
エラーファイルを読み込む。":cfile" に似ているが、最初
のエラーに移動しない。
エラーファイルのエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lg[etfile] [errorfile] :lg :lge :lgetfile
":cgetfile" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:caddf :caddfile
:caddf[ile] [errorfile] エラーファイルを読み込み、現在のquickfixリストにエラー
を追加する。quickfixリストがまだない場合は、新しいリス
トが作成される。
エラーファイルのエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:laddf :laddfile
:laddf[ile] [errorfile] ":caddfile" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cb :cbuffer E681
:cb[uffer][!] [bufnr] カレントバッファからエラーリストを読み込む。[bufnr] を
指定すると、カレントバッファの代わりにそのバッファが使
われる。bufnrには読み込まれているバッファ番号を指定し
なければならない。範囲を指定すると、読み込む行を指定す
ることができる。範囲指定がないとバッファ全体が使われ
る。
[!]については:ccを参照。
:lb :lbuffer
:lb[uffer][!] [bufnr] ":cbuffer" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cgetb :cgetbuffer
:cgetb[uffer] [bufnr] カレントバッファからエラーリストを読み込む。":cbuffer"
と同じだが、最初のエラーにジャンプしない点が異なる。
:lgetb :lgetbuffer
:lgetb[uffer] [bufnr] ":cgetbuffer" と同様だが、quickfixリストでなく、カレン
トウィンドウのlocationリストが使われる。
:cad :cadd :caddbuffer
:cad[dbuffer] [bufnr] カレントバッファからエラーリストを読み込み、現在の
quickfixリストにエラーを追加する。quickfixリストがまだ
存在しない場合は、新しいリストが作成される。それ以外は
":cbuffer" と同じ。
:laddb :laddbuffer
:laddb[uffer] [bufnr] ":caddbuffer" と同様だが、quickfixリストでなく、カレン
トウィンドウのlocationリストが使われる。
:cex :cexpr E777
:cex[pr][!] {expr} {expr} の結果を使って quickfix リストを作成し、最初の
エラーにジャンプする。
{expr} が文字列のときは、その文字列を改行コードで区切
り、各行を 'errorformat' のグローバル値に従って解釈
し、結果を quickfix リストに追加する。
{expr} がリストのときはリストの各文字列要素を解釈し、
quickfix リストに追加する。リスト中の文字列でない要素
は無視される。
[!]については:ccを参照。
例:
:cexpr system('grep -n xyz *')
:cexpr getline(1, '$')
:cexpr getline(1, '$')
:lex :lexpr
:lex[pr][!] {expr} :cexprと同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。
:cgete :cgetexpr
:cgete[xpr] {expr} {expr}の結果を使ってquickfixリストを作成する。:cexpr
と同様だが、最初のエラーにジャンプしない点が異なる。
:lgete :lgetexpr
:lgete[xpr] {expr} :cgetexprと同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cadde :caddexpr
:cadde[xpr] {expr} {expr}を評価し、結果の行を現在のquickfixリストに追加す
る。quickfixリストがまだ無い場合は、新しいリストが作成
される。現在のカーソル位置は変わらない。より詳しくは
:cexprを参照。
例:
:g/mypattern/caddexpr expand("%") . ":" . line(".") . ":" . getline(".")
:lad :addd :laddexpr
:lad[dexpr] {expr} ":caddexpr" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cl :clist
:cl[ist] [from] [, [to]]
有効なエラーを全て列挙するquickfix-valid。[from] 及
び/もしくは [to] で行数を指定された場合、その範囲のエ
ラーが表示される。負であった場合最後のエラーから数え
る。-1が最後のエラーとなる。設定 'switchbuf' がバッファ
の移動に関係する。
:filter コマンドは、指定されたパターンに一致する
quickfixのエントリだけを表示するために使用できる。パ
ターンは、エントリのファイル名、モジュール名、パターン
およびテキストと照合される。
:cl[ist]! [from] [, [to]]
全てのエラーを表示する。
:lli :llist
:lli[st] [from] [, [to]]
":clist" と同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。
:lli[st]! [from] [, [to]]
カレントウィンドウのlocationリストの中身を全部表示す
る。
正しいエラーの位置は隠されたマークによって示されているので、例え行を挿入したり
削除したとしても問題はない (Manx's Z editorではそうではない)。時々マークが幾つ
かの理由で消されてしまう事があり、メッセージ "line changed" がその警告となる。
一度Vimを終了し再起動した場合マークは失われ正しいエラー位置は把握できない。
quickfixコマンド (':make', ':grep' など) を実行する前後に2つの自動コマンドが利
用できる。詳しくは QuickFixCmdPre と QuickFixCmdPost を参照。
QuickFixCmdPost-example
'encoding' とロケールが異なる場合、コンパイラのエラーメッセージと Vim 内部のエ
ンコーディングが異なる場合がある。次のようにすれば、このメッセージを変換できる:
function QfMakeConv()
let qflist = getqflist()
for i in qflist
let i.text = iconv(i.text, "cp936", "utf-8")
endfor
call setqflist(qflist)
endfunction
let qflist = getqflist()
for i in qflist
let i.text = iconv(i.text, "cp936", "utf-8")
endfor
call setqflist(qflist)
endfunction
au QuickfixCmdPost make call QfMakeConv()
代わりに 'makeencoding' オプションを使うこともできる。quickfix-title
すべてのquickfixリストとlocationリストはタイトルを持つ。デフォルトではタイトル
はそのリストを作成したコマンドに設定される。getqflist() と getloclist() 関
数はそれぞれquickfixリストとlocationリストのタイトルを取得するために使われる。
setqflist() と setloclist() 関数はそれぞれquickfixリストとlocationリストの
タイトルを変更するために使われる。例:
call setqflist([], 'a', {'title' : 'Cmd output'})
echo getqflist({'title' : 1})
call setloclist(3, [], 'a', {'title' : 'Cmd output'})
echo getloclist(3, {'title' : 1})
echo getqflist({'title' : 1})
call setloclist(3, [], 'a', {'title' : 'Cmd output'})
echo getloclist(3, {'title' : 1})
quickfix-index
いずれかのquickfixコマンド(例えば :cc, :cnext, :cprev 等)を使用して
quickfix/locationリストエントリに移動すると、そのエントリが現在選択されている
エントリになる。quickfix/locationリストで現在選択されているエントリのインデッ
クスは、getqflist()/getloclist()関数を使って取得できる。例:
echo getqflist({'idx' : 0}).idx
echo getqflist({'id' : qfid, 'idx' : 0}).idx
echo getloclist(2, {'idx' : 0}).idx
echo getqflist({'id' : qfid, 'idx' : 0}).idx
echo getloclist(2, {'idx' : 0}).idx
新しいquickfixリストの場合、最初のエントリが選択され、インデックスは1になる。
すべてのquickfix/locationリスト内のすべてのエントリは、setqflist()関数を使用し
て現在選択されているエントリとして設定できる。例:
call setqflist([], 'a', {'idx' : 12})
call setqflist([], 'a', {'id' : qfid, 'idx' : 7})
call setloclist(1, [], 'a', {'idx' : 7})
call setqflist([], 'a', {'id' : qfid, 'idx' : 7})
call setloclist(1, [], 'a', {'idx' : 7})
quickfix-size
quickfixリストとlocationリストの中の項目の数をそれぞれ getqflist() と
getloclist() 関数を使用して取得できる。例:
echo getqflist({'size' : 1})
echo getloclist(5, {'size' : 1})
echo getloclist(5, {'size' : 1})
quickfix-context
任意のVimの型はquickfixリストまたはlocationリストとのコンテキストとして関連付
けることができる。setqflist() と setloclist() 関数はコンテキストをquickfix
とlocationリストにそれぞれ関連付けることに使用できる。getqflist() と
getloclist() 関数はそれぞれquickfixとlocationリストのコンテキストの取得に使
用できる。これは複数のquickfix/locationリストを取り扱うVimプラグインにとって便
利である。
例:
let somectx = {'name' : 'Vim', 'type' : 'Editor'}
call setqflist([], 'a', {'context' : somectx})
echo getqflist({'context' : 1})
call setqflist([], 'a', {'context' : somectx})
echo getqflist({'context' : 1})
let newctx = ['red', 'green', 'blue']
call setloclist(2, [], 'a', {'id' : qfid, 'context' : newctx})
echo getloclist(2, {'id' : qfid, 'context' : 1})
call setloclist(2, [], 'a', {'id' : qfid, 'context' : newctx})
echo getloclist(2, {'id' : qfid, 'context' : 1})
quickfix-parse
getqflist() 関数を使用してquickfixリストを作成または変更せずに、'errorformat'
を使用して行のリストをパースできる。例:
echo getqflist({'lines' : ["F1:10:Line10", "F2:20:Line20"]})
echo getqflist({'lines' : systemlist('grep -Hn quickfix *')})
これは 'items' キーに行からパースされたquickfixの項目のリストが含まれている辞echo getqflist({'lines' : systemlist('grep -Hn quickfix *')})
書を返す。以下は 'errorformat' オプションを変更せずにカスタム 'errorformat' を
使って行をパースする方法を示している。
echo getqflist({'efm' : '%f#%l#%m', 'lines' : ['F1#10#Line']})
quickfixリストやlocationリスト中のバッファに対してコマンドを実行:
:cdo
:cdo[!] {cmd} quickfix リスト中の有効な各項目に対して {cmd} を実行す
る。以下の操作と同様に動作する:
:cfirst
:{cmd}
:cnext
:{cmd}
etc.
カレントファイルが破棄できず(abandon)、かつ[!] が与:{cmd}
:cnext
:{cmd}
etc.
えられない場合、このコマンドは失敗する。
次のエントリへの移動が失敗すると、実行は停止する。
最後のバッファ (またはエラーが起こったバッファ) がカレ
ントウィンドウになる。
{cmd} の中では '|' で複数のコマンドを連結できる。
quickfixリスト中の有効な項目のみが使われる。
「範囲」を指定して項目を選択することができる。例:
:10,$cdo cmd
こうすることで1番目から9番目までをスキップできる。Note: このコマンドを実行している間、Syntax 自動コマン
ドイベントが 'eventignore' に追加され、無効化される。
これは各バッファの編集を大幅にスピードアップさせる。
:bufdo、:tabdo、:argdo、:windo、:ldo、
:cfdo、:lfdo も参照。
:cfdo
:cfdo[!] {cmd} quickfixリスト中の各ファイルに対して {cmd} を実行する。
以下の操作と同様に動作する:
:cfirst
:{cmd}
:cnfile
:{cmd}
etc.
それ以外は :cdo の場合と同様である。:{cmd}
:cnfile
:{cmd}
etc.
:ldo
:ld[o][!] {cmd} カレントウィンドウのlocationリスト中の有効な各項目に対
して {cmd} を実行する。
以下の操作と同様に動作する:
:lfirst
:{cmd}
:lnext
:{cmd}
etc.
locationリスト中の有効な項目のみが使われる。:{cmd}
:lnext
:{cmd}
etc.
それ以外は :cdo の場合と同様である。
:lfdo
:lfdo[!] {cmd} カレントウィンドウのlocationリスト中の各ファイルに対し
て {cmd} を実行する
以下の操作と同様に動作する:
:lfirst
:{cmd}
:lnfile
:{cmd}
etc.
それ以外は :cdo の場合と同様である。:{cmd}
:lnfile
:{cmd}
etc.
QUICKFIX または LOCATIONリストのフィルタリング:
cfilter-plugin :Cfilter :Lfilter
quickfixリストのエントリ数が多すぎる場合は、cfilterプラグインを使用してエント
リ数を減らすことができる。プラグインをロードする:
packadd cfilter
その後で、以下のコマンドを使って、quickfix/locationリストをフィルタすることが
できる:
:Cfilter[!] /{pat}/
:Lfilter[!] /{pat}/
:Lfilter[!] /{pat}/
:Cfilter コマンドは、現在のquickfixリストの {pat} に一致するエントリから新し
いquickfixリストを作成する。{pat} はVimの正規表現 regular-expression パター
ンである。ファイル名とエントリのテキストの両方が {pat}と照合される。オプション
の ! が指定された場合、{pat} と一致しないエントリが使用される。パターンは、次
のいずれかの文字を使用して任意に囲むことができる: ', ", /。パターンが空の場合
は、最後に使用された検索パターンが使用される。
:Lfilter コマンドは :Cfilter と同じ動作をするが、カレントlocationリストを
操作する。
=============================================================================
2. エラーウィンドウ quickfix-window
:cope :copen w:quickfix_title
:cope[n] [height] 現在のエラーリストを表示するウィンドウを開く。
[height]が与えられたとき、(余地があれば) ウィンドウの
高さがその値になる。[height] を省略したときはウィンド
ウの高さは 10 行になる。
すでにquickfixウィンドウがある場合はそれがカレントウィ
ンドウになる。2 個目のquickfixウィンドウを開くことはで
きない。[height] が指定されたとき、既存のウィンドウは
その高さにリサイズされる。
quickfix-buffer
ウィンドウは 'buftype' の値が "quickfix" である特別な
バッファを含んでいる。これを変更してはならない。
ウィンドウは w:quickfix_title 変数を持っている。この変
数はquickfixリストを生成したコマンドを示している。変数
の値は 'statusline' が適切に調整されていればステータス
ラインに表示される。このバッファがquickfixコマンドまた
は関数により変更されるたびに、b:changedtick 変数はイ
ンクリメントされる。このバッファにおける変数の値は
getqflist() や getloclist() 関数を用い 'qfbufnr'
アイテムを通して取得できる。locationリストの場合は、
locationリストが削除されるときに、このバッファも削除さ
れる。
:lop :lopen
:lop[en] [height] カレントウィンドウのlocationリストを表示するウィンドウ
を開く。カレントウィンドウにlocationリストが存在すると
きだけ動作する。一度に2個以上のlocationリストを開くこ
とができる。それ以外は ":copen" と同様。
:ccl :cclose
:ccl[ose] quickfixウィンドウを閉じる。
:lcl :lclose
:lcl[ose] カレントウィンドウのlocationリストを表示しているウィン
ドウを閉じる。
:cw :cwindow
:cw[indow] [height] 認識されたエラーがあるときquickfixウィンドウを開く。
ウィンドウがすでに開いていて認識されたエラーがない場合
はウィンドウを閉じる。
:lw :lwindow
:lw[indow] [height] ":cwindow" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cbo :cbottom
:cbo[ttom] quickfix ウィンドウの最後の行にカーソルを移動し、見え
る様にスクロールする。これは非同期コールバックでエラー
を追加するのに便利である。
大量の更新に伴う多くの再描画を避けるには一度限り呼び出
すこと。
:lbo :lbottom
:lbo[ttom] 現在のウィンドウに関するlocationリストが表示されている
ウィンドウである事を除いて ":cbottom" と同じ。
通常、quickfixウィンドウはスクリーンの一番下に現れる。垂直分割したウィンドウが
ある場合は、一番右下に現れる。常に最大幅を占めるようにさせたい場合は
:botright cwindow
とする。このウィンドウをwindow-movingコマンドで移動させることもできる。例えば、一番上に移動させたければCTRL-W Kとする。
'winfixheight' オプションが設定されれば、'winheight' と 'equalalways' を無視
し、たいていその高さを維持する。高さを手動で変更することもできる (例えばステー
タスラインをマウスで上へドラッグするなど)。
quickfixウィンドウには各行に1個ずつエラーが表示される。その行数はエラー番号に
等しい。現在の項目はQuickFixLineハイライティングでハイライトされる。あなたはそ
れをあなたの好みに変更することができる。例:
:hi QuickFixLine ctermbg=Yellow guibg=Yellow
":.cc" でカーソル下のエラーに移動できる。
<Enter>キーを押すのと行をダブルクリックするのは同じ効果がある。そのエラーを含
むファイルがquickfixウィンドウの上に開かれる。そのファイルがすでにウィンドウに
開かれていたらそのウィンドウがアクティブになる。そのウィンドウにあるバッファが
変更されていて、そのエラーが別のファイルにある場合はエラーへの移動は失敗する。
まず、そのウィンドウが破棄してもよいバッファを含んでいることを確かめなければな
らない。
CTRL-W_<Enter> CTRL-W_<CR>
CTRL-W <Enter>を使うと、新しいウィンドウを開いてそこでエラーにジャンプできる。
quickfixウィンドウが一杯になったとき、2つの自動コマンドイベントが発生する。第
一は 'filetype' オプションが "qf" にセットされ、FileTypeイベントが発生する
(qf.vim も参照)。それからBufReadPostイベントが発生する。そのときのバッファ名
は "quickfix" となる。これを使ってエラーリストに対して操作を行うことができる。
例:
au BufReadPost quickfix setlocal modifiable
\ | silent exe 'g/^/s//\=line(".")." "/'
\ | setlocal nomodifiable
これは各行に行番号を追加する。文字列の置換 ":s" コマンドの中で使われている "\="\ | silent exe 'g/^/s//\=line(".")." "/'
\ | setlocal nomodifiable
に注目。これは式を評価するのに使われる。
BufWinEnterイベントも発生する。ここでもバッファ名は "quickfix" になる。
Note: 存在する quickfix リストに追加される場合、autocommand イベントは発生しま
せん。
Note: quickfixウィンドウ内で変更を加えてもエラーのリストには何の影響もない。変
更を防ぐために 'modifiable' がオフになっている。それでも行を削除や挿入した場合
は、テキストとエラー番号の関係がめちゃくちゃになる。本当にエラーリストを変更し
たいのなら、quickfixウィンドウの内容をファイルに保存し、":cfile" を実行、ファ
イルをパースさせ、新しいエラーリストとして使うこと。
location-list-window
locationリストウィンドウはlocationリストの中身を表示する。locationリストウィン
ドウを開くと、カレントウィンドウの下に開かれ、カレントウィンドウのlocationリス
トが表示される。locationリストはquickfixウィンドウに似ているが、一度に2個以上
のlocationリストウィンドウを開ける点が異なる。このウィンドウ内でlocationリスト
コマンドを使うと、表示されているlocationリストが使われる。
locationリストウィンドウからファイルを選択すると、以下のステップによって、その
ファイルを編集するウィンドウが探される。
1. locationリストウィンドウに表示されているlocationリストに関連付けられている
ウィンドウがあるなら、そのウィンドウが使われる。
2. 上のステップが失敗した場合、そのファイルが既に他のウィンドウで開かれている
なら、そのウィンドウが使われる。
3. 上のステップが失敗した場合、'buftype' がセットされていないバッファを表示し
ているウィンドウが存在するなら、そのウィンドウが使われる。
4. 上のステップが失敗した場合、新しいウィンドウでファイルが開かれる。
上の全ての場合において、選択されたウィンドウに対してまだlocationリストが関連付
けられていなかった場合、locationリストウィンドウに表示されているlocationリスト
が関連づけられる。
quickfix-window-ID
getqflist() と getloclist() 関数を使用して、quickfixウィンドウとlocationリ
ストウィンドウのウィンドウIDをそれぞれ取得できる(もしあれば)。例:
echo getqflist({'winid' : 1}).winid
echo getloclist(2, {'winid' : 1}).winid
echo getloclist(2, {'winid' : 1}).winid
getqflist-examples
getqflist() 関数と getloclist() 関数は、それぞれquickfixとlocationリストの
さまざまな属性を取得するのに使用できる。これらの関数の使用例を以下に示す:
" 現在のquickfixリストのタイトルを取得する
:echo getqflist({'title' : 0}).title
:echo getqflist({'title' : 0}).title
" 現在のquickfixリストの識別子を取得する
:let qfid = getqflist({'id' : 0}).id
:let qfid = getqflist({'id' : 0}).id
" スタックの中の4番目のquickfixリストの識別子を取得する
:let qfid = getqflist({'nr' : 4, 'id' : 0}).id
:let qfid = getqflist({'nr' : 4, 'id' : 0}).id
" 特定の識別子を持つquickfixリストが存在するかどうかを検査する
:if getqflist({'id' : qfid}).id == qfid
:if getqflist({'id' : qfid}).id == qfid
" スタックの中の現在のquickfixリストのインデックスを取得する
:let qfnum = getqflist({'nr' : 0}).nr
:let qfnum = getqflist({'nr' : 0}).nr
" 識別子により指定されたquickfixリストのitemsを取得する
:echo getqflist({'id' : qfid, 'items' : 0}).items
:echo getqflist({'id' : qfid, 'items' : 0}).items
" idにより指定されたquickfixリストの中の項目の数を取得する
:echo getqflist({'id' : qfid, 'size' : 0}).size
:echo getqflist({'id' : qfid, 'size' : 0}).size
" スタックの中の3番目のquickfixリストのcontextを取得する
:echo getqflist({'nr' : 3, 'context' : 0}).context
:echo getqflist({'nr' : 3, 'context' : 0}).context
" スタックの中のquickfixリストの数を取得する
:echo getqflist({'nr' : '$'}).nr
:echo getqflist({'nr' : '$'}).nr
" 現在のquickfixリストが変更された回数を取得する
:echo getqflist({'changedtick' : 0}).changedtick
:echo getqflist({'changedtick' : 0}).changedtick
" 識別子により指定されたquickfixリストの中の現在の項目を取得する
:echo getqflist({'id' : qfid, 'idx' : 0}).idx
:echo getqflist({'id' : qfid, 'idx' : 0}).idx
" 識別子を使用して全てのquickfixリスト属性を取得する
:echo getqflist({'id' : qfid, 'all' : 0})
:echo getqflist({'id' : qfid, 'all' : 0})
" linesのリストの値からテキストをパースしてquickfixリストを返す
:let myList = ["a.java:10:L10", "b.java:20:L20"]
:echo getqflist({'lines' : myList}).items
:let myList = ["a.java:10:L10", "b.java:20:L20"]
:echo getqflist({'lines' : myList}).items
" カスタム 'efm' を使用してテキストをパースしてquickfixリストを返す
:echo getqflist({'lines' : ['a.c#10#Line 10'], 'efm':'%f#%l#%m'}).items
:echo getqflist({'lines' : ['a.c#10#Line 10'], 'efm':'%f#%l#%m'}).items
" quickfixリストのウィンドウIDを取得する
:echo getqflist({'winid' : 0}).winid
:echo getqflist({'winid' : 0}).winid
" quickfixリストのウィンドウのバッファ番号を取得する
:echo getqflist({'qfbufnr' : 0}).qfbufnr
:echo getqflist({'qfbufnr' : 0}).qfbufnr
" 現在のlocationリストのcontextを取得する
:echo getloclist(0, {'context' : 0}).context
:echo getloclist(0, {'context' : 0}).context
" 3番目のウィンドウのlocationリストのウィンドウIDを取得する
:echo getloclist(3, {'winid' : 0}).winid
:echo getloclist(3, {'winid' : 0}).winid
" 3番目のウィンドウのlocationリストのバッファ番号を取得する
:echo getloclist(3, {'qfbufnr' : 0}).qfbufnr
:echo getloclist(3, {'qfbufnr' : 0}).qfbufnr
" locationリストウィンドウ(winnr: 4)のファイルウィンドウIDを取得する
:echo getloclist(4, {'filewinid' : 0}).filewinid
:echo getloclist(4, {'filewinid' : 0}).filewinid
setqflist-examples
setqflist() 関数と setloclist() 関数は、それぞれquickfixとlocationリストの
さまざまな属性を設定するのに使用できる。これらの関数の使用例を以下に示す:
" titleとcontextを持つ空のquickfixリストを作成する
:let t = 'Search results'
:let c = {'cmd' : 'grep'}
:call setqflist([], ' ', {'title' : t, 'context' : c})
:let t = 'Search results'
:let c = {'cmd' : 'grep'}
:call setqflist([], ' ', {'title' : t, 'context' : c})
" 現在のquickfixリストのtitleを設定する
:call setqflist([], 'a', {'title' : 'Mytitle'})
:call setqflist([], 'a', {'title' : 'Mytitle'})
" 識別子により指定されたquickfixリストの現在のエントリを変更する
:call setqflist([], 'a', {'id' : qfid, 'idx' : 10})
:call setqflist([], 'a', {'id' : qfid, 'idx' : 10})
" 識別子により指定されたquickfixリストのcontextを設定する
:call setqflist([], 'a', {'id' : qfid, 'context' : {'val' : 100}})
:call setqflist([], 'a', {'id' : qfid, 'context' : {'val' : 100}})
" コマンド出力から新しいquickfixリストを作成する
:call setqflist([], ' ', {'lines' : systemlist('grep -Hn main *.c')})
:call setqflist([], ' ', {'lines' : systemlist('grep -Hn main *.c')})
" カスタムefmを使用してテキストをパースして特定のquickfixリストに追加する
:call setqflist([], 'a', {'id' : qfid,
\ 'lines' : ["a.c#10#L10", "b.c#20#L20"], 'efm':'%f#%l#%m'})
:call setqflist([], 'a', {'id' : qfid,
\ 'lines' : ["a.c#10#L10", "b.c#20#L20"], 'efm':'%f#%l#%m'})
" 識別子により指定されたquickfixリストにitemsを追加する
:let newItems = [{'filename' : 'a.txt', 'lnum' : 10, 'text' : "Apple"},
\ {'filename' : 'b.txt', 'lnum' : 20, 'text' : "Orange"}]
:call setqflist([], 'a', {'id' : qfid, 'items' : newItems})
:let newItems = [{'filename' : 'a.txt', 'lnum' : 10, 'text' : "Apple"},
\ {'filename' : 'b.txt', 'lnum' : 20, 'text' : "Orange"}]
:call setqflist([], 'a', {'id' : qfid, 'items' : newItems})
" 識別子により指定されたquickfixリストを空にする
:call setqflist([], 'r', {'id' : qfid, 'items' : []})
:call setqflist([], 'r', {'id' : qfid, 'items' : []})
" スタックの中の全てのquickfixリストを開放する
:call setqflist([], 'f')
:call setqflist([], 'f')
" 4番目のquickfixリストのtitleを設定する
:call setqflist([], 'a', {'nr' : 4, 'title' : 'SomeTitle'})
:call setqflist([], 'a', {'nr' : 4, 'title' : 'SomeTitle'})
" スタックの最後に新しいquickfixリストを作成する
:call setqflist([], ' ', {'nr' : '$',
\ 'lines' : systemlist('grep -Hn class *.java')})
:call setqflist([], ' ', {'nr' : '$',
\ 'lines' : systemlist('grep -Hn class *.java')})
" コマンド出力から新しいlocationリストを作成する
:call setloclist(0, [], ' ', {'lines' : systemlist('grep -Hn main *.c')})
:call setloclist(0, [], ' ', {'lines' : systemlist('grep -Hn main *.c')})
" 3番目のウィンドウのlocationリスト項目を置き換える
:call setloclist(3, [], 'r', {'items' : newItems})
:call setloclist(3, [], 'r', {'items' : newItems})
=============================================================================
3. 複数のエラーリストを使う quickfix-error-lists
これまでは一つだけのエラーリストがあると仮定してきた。実際は最後に使った10個
迄のエラーリストが記憶される。新しいリストではじめた時には、以前のリストは自動
的に保存される。古いエラーリストにアクセスするために、2つのコマンドが用意され
ている。これらは存在するエラーリストの内1つを現在のエラーリストに設定する。
:colder :col E380
:col[der] [count] 古いエラーリストへ移動する。[count]が与えられると、そ
の回数繰り返し移動する。既に一番古いエラーリストにいる
場合、エラーメッセージが表示される。
:lolder :lol
:lol[der] [count] :colder と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:cnewer :cnew E381
:cnew[er] [count] 新しいエラーリストへ移動する。[count]が与えられると、
その回数繰り返し移動する。既に一番新しいエラーリストに
いる場合、エラーメッセージが表示される。
:lnewer :lnew
:lnew[er] [count] :cnewer と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:chistory :chi
:[count]chi[story] エラーリストの一覧を表示する。現在のリストは ">" でマー
クされる。出力は以下の様になる:
error list 1 of 3; 43 errors :make
> error list 2 of 3; 0 errors :helpgrep tag
error list 3 of 3; 15 errors :grep ex_help *.c
[count] が与えられると、count番目のquickfixリストがカ
レントリストになる。例:
" 4番目のquickfixリストをカレントにする
:4chistory
:4chistory
:lhistory :lhi
:[count]lhi[story] locationリストの一覧を表示する。:chistory の様に。
新しいエラーリストが追加された時には、それがカレントリストとなる。
":colder" が実行された後で ":make" や ":grep" が実行され新しいエラーリストが追
加されたときは1個新しいリストが上書きされる。これは ":grep" grep でブラウジ
ングしているときに特に便利である。もっと最近のエラーリストを残しておきたい場合
は初めに ":cnewer 99" を行うこと。
quickfixやlocationリストのスタック数を取得するには、特別な値 '$' に設定された
リスト番号でそれぞれ、getqflist() 関数と getloclist() 関数を使用できる。例:
echo getqflist({'nr' : '$'}).nr
echo getloclist(3, {'nr' : '$'}).nr
スタック内の現在のリスト番号を取得するには:echo getloclist(3, {'nr' : '$'}).nr
echo getqflist({'nr' : 0}).nr
=============================================================================
4. :makeの使い方 :make_makeprg
:mak :make
:mak[e][!] [arguments] 1. QuickFixCmdPre に関連付けられた自動コマンドが全て
実行される。
2. オプション 'autowrite' がonならば変更のあるバッファ
は保存される。
3. 'makeef' からエラーファイルの名前が生成される。
'makeef' が "##" を含まずかつ既に名前が存在する場合
それは削除される。
4. オプション 'makeprg' で与えられたプログラム (省略時
"make") が [argument]をオプションにして実行され、出
力がerrorfileに保存される (Unixではそれも画面にecho
される)。
5. 'errorformat' を使ってerrorfileが読みこまれる。
6. QuickFixCmdPost に関連付けられた自動コマンドが全
て実行される。後述のサンプルを参照。
7. [!]が与えられていないときは最初のエラーに移動する。
8. エラーファイルが削除される。
9. :cnextや:cprevious などのコマンドでエラー間を移
動できる。上を参照。
このコマンドは如何なるコメントも受けつけず、どんな "
という文字もargumentの一部とみなされる。
プログラム出力のエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lmak :lmake
:lmak[e][!] [arguments]
":make" と同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。
コマンド ":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では ">" で、Win32では ">%s 2>&1" であ
る。これはコンパイラの出力が直接ファイルに出力されスクリーンには出力されないこ
とを意味する。Unixでは "| tee" が使用される。コンパイラがファイルに出力すると
同時にスクリーンにも表示される。使っているシェルに応じて標準エラーへの出力も含
めるために "|& tee" や "2>&1| tee" が省略値となる。
'shellpipe' が空の場合、{errorfile}が省略される。これはコンパイラ自身がエラー
ファイルを作成する場合 (Manx's Amiga C) に便利である。
QuickFixCmdPost を使ってエンコーディングを修正する
ビルドプログラムが出力するメッセージと 'encoding' の値が異なる場合がある。この
例は、Vim がそのエラーメッセージを読み込んだ後でエンコーディングを変換する方法
を示している:
function QfMakeConv()
let qflist = getqflist()
for i in qflist
let i.text = iconv(i.text, "cp936", "utf-8")
endfor
call setqflist(qflist)
endfunction
let qflist = getqflist()
for i in qflist
let i.text = iconv(i.text, "cp936", "utf-8")
endfor
call setqflist(qflist)
endfunction
au QuickfixCmdPost make call QfMakeConv()
(Faque Cheng による例)
代わりに 'makeencoding' オプションを使うこともできる。
==============================================================================
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 コマンドを作る
と次のようになる:
command! -nargs=+ NewGrep execute 'silent grep! <args>' | copen 42
5.1 Vimの内部grepの使い方
:vim :vimgrep E682 E683
:vim[grep][!] /{pattern}/[g][j][f] {file} ...
ファイル{file}から{pattern}を検索し、マッチ位置をエラー
リストに追加する。'wildignore' にマッチしたファイルは
無視される。'suffixes' にマッチしたファイルは最後に検
索される。
{pattern}はVimの検索パターンである。/ で囲まない場合、
それが{pattern}中に現れない限り、どんな非ID文字
('isident' を参照) でも使える。
'ignorecase' が適用される。パターン中に/\cを含めると
大文字小文字を区別しなくなり、/\Cを含めると区別する
ようになる。これは 'ignorecase' より優先される。
'smartcase' は適用されない。
{pattern} が空のときは(つまり // が指定されたときは)、
最後に使われた検索パターンが使用される。last-pattern
フラグ:
'g' フラグ 'g' がない場合、各行は一度だけ追加され
る。'g' がある場合は全てのマッチが追加される。
'j' フラグ 'j' がない場合、Vim は最初のマッチへジャン
プする。'j' がある場合は quickfix リストが更新さ
れるだけである。[!] を付けるとカレントバッファに
対する変更は全て失われる。
'f' フラグ 'f' を指定するとファジー文字列マッチで一致
する行が検索される。この場合 {pattern} は正規表現
ではなくリテラル文字列として扱われる。文字列への
ファジーマッチについての詳細は fuzzy-match を参
照。
QuickFixCmdPre と QuickFixCmdPost がトリガーされ
る。
マッチのために開かれたファイルはバッファ番号を使用する
が、バッファ番号の消費を避けるために、可能であれば再利
用される。
:{count}vim[grep] ...
このコマンドの前に数字が置かれると、その数が検索する
マッチの最大数となる。":1vimgrep pattern file" とする
と最初のマッチだけを検索する。マッチが存在するかどうか
だけをチェックしたく、それが見つかったらすぐに終了して
ほしい場合に便利である。
進行状況を示すため、1秒程度ごとに検索されたファイル名
が表示される。
例:
:vimgrep /an error/ *.c
:vimgrep /\<FileName\>/ *.h include/*
:vimgrep /myfunc/ **/*.c
"**" の使い方についてはstarstar-wildcardを参照。:vimgrep /\<FileName\>/ *.h include/*
:vimgrep /myfunc/ **/*.c
:vim[grep][!] {pattern} {file} ...
上と同様だが、パターンを非ID文字で囲むのでなく、空白で
パターンを区切る。パターンはID文字で始まらねばならな
い。
例:
:vimgrep Error *.c
:lv :lvimgrep
:lv[imgrep][!] /{pattern}/[g][j][f] {file} ...
:lv[imgrep][!] {pattern} {file} ...
":vimgrep" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
:vimgrepa :vimgrepadd
:vimgrepa[dd][!] /{pattern}/[g][j][f] {file} ...
:vimgrepa[dd][!] {pattern} {file} ...
":vimgrep" と同様だが、新しくエラーリストを作る代わり
に、現在のリストに追加する。
:lvimgrepa :lvimgrepadd
:lvimgrepa[dd][!] /{pattern}/[g][j][f] {file} ...
:lvimgrepa[dd][!] {pattern} {file} ...
":vimgrepadd" と同様だが、quickfixリストでなく、カレン
トウィンドウのlocationリストが使われる。
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と
同様に機能する。その場合、パターンが区切り文字で囲まれ
ていなければならないことに注意。
プログラム出力のエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lgr :lgrep
:lgr[ep][!] [arguments] ":grep" と同様だが、quickfixリストでなく、カレントウィ
ンドウのlocationリストが使われる。
:grepa :grepadd
:grepa[dd][!] [arguments]
":grep" と似ているが、新しいエラーリストを作らず、解釈
されたエラーが現在のリストに追加される。
例:
:call setqflist([])
:bufdo grepadd! something %
1番目のコマンドは新しい空のエラーリストを作成する。2番:bufdo grepadd! something %
目のコマンドはバッファリスト内の各バッファに対し
"grepadd" を実行する。最初のエラーへジャンプするのを避
けるために ! を使っていることに注意。:bufdo でジャン
プすることはできない。
引数リスト内のファイルに対して実行し、マッチがないファ
イルでのエラーを回避する例:
:silent argdo try
\ | grepadd! something %
\ | catch /E480:/
\ | endtry"
\ | grepadd! something %
\ | catch /E480:/
\ | endtry"
プログラム出力のエンコーディングが 'encoding' と異なる
場合には、'makeencoding' オプションでエンコーディング
を指定できる。
:lgrepa :lgrepadd
:lgrepa[dd][!] [arguments]
":grepadd" と同様だが、quickfixリストでなく、カレント
ウィンドウのlocationリストが使われる。
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
: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.foo" では "foo" を使い続ける。
{+eval機能なしでコンパイルされた場合には使用
できない}
"compiler" ディレクトリ内にあるVimプラグインによって、選択されたコンパイラを使
うためのオプションが設定される。:compiler はローカルオプションを設定し、
:compiler! はグローバルオプションを設定する。
current_compiler
Vimの古いバージョンをサポートするために、それらのプラグインは常に
"b:current_compiler" でなく "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
を代入する。例:
let 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\ %:S " 1つのテストケースを走らせる
となる。
次も参照。
http://vim.sourceforge.net/tip_view.php?tip_id=280.
TEX COMPILER compiler-tex
ディストリビューションに含まれているTeX用のコンパイラスクリプト
($VIMRUNTIME/compiler/tex.vim) は、可能ならmakeコマンドを使う。コンパイラがカ
レントディレクトリに "Makefile" または "makefile" というファイルを見つけたら、
*TeXファイルをmakeを使って処理しようとし、そのmakefile通りの動作をする。この場
合コンパイラは 'errorformat' を*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された
chapter2.texを編集中に
:let b:tex_flavor = 'amstex'
:compiler tex
[editing...]:compiler tex
:make mypaper
処理するファイルの名前を引数に指定しなければならないことに注意 (\inputか
\includeされたファイルを編集中に正しいファイルを処理するため; %を引数なしに置
換するポータブルな方法もよい)。これはソースではなく、ターゲットを指定するとい
うmakeの意味論ではないが、拡張子 ".tex" を除いたファイル名を指定してもよい。そ
の場合、「filename.dviまたはfilename.pdfまたは filename.[コンパイラに応じた何
らかの結果の拡張子] をメイクしろ」ということを意味する。
Note: tex コマンドライン文法はMikTex (Srinath Avadhanulaによって提案された) と
teTeX (Artem Chuprinaによってチェックされた) の両方で使えるように設定されてい
る。errorformat-LaTeXからの提案は他のシェルやOSで動かせるようにするには複雑
すぎるし、他のTeXオプションを使うことも許さない。もしあなたのTeXが
"-interaction=nonstopmode" をサポートしていなければ、コマンドラインから
\nonstopmodeを表現する他の方法とともにその旨を報告してください。
=============================================================================
7. エラーフォーマット error-file-format
errorformat E372 E373 E374
E375 E376 E377 E378
'errorformat' オプションは認識されるエラーフォーマットのリストを指定する。その
中からエラーメッセージにマッチした最初のフォーマットが使われる。複数のフォーマッ
トを指定して、数種類のメッセージに対応したり、複数のコンパイラに対応したりする
ことができる。efm-entriesを参照。
'errorformat' の各要素は、scanfに似たフォーマットを記述する文字列である。はじ
めに、scanfがどのように働くか知る必要がある。Cコンパイラのドキュメントを読むこ
と。以下はVimが理解する%の項目である。他は無効になる。
'errorformat' 中の特別な文字はコンマとバックスラッシュである。それがどう扱われ
るかはefm-entriesを参照。"%%" はリテラル "%" にマッチする。よってこれはバッ
クスラッシュでエスケープしない。
:makeと :grep の出力のすべての NUL 文字は SOH (0x01) に置換されるので注
意。
Note: デフォルトでは大文字と小文字の違いは無視される。もし大文字・小文字の区別
をしたいなら "\C" をパターンに付け加える/\C。
Vimは任意の長さの行を読み取るが、最初の4095バイトのみが使用され、残りは無視さ
れる。要素の長さは1023バイトまでである。
基本要素
%f ファイル名 (文字列を検索)
%o モジュール名 (文字列を検索)
%l 行番号 (数字を検索)
%c 桁番号 (エラーの桁を表す数字。バイトインデックス。
<Tab>1個は1桁と数える)
%v 画面上の桁番号 (エラーの画面上の桁を表す番号 (<Tab>1個
はスクリーン上8桁と数える))
%t エラーの種類 (1文字を検索):
e - エラーメッセージ
w - 警告メッセージ
i - 情報メッセージ
n - ノートメッセージ
%n エラー番号 (数字を検索)
%m エラーメッセージ (文字列を検索)
%r その行の残り全部 %O/%P/%Q
%p ポインタ行 ('-', '.', ' ' またはタブの列を検索し、その
長さを桁番号とする)
%*{conv} scanfに割り当てられない変換
%% 1個のリテラル '%'
%s テキスト検索 (文字列を検索)
"%f" の変換は現在の 'isfname' の設定に依存する。"~/" はホームディレクトリ名に
展開され、環境変数も展開される。
変換 "%f" と "%m" はその文字列の終端を検出しなければならない。通常は、後に続く
文字と要素がマッチすれば、そこが終端になる。もし後に続く要素がなかったら、その
行の残りの部分がマッチする。"%f" の後に '%' かバックスラッシュが続いているな
ら、それは 'isfname' 文字の列を検索する。
MS-Windowsでは、"C:" で始まる部分は "%f" に含まれる。"%f:" と指定したときでも
そうなる。これはアルファベット1文字の名前のファイルは検出されないことを意味す
る。
"%p" の後には通常 "^" をつける。これは、以下のような出力によってエラーの桁を示
すコンパイラ用に使える:
^
または ---------^
これは複数行のエラーメッセージでも使える。実用的なサンプルとしてはerrorformat-javacを参照。
"%s" はエラー行の位置を探すためのテキストを指定する。そのテキストは文字列リテ
ラルして使われる。検索テキストに正確にマッチするエラー行を探すために、"^" と
"$" がテキストに加えられる。また、テキストの先頭に "\V" が追加され、"very
nomagic" とされる。"%s" はエラー出力中の行番号がない行を探すために使うことがで
きる。シェルコマンド "grep" の出力のように。
パターンがある場合は行番号は使われない。
"%o" はQuickfix項目の中のモジュール名を指定する。もし指定があればそれがファイ
ル名の代わりにQuickfixエラーウィンドウの中で使われる。モジュール名は結果を表示
するためだけに使われ、ファイル名はそのファイルにジャンプするときに使われる。
ディレクトリを変更する
次の大文字の変換文字は、特別なフォーマット文字列のタイプを指定する。これらのう
ち高々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 複数行情報メッセージの開始
%N 複数行ノートメッセージの開始
%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"
これは以下でマッチできる:
:set efm=xxx,%E%>Error in line %l of %f:,%Z%m
ここで "xxx" には2番目の行にもマッチするパターンが入るとする。重要: エラーフォーマットのどの部分が以前にマッチしたかは記憶されていない。すな
わち、エラーファイルの各行が毎回エラーフォーマットの各行に対してテストされる。
例えば、次のようになっているとする:
setlocal efm=aa,bb,cc,dd,ee
ここで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' に設定することができるだろう (note:
コンマ直後の空白は無視される)。完全にマッチした最初のパターンが採択される。マッ
チするものが無い場合、最後にマッチした部分が使われるが、ファイルネームは除外さ
れエラーメッセージは全体のメッセージとして設定される。複数のコンパイラからの出
力メッセージにマッチしてしまうパターンがあった (しかし正確には一致しない) 時に
は、より制限されたもの {訳注: 他のメッセージにマッチし難いもの} の後に置く。パ
ターンの先頭にコンマを含めるにはバックスラッシュ (":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
\%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用にうまく
動作すると報告されている:
:setl efm=%A%f:%l:\ %m,%-Z%p^,%-C%.%#
または: :setl efm=%A%f:%l:\ %m,%+Z%p^,%+C%.%#,%-G%.%#
Michael F. Lambが考案した別の方法を以下に示す。これはUnix用で、最初にエラーを
フィルタリングする:
:setl errorformat=%Z%f:%l:\ %m,%A%p^,%-G%*[^sl]%.%#
:setl makeprg=javac\ %:S\ 2>&1\ \\\|\ vim-javac-filter
:setl makeprg=javac\ %:S\ 2>&1\ \\\|\ vim-javac-filter
以下の行を "vim-javac-filter" というファイルに書いて、PATHの通ったディレクトリ
(例えば~/bin) に置き、実行可能にしておく必要がある:
#!/bin/sed -f
/\^$/s/\t/\ /g;/:[0-9]\+:/{h;d};/^[ \t]*\^/G;
/\^$/s/\t/\ /g;/:[0-9]\+:/{h;d};/^[ \t]*\^/G;
{訳注: 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' を調整することができる。
jikesを使っているなら、jikesの+Eコマンドラインスイッチを使うことをantに教えな
ければならない (このスイッチはjikesに1行エラーメッセージを生成させる)。これが
build.xmlファイルの2行目が行っていることである:
<property name = "build.compiler" value = "jikes"/>
<property name = "build.compiler.emacs" value = "true"/>
<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%.%#
\%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 scriptファイルに書ける。例えばLaTeXに関連し
た内容を含むスクリプトをLaTeXソースの編集時にだけ読みこまれるようにする。
サンプルの全行をコピーしたことを確認する (順番もそのまま)。行の始まりに見るこ
とのできる '\' の表記はline-continuationを参照。
まず 'makeprg' をLaTeXが最初のエラーで止まることなく複数のエ
ラーを返すように準備する。
:set makeprg=latex\ \\\\nonstopmode\ \\\\input\\{$*}
マルチラインエラーメッセージの始まり:
:set efm=%E!\ LaTeX\ %trror:\ %m,
\%E!\ %m,
マルチライン警告メッセージの始まり;最初の2つは行番号も含んで\%E!\ %m,
いる。幾つかの正規表現の意味:
- "%.%#" (".*") 文字列 (空文字列も含む) にマッチ
- "%*\\d" ("\d\+") 数字にマッチ
\%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#,
\%+W%.%#\ at\ lines\ %l--%*\\d,
\%WLaTeX\ %.%#Warning:\ %m,
エラー/警告メッセージが続く可能性;最初の一つは行番号も含んで\%+W%.%#\ at\ lines\ %l--%*\\d,
\%WLaTeX\ %.%#Warning:\ %m,
いる:
\%Cl.%l\ %m,
\%+C\ \ %m.,
\%+C%.%#-%.%#,
\%+C%.%#[]%.%#,
\%+C[]%.%#,
\%+C%.%#%[{}\\]%.%#,
\%+C<%.%#>%.%#,
\%C\ \ %m,
次のパターンにマッチする行には重要な情報は含まれていない;\%+C\ \ %m.,
\%+C%.%#-%.%#,
\%+C%.%#[]%.%#,
\%+C[]%.%#,
\%+C%.%#%[{}\\]%.%#,
\%+C<%.%#>%.%#,
\%C\ \ %m,
よってメッセージに含まないようにする。
\%-GSee\ the\ LaTeX%m,
\%-GType\ \ H\ <return>%m,
\%-G\ ...%.%#,
\%-G%.%#\ (C)\ %.%#,
\%-G(see\ the\ transcript%.%#),
通常、空白文字だけの行は表示しない:\%-GType\ \ H\ <return>%m,
\%-G\ ...%.%#,
\%-G%.%#\ (C)\ %.%#,
\%-G(see\ the\ transcript%.%#),
\%-G%*\\s,
LaTeXの出力ログには個々のライン毎にエラーのあったファイル名が特定(記述)されているわけではない;ログのあらゆる所で与えられ、
括弧にくくられている。
続くパターンはそれらの名前を取り出し内部スタックに保存しようと
試みる。パターンは時として一つの行を複数回走査 (一つ目を
見つけた後、同じ行に次のを発見しようと) するので、パターンの
末尾の "%r" が行の残りの部分が次の試行で解釈の対象になることと、
行の末尾に達するまでそれが繰り返されることを示す。
'('...')' でくくられたファイル名を読み飛ばす;明らかにエラーを
含まないファイルはスタックに積まない:
\%+O(%f)%r,
ファイル名をスタックに積む。名前は '(' の後に与えられる。 \%+P(%f%r,
\%+P\ %\\=(%f%r,
\%+P%*[^()](%f%r,
\%+P[%\\d%[^()]%#(%f%r,
')' が見つかったらファイル名をスタックから取り崩す。\%+P\ %\\=(%f%r,
\%+P%*[^()](%f%r,
\%+P[%\\d%[^()]%#(%f%r,
\%+Q)%r,
\%+Q%*[^()])%r,
\%+Q[%\\d%*[^()])%r
\%+Q%*[^()])%r,
\%+Q[%\\d%*[^()])%r
幾つかのケースにおいてLaTeXの出力したログの中のファイル名を正確に取り出す事が
できないことに注意。括弧の対応が正しくつかない時パーサーは混乱してしまう。上記
のサンプルはもっとも一般的なケースだけ検出できるようにしてある。目的に合わせて
このサンプルを変える事はできる。例えば全てのいまいましい "Overfull ..." という
警告メッセージがエラーとして認識されてしまう事を防ぐ事ができる。
付け加えてLaTeXコンパイラの出力をフィルタリングするには、[La]TeXコンパイラに
よって生成されるファイル*.logを直接読むことも可能である。これは起こる可能性の
あるエラーについてより便利な情報を沢山含んでいる。しかしそのように複雑なファイ
ルを正確に解釈するには、外部フィルタを使うほうが良い。そのようなVimに識別され
るフィルタの作り方はずっと以前に述べたので参照。
errorformat-Perl
$VIMRUNTIME/tools にefm_perl.plスクリプトがある。これはPerlのエラーメッセージ
をフィルタし、quickfixモードが理解できるフォーマットに変換する。使い方はファイ
ルの先頭を参照。(このスクリプトはもう非推奨で、今は compiler-perl を参照のこ
と)
=============================================================================
10. Quickfix ウィンドウのカスタマイズ quickfix-window-function
quickfix ウィンドウおよび location リストウィンドウ内で各行を表示するデフォル
トのフォーマットは:
<filename>|<lnum> col <col>|<text>
各行で表示されるのは getqflist() 関数が返す、"bufnr", "lnum", "col", "text"
の各フィールドに相当する値。
いくつかの quickfix/location リストでは、表示テキストのカスタマイズが必要。例
えば、quickfixのエントリにファイル名のみが存在し、ファイル名の後にあるフィール
ド区切りの2つの "|" が不要な場合。あるいはファイル名をカスタマイズしてパスを表
示する場合。デフォルトでは、ファイルについてカレントディレクトリ以下ではなく、
完全なパス (長すぎるかもしれない) が表示される。ファイルのパスは共通の親ディレ
クトリについてシンプル化の必要があるかもしれない。
表示するテキストは 'quickfixtextfunc' オプションに Vim の関数を設定することで
カスタマイズできる。この関数は辞書を引数として呼ばれ、quickfix か location ウィ
ンドウで表示される文字列のリストを返さなくてはならない。引数の辞書は以下の
フィールドを持っている:
quickfix quickfix リストを呼ぶときは1が設定され、location リストのとき
は0が設定される。
winid location リストの時、そのウィンドウIDが設定される。quickfix
リストの時、0が設定される。getloclist() で location リストの項
目を取得するのに使える。
id quickfix か location リストの識別子
start_idx 返されたテキストの最初の項目のインデックス
end_idx 返されたテキストの最後の項目のインデックス
関数は項目の start_idx から end_idx について quickfix ウィンドウに表示する単一
の行の表示テキストを返さなくてはならない。関数は項目の情報を getqflist() 関
数から quickfix リストを識別する識別子 "id" で取れる。location リストの時は、
'winid' 引数付きで getloclist() 関数を使う。空のリストが返された場合、全エント
リの表示にデフォルトのフォーマットが使われる。返されたリストの項目が空文字列の
場合、そのエントリに一致する項目の表示にデフォルトのフォーマットが使われる。
もし quickfix か location リストで固有のカスタマイズが必要ならば、利用する
setqflist() か setloclist() 関数で 'quickfixtextfunc' 属性をリストに設定
できる。これは 'quickfixtextfunc' を上書きする。
下の例では履歴ファイル (v:oldfiles) を quickfix ウィンドウに表示している。そ
こでは各項目の行番号、カラム番号、関連するエラーのテキストはなく、
'quickfixtextfunc' の関数はファイル名だけを返している。
例:
" quickfix リストを v:oldfiles から作る
call setqflist([], ' ', {'lines' : v:oldfiles, 'efm' : '%f',
\ 'quickfixtextfunc' : 'QfOldFiles'})
func QfOldFiles(info)
" quickfix の項目の対象範囲から情報を取得する
let items = getqflist({'id' : a:info.id, 'items' : 1}).items
let l = []
for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
" ファイル名をシンプルにして利用する
call add(l, fnamemodify(bufname(items[idx].bufnr), ':p:.'))
endfor
return l
endfunc
call setqflist([], ' ', {'lines' : v:oldfiles, 'efm' : '%f',
\ 'quickfixtextfunc' : 'QfOldFiles'})
func QfOldFiles(info)
" quickfix の項目の対象範囲から情報を取得する
let items = getqflist({'id' : a:info.id, 'items' : 1}).items
let l = []
for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
" ファイル名をシンプルにして利用する
call add(l, fnamemodify(bufname(items[idx].bufnr), ':p:.'))
endfor
return l
endfunc
vim:tw=78:ts=8:noet:ft=help:norl: