Visual Studio Code プラグイン開発 - イントロダクション -

# こんにちは

  Fixstars Cloud Solutions の古坂です。
  皆さんは、Visual Studio Code を利用していますか？  
  私は、一昨年から Visual Studio Code を使っています。それ以前は、Sublime Text を使っていました。
  さて、ふと思うことがあり、この度 Visual Studio Code の機能拡張を行おうかと思っています。

  VS Code プラグインを作るための技術習得で得られた知見などを少しずつ皆様にも共有して行きますので、どうぞご覧ください。

# 初めての Visual Studio Code 拡張プラグイン

  この記事では、Visual Studio Code の拡張プラグインの開発について記述しています。

# 技術情報はどこを参照すべきか？

  Visual Studio Code 公式サイトにたくさん技術情報があります。きちんと読んでいこうかなと思います。

  - https://code.visualstudio.com/docs/extensions/overview
  - https://code.visualstudio.com/docs/extensions/yocode
  - https://code.visualstudio.com/docs/extensions/example-hello-world
  - https://code.visualstudio.com/docs/extensions/example-word-count
  - https://code.visualstudio.com/docs/extensions/example-language-server

  このあたりの情報から少しずつステップアップして行けば良さそうですね。

# エクステンション概要

  - https://code.visualstudio.com/docs/extensions/overview

  上記ページには、VS Code 機能拡張の概要について解説がなされています。

  全ての VS Code エクステンションは、以下の共通モデルを利用しています。

  - コントリビューション (レジストレーション)
  - アクティベーション (ローディング)
  - VS Code Extensibiity API アクセス

  この共通モデルを利用して、更にその上に 2種類の VS Code エクステンションがあります。

  - 言語サーバー
  - デバッガー

  これらのエクステンションは、共通モデルに加えて拡張プロトコルを持っています。それらについて別途解説していきます。

  1. エクステンション (Extension)
    - 基本機能 (base building block)
  2. 言語サーバー　(Language Servers)
    - I/Oインテンシブ、CPUインテンシブタスクの実行
  3. デバッガー (Debuggers)
    - デバッグアダプタを通じて外部デバッガと繋げる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/16225/7e11045d-78b2-d094-b372-9d876d08d941.png)

  上の図は、VS Code における Exntension のフレームワークです。

  - Electron を構成する Main プロセスと Renderer プロセスがあります。
  - Extension Host が機能拡張のベースととなるプロセスです。
  - Extension Host は Renderer プロセスとIPC通信します。
  - 言語サーバーは、VS Code 言語プロトコル (Language Protocol) を利用します。
  - デバッガーは、VS Code デバッグプロトコルを利用して、デバッグアダプターと通信します。
  - デバッグアダプターは、v8 デバッガプロトコル (Debugger Protocol) を利用して、外部プログラム (例えば、node.js) と通信します。

# エクステンション

  アクティベートされたエクステンションは、Extension Host プロセスという共有プロセス上で実行されます。VS Code とは別のプロセスで実行されることにより、VS Code のパフォーマンスに影響を与えないように設計されています。

  エクステンションには、次のようなサポートが含まれます：

  - アクティベーション
    - VS Code にプラグインがロードされます。
      - 特定のファイルタイプが読み込まれたら
      - 特定のファイルが存在していたら
      - コマンドパレットからコマンドが選択されたら
      - 特定のキーバインド (key combination) が入力されたら
  - エディター
    - エディターコンテンツの作業をサポートします
      - テキストの読み込みや編集操作
      - 選択範囲の利活用 (leverage)
  - ワークスペース
    - オープンされているエディターへのアクセス
    - ステータスバー
    - ダイアログメッセージ (information message)
    - などなど
  - イベント処理 (Eventing)
    - エディターのライフサイクルイベントのディスパッチ処理
      - ライフサイクルイベント: オープン、クローズ、チェンジなど
  - 拡張エディティング (Evolved Editing)
    - リッチな言語サポート機能のプロバイダーを作成できます。
      - IntelliSense
      - Peek
      - Hover
      - Diagnostics
      - などなどなど

  エクステンションの基本を習得するために、A-to-Z 的なチュートリアルが2つ準備されています。

  1. Hello World
    - https://code.visualstudio.com/docs/extensions/example-hello-world
    - 基本的なエクステンションを作成します。
    - フォルダー構成や、エクステンションマニフェストを理解します。
    - アクティベーションの動作を理解します。
    - ローカル環境でのエクステンションの実行、デバッグ、インストール方法を学びます。
  2. Word Count
    - https://code.visualstudio.com/docs/extensions/example-word-count
    - ファイルタイプによってアクティベートする
    - ステータスバーを更新する
    - テキストエディターの変更に応答する
    - ファイルから離れる (move off) 際にプラグインを終了する (dispose)

  以下の記事も役にたちます。Extensibility API が利用している「シェアードプログラミングパターン」について解説がされています。

  - https://code.visualstudio.com/docs/extensionAPI/patterns-and-principles

# 言語サーバー

  言語サーバーはエクステンションに対して専用プロセスを作れるようになります。他のエクステンションを遅くするような CPU インテンシブ、I/O インテンシブなヘビータスクを実行する場合、言語サーバーは有用な設計選択になります。Linter や静的解析ツールなどワークスペース内の全てのファイルを走査するようなタスクなどがあります。

  - https://code.visualstudio.com/docs/extensions/example-language-server

# デバッグアダプター

  VS Code は汎用的なデバッガー UI を実装しています。デバッガ UIは、デバッガーエクステンションと「デバッグアダプター」に依存しています。デバッグアダプターは、デバッガー UI をデバッガー本体/ランタイムと接続します。デバッグアダプターは、VS Code デバッグプロトコルを用いて VS Code と通信する専用プロセスです。任意の言語で実装が可能です。

  - https://code.visualstudio.com/docs/extensions/example-debuggers

---

  VS Code エクステンション は、エクステンションマーケットプレイスにあります。マーケットプレイスを見ると、エクステンションを簡単に見つけられます。マーケットプレイスをブラウズして有用なエクステンションを見つけたら、インストールして試しに使ってみましょう。自分自身の開発シナリオにあったエクステンションのアイデアが得られると思います。

  - https://code.visualstudio.com/docs/editor/extension-gallery

# 言語拡張ガイドライン

  言語拡張ガイドラインは、あなたのエクステンションでサポートしたい言語フィーチャー (Language Feature) を決めるのに役立ちます。ガイドラインには、VS Code 内の様々な言語フィーチャー (コードサジェスチョン、アクション、コード整形、ネーム変更) について解説しています。また、言語サーバープロトコルを利用したり、エクステンションから直接 Extensibility API を利用したりと、エクステンションの実装方法について解説しています。

  - https://code.visualstudio.com/docs/extensionAPI/language-support

# カラーテーマ、スニペット、シンタックスハイライト

  シンタックスハイライトや、有用なスニペット、きちんとしたカラーテーマのような、ちょっとした事が、皆さんのプログラミング環境を素晴らしいものにします。 TextMate カスタマイズファイルのおかげで、簡単にシンタックスハイライトや、カラーテーマ、スニペットをパッケージングしたり再利用したりできるようになります。あなた自身が直接 .tmTheme、.tmSnippets、.tmLanguage ファイルをいじることで、ご自身のエクステンションを変更できます。以下のリンク先の "Themes, Snippets, and Colorizers" というページでは、TextMate ファイルをインクルードする方法や、自分自身でカラーテーマ、スニペット、シンタックスハイライトを作る方法のガイドラインが書かれています。

  - https://code.visualstudio.com/docs/extensions/themes-snippets-colorizers

# エクステンションをプログラムする

  単純なエクステンションプロジェクトを簡単に作成する方法として Yeoman エクステンションジェネレーターというものがあります。既存のエクステンションサンプルを見つけるのも、エクステンションを書き始めるのに良いと思います。

  エクステンションは、TypeScript もしくは JavaScript で記述できます。VS Code は、VS Code 内でエクステンションの開発、ビルド、実行、テストそしてデバッグができる、一級の開発環境を提供します。

# エクステンションをテストする

  VS Code ではエクステンションのテストを書いたり実行したりするための環境を提供します。それにより、VS Code API を呼び出す結合テストを簡単に作成でき、実行中の VS Code インスタンスの上でコードをテストできます。

# エクステンションアイデア

  VS Code コミュニティから生まれるアイデアの多くは、コアプロダクトの一部として実装されるよりも、エクステンションとして実装された方が良いと思っています。こうした方が、利用者は必要なエクステンションだけをインストールすればよく、自分たちが欲しいと思う機能を選んでピックアップして行くことができます。VS Code の開発チームは、将来のエクステンションリストを GitHub の vscode リポジトリの Issue リストとして管理しています。もし、それらのエクステンションのリストをみたいと思ったら、"extension-candidate" というラベル付けされた Issue をみてください。

# 終わりに

次回は、エクステンションジェネレーターについて勉強した内容をまとめてみますね。エクステンションジェネレーターは、エクステンション開発をスタートするためのプロジェクトを作ってくれるツールになります。