aimdevel’s blog

勉強したことを書きます

syntax highlightのvscode拡張機能を作る

vscodeソースコードなどを表示すると、キーワードなどに色がついて表示されます。 ただし、色が付くのはvscode側がそのプログラミング言語に対応している必要があり、例えば社内の独自言語などがあった場合には当然vscodeで表示しても全く色が付きません。
色がついていないと単純にソースコードの可読性が悪かったり、タイプミスに気付きづらいなどの問題があります。
そのため今回は、独自言語でも色付けを行うためにvscodeのsyntax highlight拡張機能の作り方を調べました。以下の公式ドキュメントを参考にしました。

code.visualstudio.com

前提知識

拡張機能作成

拡張機能の新規プロジェクトを作成

公式ページに従い、projectを作成します。そこまでの環境構築は割愛します。
以下の作成例では、拡張機能名だけmy-extensionと指定し、残りはすべてデフォルト値を使用しています。

yo code

     _-----_     ╭──────────────────────────╮
    |       |    │   Welcome to the Visual  │
    |--(o)--|    │   Studio Code Extension  │
   `---------´   │        generator!        │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |     
   __'.___.'__   
 ´   `  |° ´ Y ` 

? What type of extension do you want to create? (Use arrow keys)
❯ New Extension (TypeScript) 
  New Extension (JavaScript) 
  New Color Theme 
  New Language Support 
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? my-extension
? What's the identifier of your extension? my-extension
? What's the description of your extension? 
? Initialize a git repository? Yes
? Bundle the source code with webpack? No
? Which package manager to use? npm

実行後にmy-extensionというディレクトリが作成されています。

必要なファイルを追加

作成したmy-extensionに以下のファイルを追加します。

  • syntaxes/abc.tmLanguage.json

このファイルに以下を記述します。内容は後で説明します。

{
  "scopeName": "source.abc",
  "patterns": [{ "include": "#expression" }],
  "repository": {
    "expression": {
    "patterns": [{ "include": "#letter" }]
    },
    "letter": {
    "match": "\\b(for|if|while)\\b",
    "name": "keyword"
    }
  }
}

既存ファイルの修正

作成したファイルが読み込まれるように既存の設定ファイルを修正します。修正ファイルは以下です。

  • package.json
    contributesの下に以下のように"lanmguages"と"grammars"の設定を追加します。
"contributes": {
    "commands": [
      {
        "command": "my-extension.helloWorld",
        "title": "Hello World"
      }
    ],
    "languages": [
      {
        "id": "abc",
        "extensions": [".abc"]
      }
    ],
    "grammars": [
      {
        "language": "abc",
        "scopeName": "source.abc",
        "path": "./syntaxes/abc.tmLanguage.json"
      }
    ]
  },

動作確認

vscodeからF5でデバッグを開始して、拡張子が.abcのファイルを開いてみましょう。
ifやfor、whileを入力するとその部分がhighlightされるはずです。

内容説明

先ほどのabc.tmLanguage.jsonについて説明します。
これは公式の手順から拝借したコードを改造したもので、重要なのは以下の部分です。

    "letter": {
    "match": "\\b(for|if|while)\\b",
    "name": "keyword"
    }

letterという定義でhighlightの設定を記述しています。それぞれの要素の意味は以下です。

  • match
    正規表現でマッチングさせる文字列を指定します。ここではfor, if, whileという文字列をマッチさせるようにしています。

  • name
    マッチする文字列の分類を指定します。ここの値によって文字列に適用される色が変わります。

vscodeはTextMeta grammarを使用しており、上記に設定できる値もそれに準拠しています。詳しい説明は以下のサイトを参照ください。

macromates.com

まとめ

vscodeのsyntax highlight拡張機能の作り方を調べました。
簡単なhighlightなら、この仕組みの中で作成することが出来そうです。
より複雑なことをしたい場合は、Semantic Highlightというものがあるようなので、そちらも触ってみようと思います。