Usr_44

Nvim の :help ページ。 生成された 元データは こちら で、tree-sitter-vimdoc パーサーを使用しています。


VIM ユーザーマニュアル - Bram Moolenaar 著
独自の構文ハイライト
Vim は、数百種類の異なるファイルタイプに対するハイライト機能を備えています。編集中のファイルが含まれていない場合は、この章を読んで、その種類のファイルのハイライト方法を確認してください。また、リファレンスマニュアルの :syn-define も参照してください。
44.1 基本的な構文コマンド 44.2 キーワード 44.3 マッチ 44.4 リージョン 44.5 ネストされたアイテム 44.6 後続グループ 44.7 その他の引数 44.8 クラスタ 44.9 他の構文ファイルのインクルード 44.10 同期化 44.11 構文ファイルのインストール 44.12 ポータブルな構文ファイルレイアウト
次の章: usr_45.txt 言語の選択 前の章: usr_43.txt ファイルタイプの使用 目次: usr_toc.txt

基本的な構文コマンド

既存の構文ファイルから始めることで、多くの時間を節約できます。類似した言語の構文ファイルを $VIMRUNTIME/syntax で探してみてください。これらのファイルは、構文ファイルの標準的なレイアウトも示しています。理解するには、以下を読んでください。
基本的な引数から始めましょう。新しい構文を定義する前に、古い定義をすべてクリアする必要があります。
:syntax clear
これは最終的な構文ファイルでは必要ありませんが、実験する際には非常に便利です。
この章では、さらに簡略化されています。他のユーザーが使用する構文ファイルを作成する場合は、最後まで読んで詳細を確認してください。

定義済みのアイテムの一覧表示

現在定義されている構文アイテムを確認するには、次のコマンドを使用します。
:syntax
これを使用して、実際に定義されているアイテムを確認できます。新しい構文ファイルを試行錯誤する際に非常に役立ちます。各アイテムに使用される色も表示されるため、何が何であるかを調べやすくなります。特定の構文グループのアイテムを一覧表示するには、次を使用します。
:syntax list {group-name}
これは、クラスタ(44.8 で説明)を一覧表示するためにも使用できます。名前の前に @ を含めるだけです。

大文字と小文字のマッチ

Pascalなど、大文字と小文字を区別しない言語もあります。Cなど、大文字と小文字を区別する言語もあります。次のコマンドを使用して、どちらの種類であるかを指定する必要があります。
:syntax case match
:syntax case ignore
"match" 引数は、Vim が構文要素の大文字と小文字を区別して一致させることを意味します。そのため、「int」は「Int」や「INT」とは異なります。「ignore」引数が使用されている場合、次のものは同等です。「Procedure」、「PROCEDURE」、および「procedure」。`:syntax case` コマンドは構文ファイル内のどこにでも配置でき、それに続く構文定義に影響を与えます。ほとんどの場合、構文ファイルには `:syntax case` コマンドが1つだけです。ただし、大文字と小文字を区別する要素と区別しない要素の両方を含む特殊な言語を扱う場合は、ファイル全体に `:syntax case` コマンドを散らすことができます。

44.2 キーワード

最も基本的な構文要素はキーワードです。キーワードを定義するには、次の形式を使用します。
:syntax keyword {group} {keyword} ...
{group} は構文グループの名前です。`:highlight` コマンドを使用して、{group} に色を割り当てることができます。{keyword} 引数は実際のキーワードです。いくつかの例を以下に示します。
:syntax keyword xType int long char
:syntax keyword xStatement if then else endif
この例では、グループ名「xType」と「xStatement」を使用しています。慣例により、各グループ名は、定義されている言語のファイルタイプをプレフィックスとして付けます。この例は、x言語(面白みのない名前の例示言語)の構文を定義しています。「csh」スクリプトの構文ファイルでは、「cshType」という名前が使用されます。したがって、プレフィックスは 'filetype' の値と同じになります。これらのコマンドにより、「int」、「long」、「char」という単語は1つの方法でハイライトされ、「if」、「then」、「else」、「endif」という単語は別の方法でハイライトされます。これで、xグループ名を標準的なVim名に接続する必要があります。次のコマンドでこれを行います。
:highlight link xType Type
:highlight link xStatement Statement
これにより、Vim は「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」とは一致しません。キーワードは常に単語全体にのみ一致します。

44.3 マッチ

もう少し複雑なものを定義することを検討してください。通常の識別子を一致させたいとします。これを行うには、マッチ構文アイテムを定義します。これは、小文字のみで構成される単語に一致します。
:syntax match xIdentifier /\<\l\+\>/
注記: キーワードは、他の構文アイテムよりも優先されます。したがって、「if」、「then」などは、上記の`:syntax keyword`コマンドで定義されているとおり、キーワードになります。これは、xIdentifierのパターンにも一致するにもかかわらずです。
最後にある部分はパターンであり、検索で使用されるものと似ています。// はパターンを囲むために使用されます(`:substitute` コマンドで行われているように)。プラス記号や引用符など、他の文字を使用することもできます。
コメントのマッチを定義してみましょう。x言語では、# から行末までのすべてです。
:syntax match xComment /#.*/
検索パターンを使用できるため、マッチアイテムを使用して非常に複雑なものをハイライトできます。検索パターンについては、pattern を参照してください。

44.4 リージョン

例として挙げたx言語では、文字列は二重引用符(")で囲まれています。文字列をハイライトするには、リージョンを定義します。リージョンの開始(二重引用符)とリージョンの終了(二重引用符)が必要です。定義は次のとおりです。
:syntax region xString start=/"/ end=/"/
"start"と"end"ディレクティブは、リージョンの開始と終了を見つけるために使用されるパターンを定義します。しかし、次のような文字列はどうでしょうか?
"二重引用符(\")を含む文字列"
これは問題を引き起こします。文字列の中央にある二重引用符によってリージョンが終了してしまいます。文字列内のエスケープされた二重引用符をスキップするようにVimに指示する必要があります。これには、skipキーワードを使用します。
:syntax region xString start=/"/ skip=/\\"/ end=/"/
二重バックスラッシュは、バックスラッシュが検索パターンでは特殊文字であるため、単一のバックスラッシュに一致します。
いつリージョンをマッチの代わりに使用するべきですか?主な違いは、マッチアイテムは単一のパターンであり、全体として一致する必要があることです。リージョンは、「start」パターンが一致するとすぐに開始されます。「end」パターンが見つかるかどうかは関係ありません。したがって、アイテムが「end」パターンの一致に依存する場合、リージョンを使用することはできません。それ以外の場合は、リージョンの定義の方が簡単なことがよくあります。また、次のセクションで説明するネストされたアイテムを使用することも簡単です。

44.5 ネストされたアイテム

次のコメントを見てください。
%入力取得 TODO: 空白をスキップ
青色でハイライトされたコメント内にあるにもかかわらず、TODOを大きな黄色い文字でハイライトしたいとします。Vimにこれを知らせるには、次の構文グループを定義します。
:syntax keyword xTodo TODO contained
:syntax match xComment /%.*/ contains=xTodo
最初の行で、「contained」引数は、このキーワードは他の構文アイテム内でのみ存在できることをVimに伝えます。次の行には「contains=xTodo」があります。これは、xTodo構文要素がその中に含まれていることを示しています。その結果、コメント行全体が「xComment」と一致し、青色になります。その中の単語TODOはxTodoと一致し、黄色でハイライトされます(xTodoのハイライトはこれのために設定されています)。

再帰的なネスト

x言語は、中括弧でコードブロックを定義します。コードブロックには、他のコードブロックを含めることができます。これはこのように定義できます。
:syntax region xBlock start=/{/ end=/}/ contains=xBlock
次のテキストがあるとします。
while i < b {
if a {
b = c;
}
}
まず、xBlockが最初の行の中括弧で開始します。2行目では、もう1つの中括弧が見つかります。xBlockアイテムの内側にあり、自身を含んでいるため、ここでネストされたxBlockアイテムが開始します。したがって、「b = c」行は2番目のレベルのxBlockリージョンの内側にあります。次に、次の行で中括弧が見つかり、リージョンの終了パターンと一致します。これにより、ネストされたxBlockが終了します。中括弧はネストされたリージョンに含まれているため、最初のxBlockリージョンからは非表示になります。最後の閉じ中括弧で、最初のxBlockリージョンが終了します。

終了を維持する

次の2つの構文アイテムを考えてみましょう。
:syntax region xComment start=/%/ end=/$/ contained
:syntax region xPreProc start=/#/ end=/$/ contains=xComment
コメントを%から行末までのものとして定義します。プリプロセッサディレクティブを#から行末までのものとして定義します。プリプロセッサ行にコメントを含めることができるため、プリプロセッサ定義には「contains=xComment」引数が含まれています。これで、次のテキストで何が起こるかを見てみましょう。
#define X = Y % コメントテキスト
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
すべての構文アイテムがこの1つに含まれます。それ自体も含まれていますが、同じ位置ではありません(無限ループを引き起こす可能性があります)。一部のグループを含めないように指定できます。したがって、リストされているものを除くすべてのグループを含みます。
:syntax region xList start=/\[/ end=/\]/ contains=ALLBUT,xString
"TOP"アイテムを使用すると、「contained」引数を持たないすべてのアイテムを含めることができます。"CONTAINED"は、「contained」引数を持つアイテムのみを含めるために使用されます。:syn-containsで詳細を参照してください。

44.6 以下のグループ

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」引数は、次にどの項目が来ることができるかを指定します。これは必須ではありません。指定された項目が1つも見つからない場合、何も起こりません。例えば、このテキストでは
if not (condition) then
「if」はxIfによってマッチします。「not」は指定されたnextgroup xIfConditionにマッチしないため、「if」のみが強調表示されます。
「skipwhite」引数は、項目間に空白文字(スペースとタブ)が存在する可能性があることをVimに伝えます。同様の引数として、「skipnl」があり、これは項目間に改行を許可し、「skipempty」は空行を許可します。「skipnl」は空行をスキップしないことに注意してください。改行の後には何かがマッチする必要があります。

44.7 その他の引数

MATCHGROUP

領域を定義する場合、指定されたグループ名に従って領域全体が強調表示されます。例えば、括弧()で囲まれたテキストをxInsideグループで強調表示するには、次のコマンドを使用します。
:syntax region xInside start=/(/ end=/)/
括弧を異なる方法で強調表示したいとします。これは多くの複雑な領域記述子を使って行うこともできますが、「matchgroup」引数を使用することもできます。これはVimに、領域の先頭と末尾を異なる強調表示グループ(この場合はxParenグループ)で強調表示するように指示します。
:syntax region xInside matchgroup=xParen start=/(/ end=/)/
「matchgroup」引数は、その後に続く先頭または末尾のマッチに適用されます。前の例では、先頭と末尾の両方がxParenで強調表示されています。末尾をxParenEndで強調表示するには
:syntax region xInside matchgroup=xParen start=/(/
        \ matchgroup=xParenEnd end=/)/
「matchgroup」を使用する副作用として、含まれる項目は領域の先頭または末尾ではマッチしません。「transparent」の例ではこれが使用されています。

TRANSPARENT

C言語ファイルでは、「while」の後の()内のテキストと「for」の後の()内のテキストを異なる方法で強調表示したいとします。これら両方の内部にはネストされた()項目が存在する可能性があり、それらは同じ方法で強調表示する必要があります。()の強調表示が対応する)で停止するようにする必要があります。これを行う方法の1つは次のとおりです。
: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」引数が項目自体と同じグループであることに注意してください。では、なぜこれを定義するのでしょうか?それは、マッチグループを使用する副作用として、含まれる項目が先頭項目とのマッチでは見つからないためです。これにより、cCondNestグループが「while」または「for」の直後の(にマッチすることがなくなります。これが発生すると、対応する)まで全体のテキストにまたがり、領域はその後に続きます。これで、cCondNestは先頭パターンとのマッチの後、つまり最初の(の後にのみマッチします。

OFFSETS

「if」の後の(と)の間のテキストの領域を定義したいとします。しかし、「if」または(と)を含めたくありません。パターンにオフセットを指定することで、これを行うことができます。例
:syntax region xCond start=/if\s*(/ms=e+1 end=/)/me=s-1
先頭パターンのオフセットは「ms=e+1」です。「ms」はマッチ開始を表します。これはマッチ開始位置のオフセットを定義します。通常、マッチはパターンがマッチした場所で開始されます。「e+1」は、マッチがパターンマッチの末尾から1文字先に開始されることを意味します。末尾パターンのオフセットは「me=s-1」です。「me」はマッチ終了を表します。「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」がない場合、領域はマッチしません。
注記:「oneline」を使用する場合、同じ行に末尾パターンがマッチしない限り、領域は開始しません。「oneline」を使用しない場合、Vimは末尾パターンのマッチがあるかどうかをチェックしません。ファイルの残りの部分に末尾パターンがマッチしなくても、領域は開始されます。

継続行とそれらの回避

状況は少し複雑になります。プリプロセッサ行を定義してみましょう。これは、最初の列に#で始まり、行末まで続きます。\で終わる行は、次の行を継続行にします。これを処理する方法は、構文項目に継続パターンを含めることです。
:syntax region xPreProc start=/^#/ end=/$/ contains=xLineContinue
:syntax match xLineContinue "\\$" contained
この場合、xPreProcは通常1行にマッチしますが、それに含まれるグループ(つまりxLineContinue)により、複数行にわたることができます。例えば、次の2行の両方にマッチします。
#define SPAM spam spam spam \
bacon and spam
この場合は、これが望ましい動作です。これが望ましい動作でない場合、「excludenl」を包含パターンに追加することで、領域を1行にするように要求できます。例えば、「end」をxPreProcで強調表示したいが、行末でのみ強調表示したいとします。xLineContinueのようにxPreProcが次の行に継続することを避けるには、「excludenl」を次のように使用します。
:syntax region xPreProc start=/^#/ end=/$/
        \ contains=xLineContinue,xPreProcEnd
:syntax match xPreProcEnd excludenl /end$/ contained
:syntax match xLineContinue "\\$" contained
「excludenl」はパターンの前に配置する必要があります。「xLineContinue」には「excludenl」がないため、それとのマッチは以前のようにxPreProcを次の行に拡張します。

44.8 クラスタ

構文ファイルを書き始めると、多くの構文グループが生成されることに気付くでしょう。Vimでは、クラスタと呼ばれる構文グループのコレクションを定義できます。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回追加する必要があります。構文クラスタは、1つのクラスタが複数の構文グループを表すことができるようにすることで、これらの定義を簡素化します。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

44.9 別の構文ファイルを含める

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スクリプトは、POD形式のドキュメントセクションと、Perl自体で記述されたプログラムという2つの異なる部分で構成されています。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領域が開始されます。この領域には@Podクラスタが含まれています。pod.vim構文ファイルで最上位項目として定義されているすべての項目がここでマッチします。「=cut」が見つかった場合、領域は終了し、Perlファイルで定義されている項目に戻ります。「:syntax include」コマンドは、包含ファイル内の「:syntax clear」コマンドを無視するほど賢いです。「contains=ALL」などの引数は、それを含むファイルではなく、包含ファイルで定義された項目のみを含みます。「<sfile>:p:h/」の部分は、現在のファイル名(<sfile>)を使用し、完全パスに展開し(:p)、次に先頭(:h)を取ります。これにより、ファイルのディレクトリ名が生成されます。これにより、同じディレクトリ内のpod.vimファイルが含まれます。

44.10 同期

コンパイラは簡単です。ファイルの先頭から開始し、それを直接解析します。Vimはそれほど簡単ではありません。編集が行われている場所の中間から開始する必要があります。では、Vimはどこにいるかをどのように判断するのでしょうか?秘密は「:syntax sync」コマンドです。これは、Vimが現在位置をどのように把握するかを指示します。例えば、次のコマンドは、VimにCスタイルのコメントの先頭または末尾を逆方向にスキャンし、そこから構文カラーリングを開始するように指示します。
:syntax sync ccomment
いくつかの引数を使用して、この処理を調整できます。「minlines」引数は、Vimに後方検索する最小行数を指示し、「maxlines」引数は、エディタにスキャンする最大行数を指示します。例えば、次のコマンドは、Vimに画面の上端から少なくとも10行前を調べるように指示します。
:syntax sync ccomment minlines=10 maxlines=500
その範囲内で現在位置を判断できない場合、処理を行うまでさらに遠くまで後方検索を開始します。しかし、500行より遠くまで後方検索することはありません。(「maxlines」が大きいと処理速度が低下します。「maxlines」が小さいと同期に失敗する可能性があります。)同期の速度を上げるには、スキップできる構文項目をVimに指示します。テキストの表示にのみ必要なすべてのマッチと領域には、「display」引数を指定できます。デフォルトでは、検索されるコメントはComment構文グループの一部としてカラー化されます。別の方法でカラー化したい場合は、別の構文グループを指定できます。
:syntax sync ccomment xAltComment
使用しているプログラミング言語にCスタイルのコメントがない場合、別の同期方法を試すことができます。最も簡単な方法は、Vimに数行上に移動させ、そこから状況を把握するように指示することです。次のコマンドは、Vimに150行上に移動し、そこから解析を開始するように指示します。
:syntax sync minlines=150
"minlines"の値を大きくすると、特にファイル内で後方にスクロールする際に、Vimの速度が低下する可能性があります。最後に、このコマンドを使用して、検索する構文グループを指定できます。
:syntax sync match {sync-group-name}
        \ grouphere {group-name} {pattern}
これは、Vimが`{pattern}`を見つけると、指定されたパターンの直後に`{group-name}`という名前の構文グループが始まることを指示します。`{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"引数は、パターンがグループを終了することをVimに伝えます。たとえば、if/fiグループの終わりは次のようになります。
:syntax sync match shIfSync groupthere NONE "\<fi\>"
この例では、NONEは、特別な構文領域にないことをVimに伝えます。具体的には、ifブロック内にはありません。
"grouphere"または"groupthere"引数のない一致と領域も定義できます。これらのグループは、同期中にスキップされる構文グループ用です。たとえば、次の例では、たとえ他の同期方法に通常一致するものであっても、{}内のものはすべてスキップされます。
:syntax sync match xSpecial /{.*}/
同期の詳細については、リファレンスマニュアルを参照してください::syn-sync

44.11 構文ファイルのインストール

新しい構文ファイルを使用できるようになったら、'runtimepath'の「syntax」ディレクトリに配置します。Unixの場合、`~/.config/nvim/syntax`になります。構文ファイルの名前はファイルの種類と同じで、".vim"が追加されている必要があります。したがって、x言語の場合、ファイルのフルパスは次のようになります。
~/.config/nvim/syntax/x.vim
ファイルの種類も認識されるようにする必要があります。43.2を参照してください。
ファイルが正常に機能する場合は、他のVimユーザーが利用できるようにすることができます。まず、次のセクションを読んで、ファイルが他のユーザーにも正常に機能することを確認してください。次に、Vimのメインテナーにメールを送信してください:<[email protected]>。ファイルタイプの検出方法についても説明してください。少し運が良ければ、ファイルは次のVimバージョンに含まれるでしょう!

既存の構文ファイルへの追加

完全に新しい構文ファイルを追加すると仮定していました。既存の構文ファイルが機能するが、いくつかの項目が不足している場合、別のファイルに項目を追加できます。これにより、Vimの新しいバージョンをインストールしたときに失われる、配布された構文ファイルの変更が回避されます。既存の構文からのグループ名を使用するなどして、ファイルに構文コマンドを記述します。たとえば、C構文ファイルに新しい変数タイプを追加するには
:syntax keyword cType off_t uint
元の構文ファイルと同じ名前のファイルを作成します。この場合は"c.vim"です。'runtimepath'の最後付近のディレクトリに配置します。これにより、元の構文ファイルの後に読み込まれます。Unixの場合、これは次のようになります。
~/.config/nvim/after/syntax/c.vim

44.12 ポータブルな構文ファイルのレイアウト

すべてのVimユーザーが構文ファイルを交換できたら素晴らしいと思いませんか?これを実現するには、構文ファイルがいくつかのガイドラインに従う必要があります。
構文ファイルの目的、メンテナンス担当者、および最終更新日時を説明するヘッダーから始めます。変更履歴に関する情報をあまり多く含めないでください。多くの人が読むわけではないからです。例
" Vim syntax file
" Language:        C
" Maintainer:        Bram Moolenaar <[email protected]>
" Last Change:        2001 Jun 18
" Remark:        Included by the C++ syntax.
他の構文ファイルと同じレイアウトを使用します。既存の構文ファイルを例として使用すると、多くの時間を節約できます。
構文ファイルに適切で説明的な名前を選択します。小文字と数字を使用します。長すぎないようにしてください。多くの場所で使用されます。構文ファイル名「name.vim」、'filetype'、b:current_syntax、および各構文グループの先頭(nameType、nameStatement、nameStringなど)。
"b:current_syntax"のチェックから始めます。これが定義されている場合、'runtimepath'のより前の別の構文ファイルが既にロードされています。
if exists("b:current_syntax")
  finish
endif
最後に、"b:current_syntax"を構文の名前に設定します。インクルードされたファイルもこれを行うことを忘れないでください。2つのファイルをインクルードする場合は、"b:current_syntax"をリセットする必要があるかもしれません。
ユーザー設定を含めないでください。'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`の速度を上げます。
次の章:usr_45.txt 言語の選択
著作権:manual-copyrightを参照してください vim:tw=78:ts=8:noet:ft=help:norl
メイン
コマンド索引
クイックリファレンス