シンプルな構文的Font LockやregexpベースのFont Lockに加えて、Emacsはパーサーを用いた完全な構文的Font Lockも提供します。Emacsでは現在のところは、この目的のためにtree-sitterライブラリーを使用しています(プログラムソースの解析を参照)。
パーサーベースのFont Lockそれ以外のFont Lockのメカニズムは互いに排他ではありません。もしパーサーベースのFont Lockが有効なら、最初に構文的Font Lock置き換わり実行されて、その後にregexpベースのFont Lockが実行されます。
パーサーベースのFont LockがregexpベースのFont
Lockと同じカスタマイズ変数を共有しないとしても、カスタマイズでは類似したスキームを使用します。tree-sitterにおいてfont-lock-keywords
のカウンターパートとなるのがtreesit-font-lock-settings
です。
tree-sitterのフォント表示は一般的には以下のように機能します:
font-lock-keyword
とタグ付けされたノードなら、font-lock-keyword
フェイスによってハイライトされることになるだろう。
クエリー、パターン、キャプチャ名n関する詳細については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式、あるいはコンパイル済みフォームのいずれかによるtree-sitterクエリーのこと。
queryそれぞれの前にはクエリーにメタ情報を付加するkeyword/valueペアーが前置される。キーワード:language
はqueryの言語を宣言、キーワード:feature
はqueryのfeature名をセットする。ユーザーhtreesit-font-lock-level
とtreesit-font-lock-feature-list
によって、どのfeatureを有効にするかを制御できる(後述)。いずれのキーワードも必須(例外あり)。
その他のキーワードはオプションである:
キーワード | 値 | 意味 |
---|---|---|
:override | nil | そのリージョンにすでにフェイスがセットされていれば新たなフェイスを破棄 |
t | 常に新たなフェイスを適用する | |
append | 既存フェイスの後に新たなフェイスを追加 | |
prepend | 既存フェイスの前に新たなフェイスを追加 | |
keep | 既存フェイスなしでリージョンをフィルする | |
:default-language | language | このキーワードの後のqueryは、デフォルトではすべてlanguageを使用する。 |
Lispプログラムはquery内のパターンをキャプチャ名(@
で始まる名前)でマークする。そしてtree-sitterは同じキャプチャ名でタグ付けされたノードをリターンする。フォント表示という目的のために、queryのキャプチャ名はfont-lock-keyword-face
のようなフェイス名であること。キャプチャされたノードはそのフェイスによってフォント表示されることになる。
キャプチャ名は関数でもよい。この場合にはnode and
override、start、endという4つの引数で呼び出される関数であること。ここでnodeはそのノード自身、overrideはそのノードにキャプチャされたルールの:override
プロパティ、startとendはこの関数がフォント表示するべきリージョンを制限する(この関数がoverrideを尊重したければtreesit-fontify-with-override
を使用できる)。
機能拡張を可能にするために、その関数は5つ以上の引数が与えられた場合にはそれらをオプションの引数として受け入れる必要がある。
キャプチャ名がフェイスと関数のどちらにも当てはまる場合にはフェイスが優先される。フェイスにも関数にも当てはまらないキャプチャ名は無視される。
これはfeatureシンボル(feature symbol:
機能シンボル)のリストのリスト。このリストの要素はそれぞれ装飾レベルを表すためのリストである。どのレベルをアクティブにするかを制御するのがtreesit-font-lock-level
。
リストの要素はそれぞれ(feature …)
という形式のリスト。ここでfeatureはそれぞれtreesit-font-lock-rules
内で定義されるクエリーで対応する:feature
の値。このリストからfeatureシンボルを削除することによって、font-lockの間に対応するクエリーが無効なる。
多くのプログラミング言語にとって一般的なfeature名にはdefinition
、type
、assignment
、builtin
、constant
、keyword
、string-interpolation
、comment
、doc
、string
、operator
、preprocessor
、escape-sequence
、key
が含まれる。メジャーモードはこれらの一般的なfeatureを自由に分割あるいは拡張ができる。
これらのfeatureのうちいくつかは説明が必要だろう。definition
は何であれ定義されつつあるものをハイライトする(関数定義の関数名、構造体定義構造体名、変数定義の変数など)。assignment
は何であれ割り当てされつつあるものをハイライトする(割り当て命令の変数やフィールドなど)。key
はキー/値ペアーのキーをハイライトする(JSONオブジェクトのキーやPythonのdictionaryなど)。doc
はdoc文字列や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-settings
をリセットする)treesit-font-lock-recompute-features
、または(treesit-font-lock-recompute-features
を呼び出す)treesit-major-mode-setup
を呼び出す必要がある。
tree-sitterベースのfont
lock用のセッティングのリスト。セッティングそれぞれの正確なフォーマットは内部的なフォーマットとみなされる。この変数のセットには、常にtreesit-font-lock-rules
を使うこと。
複数言語用のメジャーモードはtreesit-range-functions
でrange関数(range function:
範囲関数)を提供する必要があり、Emacsはリージョンのフォント表示を行う前にrangeを適宜セットします(複数言語のパースを参照)。