Next: , Previous: , Up: 目次   [Index]


構文ファイルを作成する

*usr_44.txt*	For Vim バージョン 8.1.  Last change: 2017 May 06

		     VIM USER MANUAL - by Bram Moolenaar

			    構文ファイルを作成する

Vim は 200 種類以上ものファイルを强調表示できます。强調表示されないファイルを見つけた場合は、本章を讀んで、ファイルを强調表示する方法を調べてください。リファレンスマニュアルの |:syn-define| も參照してください。

|44.1|基本的な syntax コマンド
|44.2|キーワード
|44.3|マッチ
|44.4|リージョン
|44.5|構文アイテムを入れ子にする
|44.6|グループの竝び
|44.7|その他の引數
|44.8|クラスタ
|44.9|他の構文ファイルをインクルードする
|44.10|シンクロナイズ
|44.11|構文ファイルをインストールする
|44.12|ポータブルな文法定義ファイル

基本的な syntax コマンド

既存の構文ファイルを土臺にすることで多くの時閒を節約できます。望みのものに近い言語の構文ファイルを $VIMRUNTIME/syntax から探してください。それらのファイルを見れば、構文ファイルの基本的な構造がわかると思ひます。內容を理解するには本章を讀んでください。

基本的なことから說明します。構文定義を開始する前に、古い定義をクリアする必要があります:

:syntax clear

最終的な構文ファイルではこのコマンドは必要ありませんが、いろいろと試したいときには便利です。

本章の說明はかなり簡略化されてゐます。構文ファイルを書いて、それを他人に使つてもらふ場合は、本章を最後まで讀んで詳細を理解してください。

定義された構文アイテムを一覽表示する

現在定義されてゐる構文アイテムを表示するには、次のコマンドを使ひます:

:syntax

實際に定義されてゐる構文アイテムを確認することができます。新しい構文ファイルを作つてゐて、いろいろと試してゐるときに便利です。また、それぞれの構文アイテムは、實際の表示と同じ色で表示されるので、何がどうなつてゐるかも確認できます。

特定の構文グループのアイテムを一覽表示するには次のやうにします:

:syntax list {group-name}

これはクラスタ (|44.8|參照) を一覽表示することもできます。その場合は名前に @ を付けてください。

大文字と小文字の區別

Pascal などの言語は大文字と小文字を區別しません。C などの言語は大文字と小文字を區別します。次のコマンドで區別するかしないかを指定できます:

:syntax case match
:syntax case ignore

"match" を指定すると大文字と小文字は區別されます。その場合、"int" と "Int" と"INT" はそれぞれ違ふものになります。"ignore" を指定した場合は、"Procedure" と "PROCEDURE" と "procedure" は同じ扱ひになります。

":syntax case" コマンドは構文ファイルのどこにでも書くことができ、それ以降の構文定義に作用します。ほとんどの場合、":syntax case" コマンドは構文ファイルに 1 つだけ書きますが、大文字と小文字を區別する要素と區別しない要素を兩方もつやうな特殊な言語の場合には、ファイルのゐたるところで ":syntax case" コマンドを書くこともできます。

キーワード

最も基本的な構文要素はキーワードです。次のやうに定義します:

:syntax keyword {group} {keyword} ...

{group} は構文グループの名前です。":highlight" コマンドを使ふことで {group} に色を割り當てることができます。{keyword} は實際のキーワードです。いくつか例を示します:

:syntax keyword xType int long char
:syntax keyword xStatement if then else endif

"xType" と "xStatement" がグループ名です。習慣的に、グループ名の先頭にはファイルタイプ名が付けられます。この例では x 言語 (さういふ言語があるのではなく單にeXample の x) の構文を定義してゐます。例へば "csh" スクリプト用の構文ファイルなら "cshType" といふ名前になります。つまり、’filetype’ の値と同じものを先頭に付けます。

この例では "int" と "long" と "char" が同じ方法で强調表示され、"if" と "then" と "else" と "endif" が別の同じ方法で强調表示されます。次に、x グループ名と Vim の標準名を關聯付ける必要があります。次のやうにします:

:highlight link xType Type
:highlight link xStatement Statement

"xType" を "Type" で强調表示し、"xStatement" を "Statement" で强調表示します。標準名については |group-name| を參照してください。

特殊なキーワード

キーワードとして使はれる文字は ’iskeyword’ オプションに指定されてゐなければなりません。それ以外の文字を使つた場合、その單語は決してマッチしません。Vim はそのことについて警告メッセージを出しません。

例題の x 言語は ’-’ 文字をキーワードとして使へます。それは次のやうに設定します:

:setlocal iskeyword+=-
:syntax keyword xStatement when-not

":setlocal" コマンドを使つて、カレントバッファだけ ’iskeyword’ を變更してゐます。この設定によつて "w" や "*" などのコマンドの動作も變更されます。動作を變更したくない場合は、キーワードではなくマッチを使つてください (次節で說明します)。

x 言語では短縮形も使へます。例へば、"next" は "n"、"ne"、"nex" に短縮できます。次のコマンドでそれを定義できます:

:syntax keyword xStatement n[ext]

これは "nextone" にはマッチしません。キーワードは常に單語全體にのみマッチします。

マッチ

もう少し複雜なものを定義してみませう。普通の識別子にマッチさせるため、マッチ構文アイテムを定義します。次の例は、すべての文字が小文字の單語にマッチします:

:syntax match xIdentifier /\<\l\+\>/

Note:
キーワードは他の構文アイテムより優先されます。"if" や "then" などのキーワード (上述の ":syntax keyword" コマンドで定義したもの) は、xIdentifier にもマッチしますが、キーワードとして扱はれます。

最後の部分はパターンです。これは檢索で使用するものと同じです。// を使つてパターンを圍みます (":substitute" コマンドと同じ)。+ や " など、他の文字を使ふこともできます。

次はコメント用のマッチを定義してみます。x 言語では "#" から行末までがコメントになります:

:syntax match xComment /#.*/

すべての檢索パターンが使へるので、マッチを使ふことで非常に複雜なものを强調表示できます。檢索パターンについては |pattern| を參照してください。

リージョン

例題の x 言語では、文字列をダブルクォートで圍みます。文字列を强調表示するためにリージョン (領域) を定義します。それにはリージョンの開始 (ダブルクォート) とリージョンの終了 (ダブルクォート) が必要です。定義は次のやうになります:

:syntax region xString start=/"/ end=/"/

"start" と "end" に指定したパターンは、リージョンの開始と終了を探すために使用されます。しかし次のやうな文字列があつたらどうなるでせうか?

"A string with a double quote (\") in it" ~

これはうまくいきません。文字列の途中のダブルクォートによつてリージョンが終了してしまひます。文字列中のエスケープされたダブルクォートをスキップするやうに指定する必要があります。それには "skip" キーワードを使ひます:

:syntax region xString start=/"/ skip=/\\"/ end=/"/

檢索パターンの中ではバックスラッシュが特殊な文字として使はれるので、連續した 2 つのバックスラッシュが 1 つのバックスラッシュにマッチします。

マッチではなくリージョンを使ふのはどんな場面でせうか?主な違ひは、マッチは 1 つのパターンであり、そのパターン全體がマッチするといふことです。リージョンは "start" パターンがマッチするとすぐに開始されます。"end" パターンが見つかるかどうかは關係ありません。つまり、構文アイテムが "end" パターンにマッチすることに依存してゐる場合はリージョンは使へません。それが大丈夫なら、リージョンを定義する方が簡單な場合が多々あります。また、次の節でも述べるやうに、構文アイテムを入れ子にする場合もリージョンが適してゐます。

構文アイテムを入れ子にする

次のやうなコメントがあります:

%Get input  TODO: Skip white space ~

コメントを靑色で强調表示し、その中の TODO を黃色の大きな字で强調表示してみませう。それには、次のやうな構文グループを定義します:

:syntax keyword xTodo TODO contained
:syntax match xComment /%.*/ contains=xTodo

1 行目の "contained" 引數は、そのキーワードが他の構文アイテムの中にのみ出現することを示してゐます。2 行目の "contains=xTodo" は、その構文アイテムの中に xTodo が出現することを示してゐます。結果、コメント全體は "xComment" にマッチして靑色になり、その中の TODO は xTodo にマッチして黃色になります (xTodo に對する强調表示が設定してあるなら)。

入れ子の再歸

x 言語では波カッコでコードブロックを表現します。コードブロックの中にはさらに別のコードブロックを入れることができます。これは次のやうに定義できます:

:syntax region xBlock start=/{/ end=/}/ contains=xBlock

例へば、次のやうなテキストがあつた場合:

while i < b {
    if a {
        b = c;
    }
}

まづ、1 行目の { で 1 つ目の xBlock が開始します。2 行目には別の { があります。そこは xBlock の中で、xBlock は自身を含むことができるので、2 つ目の xBlock が開始します。したがつて、"b = c" の行は第二レベルの xBlock リージョンの中といふことになります。次の行には } があり、これはリージョンの末尾を示すパターンにマッチするので、これによつて 2 つ目の xBlock が閉ぢます。この } は 2 つ目の xBlock リージョンの中の文字なので、1 つ目の xBlock リージョンからは隱されます。そして、最後の } によつて 1 つ目の xBlock リージョンが閉ぢます。

末尾をキープする

次の 2 つの構文アイテムを見てみませう:

:syntax region xComment start=/%/ end=/$/ contained
:syntax region xPreProc start=/#/ end=/$/ contains=xComment

% から行末までをコメントとして定義し、# から行末までをプリプロセッサー指令として定義してゐます。プリプロセッサー行にはコメントを入れることができるので、プリプロセッサーの定義には "contains=xComment" 引數が指定されてゐます。では、次のやうなテキストで何が起こるか見てみませう:

#define X = Y  % Comment text
int foo = 1;

このテキストは、2 行目も xPreProc として强調表示されます。プリプロセッサー指令は行末で終はるものであり、そのために "end=/$/" と指定しました。何が閒違つてゐたのでせうか?

問題は內包されたコメントにあります。コメントは % で始まり、行末で終はります。コメントが終はるとプリプロセッサー構文に戾りますが、それは行末が處理された後なので、次の行も含まれてしまふのです。

この問題を囘避し、內包された構文が改行を消費しないやうにするには、"keepend" 引數を使ひます。これで、行末への二重マッチに對應できます:

:syntax region xComment start=/%/ end=/$/ contained
:syntax region xPreProc start=/#/ end=/$/ contains=xComment keepend

複數アイテムの內包

"contains=" 引數には「すべての構文アイテム」を指定することができます。例:

:syntax region xList start=/\[/ end=/\]/ contains=ALL

xList にはすべての構文アイテムが內包されます。「すべて」は自分自身を含みますが、同じ位置のものは除外されます (無限ループを避けるため)。

一部のグループだけを除外するやうな指定もできます。つまり、指定したグループ以外のグループを內包できます:

:syntax region xList start=/\[/ end=/\]/ contains=ALLBUT,xString

"TOP" を指定すると、"contained" 引數を持たないすべてのアイテムが對象になります。"CONTAINED" を指定すると、"contained" 引數を持つアイテムだけが對象になります。詳しくは |:syn-contains| を參照してください。

グループの竝び

x 言語には次のやうな形式のステートメントがあります:

if (condition) then

この 3 つのアイテムを別々に强調表示します。ただし、"(condition)" と "then" は他の場所にも出現し、そこでは別の方法で强調表示されることもあります。次のやうに定義します:

:syntax match xIf /if/ nextgroup=xIfCondition skipwhite
:syntax match xIfCondition /([^)]*)/ contained nextgroup=xThen skipwhite
:syntax match xThen /then/ contained

"nextgroup" 引數で、次に來るアイテムを指定します。これは (マッチするための) 必須條件にはなりません。指定されたアイテムが見つからなかつた場合は何も起こりません。例へば、次のテキストの場合:

if not (condition) then

"if" は xIf にマッチします。"not" は nextgroup に指定された xIfCondition にマッチしません。したがつて、"if" だけが强調表示されます。

"skipwhite" 引數を指定すると、次のアイテムとの閒に空白 (スペースとタブ) をはさむことができます。同樣に、"skipnl" を指定すれば、次のアイテムとの閒に改行をはさむことができ、"skipempty" を指定すれば、空行をはさむことができます。ただし、"skipnl" は空行をスキップしないので注意してください。改行の後で何かにマッチする必要があります。

その他の引數

MATCHGROUP

リージョンは、リージョン全體が同じグループで强調表示されます。例へば、() で圍まれたテキストを xInside グループで强調表示するため、次のやうに定義します:

:syntax region xInside start=/(/ end=/)/

このときに、カッコだけを別の方法で强調表示することを考へます。複雜な方法を使つて定義することもできますが、"matchgroup" 引數を使ふ方法もあります。"matchgroup" を指定すると、リージョンの start と end の部分を別の强調グループで表示できます (この例では xParen):

:syntax region xInside matchgroup=xParen start=/(/ end=/)/

"matchgroup" 引數は、その引數より後ろに指定された start と end に對して適用されます。上の例では start と end の兩方が xParen で强調表示されます。end を xParenEnd で强調表示する場合は次のやうにします:

:syntax region xInside matchgroup=xParen start=/(/
    \ matchgroup=xParenEnd end=/)/

"matchgroup" を使ふと、內包されたアイテムが start と end の部分にマッチしなくなります。次の "transparent" の例題ではそれを利用してゐます。

TRANSPARENT (透過)

例へば C 言語のファイルで、"while" の後の () と、"for" の後の () を別の方法で强調表示してみます。兩方とも () を入れ子にできて、それが外側の () と同じ方法で强調表示されるやうにします。() の强調表示は ) がマッチしたところでストップします。それには、例へば次のやうにします:

:syntax region cWhile matchgroup=cWhile start=/while\s*(/ end=/)/
    \ contains=cCondNest
:syntax region cFor matchgroup=cFor start=/for\s*(/ end=/)/
    \ contains=cCondNest
:syntax region cCondNest start=/(/ end=/)/ contained transparent

cWhile と cFor には別の强調表示が使はれます。cCondNest は兩方に出現し、自身を內包してゐるアイテムと同じ强調グループで强調表示されます。"transparent" 引數によつてこのやうな動作になります。

この例では、"matchgroup" 引數に自分自身のグループを指定してゐます。その理由は、matchgroup を使ふことで、內包されたアイテムが start の部分にマッチしないといふ副作用が發生するからです。それを利用して cCondNest グループが "while" や "for" の直後の ( にマッチしないやうにしてゐます。もし直後の ( にマッチしてしまふと、cCondNest は ) までのすべてのテキストにマッチしてしまひ、その後ろからリージョンが再開することになつてしまひます。matchgroup を指定することで、cCondNest は start の後、つまり最初の ( より後でマッチするやうになります。

オフセット

"if" の後ろにある ( と ) の閒のテキストをリージョンとして定義します。ただし、"if" と () 自體はリージョンに含めたくありません。そのやうな場合はオフセットを使ひます。例:

:syntax region xCond start=/if\s*(/ms=e+1 end=/)/me=s-1

start パターンには "ms=e+1" といふオフセットが指定されてゐます。"ms" は Match Start といふ意味です。マッチの開始位置のオフセットを設定できます。通常は、パターンがマッチした場所がマッチの開始位置になります。"e+1" はパターンがマッチしたテキストの末尾からさらに 1 つ進んだ場所を示します。

end パターンには "me=s-1" といふオフセットが指定されてゐます。"me" は Match End といふ意味です。"s-1" はパターンにマッチしたテキストの先頭から 1 つ戾つた場所を示します。例へば、次のテキストでは:

if (foo == bar)

"foo == bar" の部分だけが xCond で强調表示されます。

オフセットの詳細については |:syn-pattern-offset| を參照してください。

ONELINE

"oneline" 引數は、リージョンが複數行にまたがらないことを示します。例:

:syntax region xIfThen start=/if/ end=/then/ oneline

これは "if" で始まつて "then" で終はるリージョンを定義してゐます。ただし、"if" と "then" が同じ行にない場合はマッチしません。

Note:
"oneline" を使用した場合、end パターンが同じ行でマッチしない限り、リージョンは開始されません。"oneline" がない場合は、end パターンがマッチする場所があるかどうかはチェックされません。その場合、たとへ end パターンにマッチする場所がなくても、リージョンは開始されます。

行の繼續と繼續の囘避

さて、少し複雜になつてきました。次はプリプロセッサー行を定義してみます。プリプロセッサー行は行頭の # で始まり、行末まで續きます。行末が \ で終つてゐた場合は、次の行まで繼續します。それには、繼續パターンにマッチする構文アイテムを內包するやうに指定します:

:syntax region xPreProc start=/^#/ end=/$/ contains=xLineContinue
:syntax match xLineContinue "\\$" contained

通常は xPreProc は單一行にマッチしますが、內包された xLineContinue によつて次の行まで繼續するやうになります。例へば、次のテキストは 2 行ともマッチします:

#define SPAM  spam spam spam \
                bacon and spam

これは期待した動作ですね。あるいは、內包されたパターンに "excludenl" を指定することによつて、リージョンを單一行に收めることもできます。例へば、xPreProc の中で、行末に "end" があつたときに、それを强調表示したいやうな場合に使ひます。xPreProc が (xLineContinueのときのやうに) 次の行に繼續しないやうにするには、次のやうに "excludenl" を使ひます:

:syntax region xPreProc start=/^#/ end=/$/
        \ contains=xLineContinue,xPreProcEnd
:syntax match xPreProcEnd excludenl /end$/ contained
:syntax match xLineContinue "\\$" contained

"excludenl" はパターン指定の前に置いてください。"xLineContinue" には "excludenl" が指定されてゐないので、最初の例と同樣、マッチすることによつて xPreProc リージョンが擴張されます。

クラスタ

構文ファイルを書いてみると、實にたくさんの構文グループを作成するといふことに氣づくと思ひます。必要なら、クラスタと呼ばれるものを定義して複數の構文グループをひとまとめにすることができます。

例へば、for ループ、if 文、while ループ、函數、などを持つた言語があります。それぞれは數値や識別子など、同じ構文要素を含むことができます。それを次のやうに定義してみます:

:syntax match xFor /^for.*/ contains=xNumber,xIdent
:syntax match xIf /^if.*/ contains=xNumber,xIdent
:syntax match xWhile /^while.*/ contains=xNumber,xIdent

同じ "contains=" を何度も書かなければなりません。內包されるアイテムを追加するときは、その變更を 3 回繰り返すことになります。クラスタを使つて複數の構文グループをひとまとめにすることで、このやうな指定が簡單になります。

上の 3 つのグループが內包してゐる 2 つのアイテムをクラスタとして定義するには、次のコマンドを使ひます:

:syntax cluster xState contains=xNumber,xIdent

クラスタは他の構文アイテムの中で使はれます。使ひ方は普通の構文アイテムと同じです。名前の先頭に  を付けてください。例の 3 つの構文アイテムは次のやうに定義できます:

:syntax match xFor /^for.*/ contains=@xState
:syntax match xIf /^if.*/ contains=@xState
:syntax match xWhile /^while.*/ contains=@xState

クラスタに構文グループを追加するには "add" 引數を使ひます:

:syntax cluster xState add=xString

クラスタから構文グループを取り除くこともできます:

:syntax cluster xState remove=xNumber

他の構文ファイルをインクルードする

C++ 言語の構文は C 言語のスーパーセットです。構文ファイルを 2 つも書くのは避けたいので、次のコマンドを使つて、C++ 構文ファイルの中で C 構文ファイルを讀み込みます:

:runtime! syntax/c.vim

":runtime!" コマンドは ’runtimepath’ の中からすべての "syntax/c.vim" を探します。そして、C ファイルを開いたときと同樣に、C++ における C の部分の構文が定義されます。c.vim 構文ファイルを入れ替へてゐたり、擴張ファイルで構文アイテムを追加してゐたりする場合は、それらも讀み込まれます。

C の構文アイテムをロードしたら、C++ 特有の構文アイテムを定義します。例へば、C にはないキーワードを定義します:

:syntax keyword cppStatement    new delete this friend using

コマンドの動作は普通の構文ファイルのときと同じです。

次に、Perl 言語を考へてみませう。Perl スクリプトは 2 つの異なる部分で構成されます。1 つは POD 形式のドキュメントセクション、もう 1 つは Perl で書かれたプログラムです。POD セクションは "=head" で始まり "=cut" で終はります。

POD 構文の定義を 1 つのファイルに書き、Perl 構文ファイルの中からそれを使ひます。":syntax include" コマンドで構文ファイルを讀み込むと、その中で定義されてゐる要素がクラスタに格納されます。Perl の場合、次のやうなコマンドを使ひます:

:syntax include @Pod <sfile>:p:h/pod.vim
:syntax region perlPOD start=/^=head/ end=/^=cut/ contains=@Pod

Perl ファイルの中で "=head" が見つかると perlPOD リージョンが開始します。perlPOD リージョンは @Pod クラスタを內包してゐます。リージョンの中では、pod.vim 構文ファイルで定義されたトップレベルの構文アイテムがマッチします。"=cut" が見つかるとリージョンは終了し、Perl ファイルの構文アイテムに戾ります。

":syntax include" コマンドで讀み込まれたファイル內の ":syntax clear" コマンドは適切に無視されます。さらに、"contains=ALL" のやうな引數は同じファイルの構文アイテムだけが對象になります。呼び出し元の構文アイテムは對象になりません。

"<sfile>:p:h/" の部分は、カレントファイル名 (<sfile>) をフルパス (:p) に展開し、その head (尖端) (:h) を取り出してゐます。展開結果はファイルのディレクトリ名になります。つまり、同じディレクトリの pod.vim がインクルードされます。

シンクロナイズ (構文解析の同期)

例へばコンパイラなら話は簡單です。ファイルの先頭から開始して、順番に構文解析していくだけです。しかし Vim では、ユーザーが編輯してゐる場所、つまりファイルの途中から構文解析が開始されます。どのやうにして適切な開始位置を決めてゐるのでせうか。

祕密は ":syntax sync" コマンドにあります。このコマンドを使つて、構文解析の開始位置を指定します。例へば、次のコマンドを使ふと、C スタイルコメントの開始位置、あるいは終了位置が後方檢索され、その場所から構文ハイライトが開始されます:

:syntax sync ccomment

引數を指定して動作を調整できます。"minlines" 引數には、後方檢索で戾る最小の行數を指定します。"maxlines" 引數には、檢索される行數の上限を指定します。

例へば、畫面の一番上に表示されてゐる行から、最低でも 10 行前まで調べるやうにするには、次のやうにします:

:syntax sync ccomment minlines=10 maxlines=500

最小の範圍內で見つからなかつた場合は、適切な場所が見つかるまで、さらに戾つて調べます。ただし、500 行以上は戾りません。 ("maxlines" を大きくすると處理速度が遲くなります。小さ過ぎるとシンクロナイズに失敗してしまひます。)

シンクロナイズは、スキップ可能な構文アイテムを指定することで、少し高速になります。テキストを實際に表示するときだけ必要な構文アイテムを定義するときに"display" 引數を指定してください。

デフォルトでは、檢索されたコメントは Comment 構文グループで强調表示されます。他の方法で强調表示したい場合は、使用したい構文グループを指定してください:

:syntax sync ccomment xAltComment

プログラミング言語が C スタイルコメントを持つてゐない場合は、他の方法でシンクロナイズします。最も簡單なのは、戾る行數を指定して、その場所から構文解析を試す方法です。例へば、150 行前に戾つて、そこから構文解析を開始するには、次のやうにします:

:syntax sync minlines=150

"minlines" に大きな値を指定すると Vim の動作が遲くなります (特に上方にスクロールする場合など)。

檢索對象になる構文グループを指定することもできます:

:syntax sync match {sync-group-name}
        \ grouphere {group-name} {pattern}

{group-name} といふ構文グループが {pattern} にマッチした場所のすぐ後から開始するといふことを定義します。{sync-group-name} はシンクロナイズ定義の名前です。例へば、sh スクリプトでは if 文を "if" で開始し、"fi" で閉ぢます:

if [ --f file.txt ] ; then
    echo "File exists"
fi

この構文に對して "grouphere" を定義すると、次のやうになります:

:syntax sync match shIfSync grouphere shIf "\<if\>"

"groupthere" 引數を使つてグループの終端を示すパターンを指定します。例へば、if/fi グループの終端は次のやうに定義できます:

:syntax sync match shIfSync groupthere NONE "\<fi\>"

この例では、NONE を指定して、パターンにマッチした場所が特定のリージョンの中ではないこと、つまりは if ブロックの中ではないことを指定してゐます。

"grouphere" 引數と "groupthere" 引數を指定しないで、マッチやリージョンを定義することもできます。そのやうなグループはシンクロナイズのときにスキップされます。例へば、次のやうに定義すると、{} で圍まれた範圍がスキップされます (他のシンクロナイズメソッドにマッチする場合でも):

:syntax sync match xSpecial /{.*}/

シンクロナイズの詳細はリファレンスマニュアルの |:syn-sync| を參照してください。

構文ファイルをインストールする

新しい構文ファイルを使用する準備ができたら、それを ’runtimepath’ の "syntax" ディレクトリにコピーしてください。Unix なら "~/.vim/syntax" です。

構文ファイルの名前はファイルタイプ名に ".vim" を付けた名前にします。したがつて、x 言語ならファイルのフルパスは次のやうになります:

~/.vim/syntax/x.vim

さらに、ファイルタイプが認識されるやうに設定する必要があります。|43.2| 參照。

構文ファイルがうまく動作したら、それを他の Vim ユーザーが利用できるやうにしてあげるといいでせう。まづ次のセクションを讀んで、構文ファイルが他の環境でも動作するやうにしてください。そして、Vim のメンテナー <maintainer@vim.org> にメールを送つてください。ファイルタイプの認識方法の說明もお願ひします。よほどのことがない限り、Vim のバージョンアップに合はせて取り込まれます。

既存の構文ファイルを擴張する

上記は、完全に新しい構文ファイルを作成する場合の說明です。既存の構文ファイルを使つてゐて、それに足りない構文アイテムがあるやうな場合には、それとは別のファイルを使つて構文アイテムを追加することができます。ファイルを別にすることで、Vim をバージョンアップしたときに變更が失はれてしまふのを防止します。

syntax コマンドを自分のファイルに書きます。できる限り既存の構文グループの名前を使つてください。例へば、C 構文ファイルに新しい變數タイプを追加するには、次のやうに書きます:

:syntax keyword cType off_t uint

これを、元の構文ファイルと同じ名前で保存します。この場合なら "c.vim" です。そのファイルを ’runtimepath’ の最後の方にあるディレクトリに置きます。さうすることで、元の構文ファイルよりも後に讀み込ませます。Unix なら次の場所に保存します:

~/.vim/after/syntax/c.vim

ポータブルな構文ファイル

すべての Vim ユーザーが構文ファイルを共有できれば素晴らしいと思ひませんか?そのためには、構文ファイルはいくつかのガイドラインに從つてゐる必要があります。

ファイルの先頭にヘッダーを書いてください。構文ファイルの用途、メンテナー、最終更新日を書きます。詳細な變更履歷は必要ありません(ほとんどの人はそれを讀みません)。例:

" Vim syntax file
" Language:     C
" Maintainer:   Bram Moolenaar <Bram@vim.org>
" Last Change:  2001 Jun 18
" Remark:       Included by the C++ syntax.

他の構文ファイルと同じレイアウトを使つてください。既存の構文ファイルを參考にすると時閒を節約できます。

構文ファイルには分かりやすい名前を付けます。小文字と數字だけを使つてください。名前は多くの場所で使ふので長くなり過ぎないやうにします (構文ファイルの名前 ("name.vim")、’filetype’、b:current_syntax、構文グループの接頭辭 (nameType、nameStatement、nameString、etc) などで使ひます)。

最初に "b:current_syntax" をチェックします。これが定義濟みなら、他の構文ファイルが ’runtimepath’ の前の方でロードされたといふことです:

if exists("b:current_syntax")
  finish
endif

Vim 5.8 との互換性が必要なら次のやうにします:

if version < 600
  syntax clear
elseif exists("b:current_syntax")
  finish
endif

ファイルの最後で "b:current_syntax" に構文の名前を設定します。ファイルをインクルードしてゐる場合、そのファイルの中でも "b:current_syntax" が設定されるので注意してください。複數のファイルをインクルードする場合には、"b:current_syntax" をリセットする必要があるかもしれません。

構文ファイルが Vim 5.x でも動作するやうにするには、v:version をチェックする必要があります。實例は Vim 7.2 のシンタックスファイルを探してください。

ユーザー設定を變更しないでください。’tabstop’ や ’expandtab’ などの設定を變更してはいけません。そのやうな設定はファイルタイププラグインの仕事です。

マップや短縮入力を定義しないでください。’iskeyword’ だけは、キーワードの識別にどうしても必要なら、設定しても構ひません。

ユーザーが好みの色を選擇できるやうに、强調表示されるグループの名前に標準とは違ふ名前を付けます。そして、それらを標準の强調グループにリンクします。さうすればどのカラースキームでも適切に强調表示できます。標準以外の强調グループを使つてしまふと、カラースキームによつては正しく强調表示されません。また、ユーザーの環境によつて背景色が違つたり、色數が 8 色しかない場合もあるので覺えておいてください。

强調グループをリンクするには "hi def link" を使ひます。さうすることで、ユーザーはあなたの構文ファイルがロードされる前の段階で他の强調グループを選擇できます。例:

hi def link nameString        String
hi def link nameNumber        Number
hi def link nameCommand       Statement
... etc ...

シンクロナイズで使用しない構文アイテムには "display" 引數を付けてください。上方向へのスクロールや CTRL-L の動作が早くなります。


Next: , Previous: , Up: 目次   [Index]