Previous: , Up: Font Lockモード   [Contents][Index]


24.6.10 パーサーベースのFont Lock

シンプルな構文的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のフォント表示は一般的には以下のように機能します:

クエリー、パターン、キャプチャ名n関する詳細についてはtree-sitterノードにたいするパターンマッチングを参照してください。

tree-sitterのフォント表示をセットアップするためには、まずメジャーモードがtreesit-font-lock-rulesの出力をtreesit-font-lock-settingsにセットしてからtreesit-major-mode-setupを呼び出す必要があります。

Function: treesit-font-lock-rules &rest query-specs

これは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ペアーが前置される。キーワード:languagequeryの言語を宣言、キーワード:featurequeryのfeature名をセットする。ユーザーhtreesit-font-lock-leveltreesit-font-lock-feature-listによって、どのfeatureを有効にするかを制御できる(後述)。いずれのキーワードも必須。

その他のキーワードはオプションである:

キーワード意味
:overridenilそのリージョンにすでにフェイスがセットされていれば新たなフェイスを破棄
t常に新たなフェイスを適用する
append既存フェイスの後に新たなフェイスを追加
prepend既存フェイスの前に新たなフェイスを追加
keep既存フェイスなしでリージョンをフィルする

Lispプログラムはquery内のパターンをキャプチャ名(@で始まる名前)でマークする。そしてtree-sitterは同じキャプチャ名でタグ付けされたノードをリターンする。フォント表示という目的のために、queryのキャプチャ名はfont-lock-keyword-faceのようなフェイス名であること。キャプチャされたノードはそのフェイスによってフォント表示されることになる。

キャプチャ名は関数でもよい。この場合にはnode and overridestartendという4つの引数で呼び出される関数であること。ここでnodeはそのノード自身、overrideはそのノードにキャプチャされたルールの:overrideプロパティ、startendはこの関数がフォント表示するべきリージョンを制限する(この関数がoverrideを尊重したければtreesit-fontify-with-overrideを使用できる)。

機能拡張を可能にするために、その関数は5つ以上の引数が与えられた場合にはそれらをオプションの引数として受け入れる必要がある。

キャプチャ名がフェイスと関数のどちらにも当てはまる場合にはフェイスが優先される。フェイスにも関数にも当てはまらないキャプチャ名は無視される。

Variable: treesit-font-lock-feature-list

これはfeatureシンボル(feature symbol: 機能シンボル)のリストのリスト。このリストの要素はそれぞれ装飾レベルを表すためのリストである。どのレベルをアクティブにするかを制御するのがtreesit-font-lock-level

リストの要素はそれぞれ(feature …)という形式のリスト。ここでfeatureはそれぞれtreesit-font-lock-rules内で定義されるクエリーで対応する:featureの値。このリストからfeatureシンボルを削除することによって、font-lockの間に対応するクエリーが無効なる。

多くのプログラミング言語にとって一般的なfeature名にはdefinitiontypeassignmentbuiltinconstantkeywordstring-interpolationcommentdocstringoperatorpreprocessorescape-sequencekeyが含まれる。メジャーモードはこれらの一般的な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を呼び出す必要がある。

Variable: treesit-font-lock-settings

tree-sitterベースのfont lock用のセッティングのリスト。セッティングそれぞれの正確なフォーマットは内部的なフォーマットとみなされる。この変数のセットには、常にtreesit-font-lock-rulesを使うこと。

複数言語用のメジャーモードはtreesit-range-functionsでrange関数(range function: 範囲関数)を提供する必要があり、Emacsはリージョンのフォント表示を行う前にrangeを適宜セットします(複数言語ののパースを参照)。