textMateRules項目ではTextMateエディタで使われている「スコープ規則」に従って、プログラムコード中で構文ハイライトを行う部分と、そこに適用するフォントの色とスタイルを設定する。ここでいう「スコープ」とは例えば「1行コメント」「ブロックコメント」「型名」「数値リテラル」「文字列リテラル」といったプログラムコード中の特定の範囲を示すものだ。詳細についてはSublime Textのドキュメント「Scope Naming」ページを参照されたい。
textMateRules項目は次のような形式で、スコープとその色およびスタイルを指定していく。このときに指定するスコープのことを「セレクタ」という(CSSと同様に、空白文字で区切ってセレクタを指定することで、スコープをより限定させていくことも可能だが、本稿では説明は割愛する。興味のある方は「Themes, Snippets and Colorizers」ページを参照されたい)。foreground/fontStyle項目に指定できるのは、上で見たものとと同じだ(色は"#RRGGBB"などの形式、スタイルは"bold"/"underline"/"italic"の組み合わせ)。ただし、色名のみの簡略表記はできない。
{
// …… 省略 ……
"editor.tokenColorCustomizations": {
"textMateRules": [
{
"scope": "構文ハイライトのスコープ", // セレクタ
"settings": {
"foreground": "そのスコープの色",
"fontStyle": "そのスコープのスタイル"
}
},
{
// 同様な設定を行う
}
// …… 同様な設定が続く ……
]
}
}
実際にはname項目も指定可能だが、本稿では割愛する。実際の設定例を以下に示す(先ほど設定したcomments項目などは削除している)。
{
// …… 省略 ……
"editor.tokenColorCustomizations": {
"textMateRules": [ // textMateRules項目で詳細に設定を行う
{
"scope": "comment.line", // 1行コメント
"settings": {
"foreground": "#FF0000",
"fontStyle": "bold"
}
},
{
"scope": "comment.block", // ブロックコメント
"settings": {
"foreground": "#008800",
"fontStyle": "italic bold"
}
},
{
"scope": "constant.numeric", // 数値リテラル
"settings": {
"foreground": "#888800",
"fontStyle": "bold underline"
}
},
{
"scope": "string", // 文字列
"settings": {
"foreground": "#338888",
"fontStyle": "bold"
}
},
{
"scope": "entity.name.type", // 型名など
"settings": {
"foreground": "#0000FF",
"fontStyle": "bold"
}
}
]
}
}
以上の設定を以下のC#コードに適用してみることにしよう。
using System;
namespace cs_sample
{
class Foo {}
class Program
{
static void Hello(string whom) {
// sample comment line
string msg = $"Hello {whom}";
Console.WriteLine(msg);
}
static void Main(string[] args)
{
/*
commnet block
*/
string[] items = { "Insider.NET", "Windows Server Insider", "Build Insider" };
for (int i = 0; i < 3; i++)
{
Hello(items[i]);
}
Foo f = new Foo();
Console.ReadKey();
}
}
}
上で設定した項目がどのように反映されるかを見てみたいので、コードはくどい箇所もあるがご容赦されたい。実際のエディタ画面は次のようになる。ダブルスラッシュで始まる1行コメントと、「/* 〜 */」で囲まれたブロックコメントで色が変わっているところや、クラス名や名前空間名などが強調書体で表示されているところ、文字列リテラルや整数リテラルの色が変わっているところに注目されたい。
その一方で、「Foo f = new Foo();」という行では、クラス名の色にもスタイルにも変化がない。これは上の設定で指定したスコープ(entity.name.type)とは異なっているからだ。これがどんなスコープになっているかをコードから人が判断するのは難しい。そこで、VS CodeにはTextMateのスコープをチェックするためのコマンドが用意されている。これを利用するにはコマンドパレットで「tm scope」などと入力して、[開発者: TM スコープの検査]コマンドを実行すればよい。実は、上で設定したスコープも幾つかはこの方法で調べたものだ。
すると、VS Codeのエディタ画面でカーソルがある部分について、TextMateのスコープがポップアップ表示されるようになる(表示を止めるには[ESC]キーを押す)。
上の画像は先ほどの「Foo f = new Foo();」の「Foo」にカーソルがある状態だ。ポップアップには、解析の結果として、言語が何か、トークンの種類、表示に使われているフォントや色の情報、実際に使われているセレクタ、スコープが列挙されている。
上の画像からは、セレクタは「storage.type.cs」であることと、スコープは同じく「storage.type.cs」と「source.cs」であることが分かる。また、最後に付いている「.cs」はこれがC#のソースコードであることを示している。TextMateのスコープは、ソースファイル内部でツリーを形成するので、これは「C#のソースファイル」→「C#で変数などを宣言する際に使用するキーワード」というスコープを表している。ちなみに、TextMateでは前方一致でスコープのマッチを行うため、「storage.type」というスコープは「storage.type.cs」を含むことになる。そこで、上の設定を次のように修正すると、「Foo f = new Foo();」の「Foo」も強調表示されるようになる。
{
// …… 省略 ……
"editor.tokenColorCustomizations": {
"textMateRules": [
// …… 省略 ……
{
"scope": [
"entity.name.type",
"storage.type"
],
"settings": {
// …… 省略 ……
}
}
]
}
}
このようにスコープ(セレクタ)を要素とする配列として記述することで、複数のスコープに同一の設定を適用できる。実際に適用した結果を示す。
ここまで見てきたように、settings.jsonファイルのeditor.tokenColorCustomizations項目を使うことで、構文ハイライトの簡易的なカスタマイズとより詳細なカスタマイズを行える。このようにしてカスタマイズした設定はテーマとして保存して、VS Marketplaceで公開したり、別のマシンに拡張機能としてインストール(コピー)して利用したりできる。次ページではこれについて簡単に見ていこう。
なお、構文ハイライトの詳細については「Optimizations in Syntax Highlighting」ページ、「User and Workspace Settings」ページ、「Themes, Snippets and Colorizers」ページなどを参照されたい(いずれも英語ページ)
Copyright© Digital Advantage Corp. All Rights Reserved.