単純な構文ベースのフォントロックや正規表現ベースのフォントロックに加え、Emacsではパーサーを用いた完全な構文ベースのフォントロックも提供しています。現在、Emacsではこの目的でtree-sitterライブラリ(プログラムソースの解析を参照)を使用しています。
パーサーベースのフォントロックと他のフォントロック機構は、相互に排他的なものではありません。デフォルトでは、有効になっている場合、まずパーサーベースのフォントロックが実行されて構文ベースのフォントロックを置き換え、続いて正規表現ベースのフォントロックが実行されます。
パーサーベースのフォントロックは、正規表現ベースのフォントロックと同じカスタマイズ変数を共有しているわけではありませんが、同様のカスタマイズ方式を採用しています。font-lock-keywordsに対応するTree-sitterの表記はtreesit-font-lock-settingsです。
一般的に、Tree-sitterのフォント化は次のように動作します。
font-lock-keyword というタグが付いたノードは、font-lock-keyword フォントでハイライトされます。
クエリ、パターン、キャプチャ名の詳細については、パターンマッチング Tree-sitter ノードを参照してください。
Tree-sitterのフォント化を設定するには、まずメジャーモードがtreesit-font-lock-rulesの出力を用いてtreesit-font-lock-settingsを設定し、次にtreesit-major-mode-setupを呼び出す必要があります。
この関数は treesit-font-lock-settings
を設定するために使用されます。クエリのコンパイルやその他の後処理を行い、treesit-font-lock-settings が受け付ける値を出力します。以下に例を示します。
(treesit-font-lock-rules :language 'javascript :feature 'constant :override t '((true) @font-lock-constant-face (false) @font-lock-constant-face) :language 'html :feature 'script "(script_element) @font-lock-builtin-face")
この関数は一連の query-spec を受け取ります。ここで各 query-spec は、1つ以上の keyword/value ペアに先行する query です。各 query は、文字列、s-expression、またはコンパイル済み形式のいずれかにおける Tree-sitter クエリです。
各queryに対して、その前にあるkeyword/valueのペアがメタ情報を付与します。:languageキーワードはqueryの言語を指定します。:featureキーワードはqueryの機能名を設定します。ユーザーはtreesit-font-lock-levelおよびtreesit-font-lock-feature-list(後述)を用いて、どの機能を有効にするかを制御できます。これら2つのキーワードは必須です(例外あり)。
その他のキーワードは任意です:
| キーワード | 値 | 説明 |
|---|---|---|
:override | nil | 領域に既に面がある場合は、新しい面を破棄する |
t | 常に新しい顔を適用してください | |
append | 新しい面を既存の面に追加する | |
prepend | 新しい顔を既存の顔の先頭に追加する | |
keep | 既存の面がない領域を塗りつぶす | |
:reversed | t | feature が機能リストに含まれていない場合は、query を有効にする。 |
:default-language | language | このキーワード以降のすべての query は、デフォルトで language が使用されます。 |
Lispプログラムはquery内のパターンにキャプチャ名(@で始まる名前)を付与し、tree-sitterはそれらと同じキャプチャ名がタグ付けされた一致ノードを返します。フォント化にあたっては、query内のキャプチャ名はfont-lock-keyword-faceのようなフェイス名である必要があります。キャプチャされたノードは、そのフェイスでフォント化されます。
キャプチャ名には関数名を指定することもでき、その場合、関数は node と override、start と end という4つの引数で呼び出されます。ここで、node
はノード自体、override はこのノードをキャプチャしたルールの :override プロパティ、そして start と end はこの関数が書式設定を行うべき領域を制限します。(この関数が override 引数を考慮したい場合は、treesit-fontify-with-override を使用できます。)
提示された4つの引数に加え、将来的な拡張性を考慮し、本関数はより多くの引数をオプション引数として受け付けられるようにすべきです。
キャプチャ名がフェイスかつ関数である場合は、フェイスが優先されます。キャプチャ名がフェイスでも関数でもない場合は、無視されます。
同じ文法の異なるバージョンに対応するため、条件付きでオプションの query
を含めたり、クエリの一覧から最初に見つかった有効なクエリを選択したりすることが有用な場合があります。treesit-query-with-optional や treesit-query-with-fallback といった関数が役立ちます。
これはフィーチャーシンボルのリストのリストです。リストの各要素は、装飾レベルを表すリストです。ユーザーオプション treesit-font-lock-level で、どのレベルを有効にするかを制御します。
リストの各要素は (feature …) 形式のリストであり、各 feature は treesit-font-lock-rules で定義されたクエリの :feature 値に対応しています。このリストからフィーチャーシンボルを削除すると、font-lock
実行中に対応するクエリが無効になります。
多くのプログラミング言語における共通機能名には、definition、type、assignment、builtin、constant、keyword、string-interpolation、comment、doc、string、operator、preprocessor、escape-sequence、およびkeyなどがあります。メジャーモードは、これらの共通機能を自由に細分化したり拡張したりすることができます。
これらの機能の中には、説明が必要なものがあります:definition
は定義対象(例:関数定義における関数名、構造体定義における構造体名、変数定義における変数名)をハイライトします。assignment は代入対象(例:代入文における変数やフィールド)をハイライトします。key
はキー・バリューペアのキー(例:JSONオブジェクトやPython辞書のキー)をハイライトします。doc はドキュメント文字列やドキュメントコメントをハイライトします。
例えば、この変数の値は以下のようになります:
((comment string doc) ; level 1 (function-name keyword type builtin constant) ; level 2 (variable-name string-interpolation key)) ; level 3
主要なモードは、treesit-major-mode-setupを呼び出す前にこの変数を設定する必要があります。
この変数を機能させるには、Lispプログラムで treesit-font-lock-recompute-features(これに応じて treesit-font-lock-settings をリセットする)、または treesit-major-mode-setup(treesit-font-lock-recompute-features を呼び出す)を呼び出す必要があります。
Tree-sitterベースのFont Lock用設定一覧。各設定の正確なフォーマットは内部仕様とされています。この変数を設定する際は、常に treesit-font-lock-rules を使用してください。
設定オブジェクトは不透明ですが、Emacsは設定のクエリ、機能、有効化フラグ、およびオーバーライドフラグへのアクセス手段(treesit-font-lock-setting-query、treesit-font-lock-setting-feature、treesit-font-lock-setting-enable、treesit-font-lock-setting-override、treesit-font-lock-setting-reversed)を提供しています。
多言語メジャーモードでは treesit-range-functions
に範囲関数を提供する必要があり、Emacs はリージョンをフォント化する前にそれに応じて範囲を設定します(複数言語のテキスト解析 を参照)。