VSCode用のGrimoire.js language extensionを作ったよ

# Grimoire.js Helper for VSCode を公開した話
この記事は、[Grimoire.js Advent Calendar 2016](http://qiita.com/advent-calendar/2016/grimoire)の11日目の記事…だっははず(大遅刻)です。

## TL;DR

[Grimoire.js用のVSCode拡張機能を作った！皆使え！](https://marketplace.visualstudio.com/items?itemName=m2wasabi.grimoire-js-helper)

## 拡張機能の作り方

### 土台(Scaffold)の作成

基本的に[公式の方法](https://code.visualstudio.com/docs/extensions/example-hello-world) で無事完了できます。

今回はlanguageとsnnipetsのみ作りたかったので、
スクリプト機能は無し。

yomanをインストールして起動

```
npm install -g yo generator-code
yo
```

![yo01.jpg](https://qiita-image-store.s3.amazonaws.com/0/35009/ede03598-3dfb-2c7d-fd72-0498e2b27a57.jpeg)


`Code`を選ぶ

![yo02.jpg](https://qiita-image-store.s3.amazonaws.com/0/35009/7d3a77a9-78e5-472d-79bb-8a730619534f.jpeg)

何作る？って聞いてくるので、
今回は `New language support` と `New Code Snippets` の機能をもったものを作りたいです。

合わせ技の拡張機能は手動で作るしかないので、適当なディレクトリに `language` と `Snippets` をそれぞれ作り、
参考にしつつ新しい場所にミックスします。(手動めんどいです!)

拡張機能の作り方は
VSCodeのインストールディレクトリの `resources/app/extensions/` に沢山サンプルがあるので参考にするといいかもしれないです。
ちゃんとしたドキュメントが無いとヤダヤダって人は [公式のドキュメントリポジトリ](https://github.com/Microsoft/vscode-docs) を見ましょう。

### 言語の定義

`package.json` にlanguage拡張機能が入っていることを定義します。
今回はスニペットも使うので併記します。

```json:package.json
{
    "categories": [
        "Languages",
        "Snippets"
    ],
}
```

機能の詳細は `contributes` オブジェクトに記述します。

```json:package.json
{
    "contributes": {
        "languages": [
            {
                "id": "goml",
                "aliases": [
                    "GOML",
                    "goml"
                ],
                "extensions": [
                    ".goml"
                ],
                "firstLine": "(\\<\\goml.*)",
                "configuration": "./language-configuration.json"
            },
            {
                "id": "glsl",
                "extensions": [
                    ".sort"
                ]
            }
        ],
        ...
    }
}
```

GOMLについて、名前・idなどを定義し、
言語の規則は`language-configuration.json` を参照するよう書いています。

また、 `glsl`について 、`id`と `extensions` のみ定義していますが、
こうすることで、他の拡張機能のlanguage設定をidで引っ張ってくることができます。
他の優秀な拡張機能が文法をしっかり押さえている場合には便利です。

### 文法の記述

文法の記述は、以下のように書きます。
ここでは `text.xml.goml` というスコープ名を定義し、
その内容は `./syntaxes/goml.json` に書いてある旨を設定しています。

```json:package.json
{ 
   "contributes": {
        ...
        "grammars": [
            {
                "language": "goml",
                "scopeName": "text.xml.goml",
                "path": "./syntaxes/goml.json"
            }
        ],
        ...
    }
}
```

今回、 `./syntaxes/goml.json` は、
VSCode内蔵の xml の定義を参考に作成しました(コピペ長すぎるので割愛します)

### スニペットの記述

スニペットの定義もgrammarと同様にファイルを指定するだけのシンプルなものです。

```json:package.json
{
    "contributes": {
        ...
        "snippets": [
            {
                "language": "goml",
                "path": "./snippets/snippets.json"
            }
        ]
    }
}
```

実際のスニペットの記述方法は以下のようにシンプルです。

|項目|説明|
|---|---|
|prefix|ここで指定した文字を打ち込むことで候補として表示される|
|body|登録されたスニペットの内容。`$1`の記述はプレースホルダで、`tab`キーを使って移動する|
|description|スニペットの説明|

```json:./snippets/snippets.json
{
    "GOML": {
        "prefix": "goml",
        "body": [
            "<goml width=\"fit\" height=\"fit\">",
            "    $1",
            "</goml>"
        ],
        "description": "goml tag"
    },
    ...
    "mesh with component": {
        "prefix": "mesh-component",
        "body": [
            "<mesh color=\"$1\" position=\"$2,$3,$4\" geometry=\"$5\"/>",
            "  <mesh.components>",
            "    $6",
            "  </mesh.components>",
            "</mesh>$7"
        ],
        "description": "GOML Snippet: Mesh with component"
    }
}
```

### 動かしてみる

ローカルで動かしたい場合は、`F5` キーを押すことで、
現在の拡張機能を有効にした状態で新しいVSCodeが立ち上がるので、
それで動作を確認します。

![snippet.gif](https://qiita-image-store.s3.amazonaws.com/0/35009/e0b90993-30e7-72bd-8e38-9fc415f3ff07.gif)

## 公開の方法

[Visual Studio Teaqm Services](https://www.visualstudio.com/en-us/get-started/setup/sign-up-for-visual-studio-online) にログインできるアカウントが必要です。

基本的には公式の方法そのままで大丈夫。
https://code.visualstudio.com/docs/tools/vscecli

## 使いたい！

`Ctrl` + `Shift` + `X` で拡張機能を検索し、
 `Grimoire.js Helper` を選ぶことでインストールできます。

![vsc.JPG](https://qiita-image-store.s3.amazonaws.com/0/35009/7d2ffcf0-620a-d27e-e64b-dd39567fd5e2.jpeg)

ご参考までに、ソースはGitHubに公開しています。
[GitGubリポジトリ](https://github.com/m2wasabi/vsc-ext-grimoirejs-helper)

## 最後に

意外と簡単に公開できるので、みんなマイナー言語のVSCode拡張を作ればいいと思う。

これでWeb3Dコンテンツ作成が捗ればいいな。

VSCodeのLanguage extensionで、
さらに進化した話題にLauguage Server という仕様があるけど、とても大変そうな予感しかしない…
http://qiita.com/atsushieno/items/ce31df9bd88e98eec5c4