Visual Studio Code はじめての拡張機能開発
最近、Visual Studio Codeを使い始めました。
主に、メモ程度の文書作成ですが、Markdpwn形式で作成して、まとめています。Previewが簡単に見れるのがいいですね。
さて、本題ですが、ほしい機能が見つからなく、拡張機能を作ることができるので、作ってみたいと思います。といっても、作り方がわからないので、HelloWorldです。
Hollo worldを表示する拡張機能
ここに書くサンプルは、、公式サイトに載っています。
公式サイト Example - Hello World
開発環境
- Windows 10 Pro 1607
- Visual Studio Code v1.4
- node.js v6.3.1
環境構築
Node.js
まずは、Node.jsが必要なので、インストールをします。
Node.jsには、LSTとCurrentがありますが、そろそろ、LSTになりそうなので、今回は、Currentバージョンです。
Node.jsがインストールされたら、環境変数のPATHを通します。
デフォルトだと、「C:\Program Files\nodejs」に、インストールされます。
「システムプロパティ」ウィンドウの「詳細設定」タブにある、「環境変数」ボタンで設定できます。
一例として、コントロールパネル > システム > システムの詳細設計 から「システムプロパティ」が表示できる。
コマンドの確認
インストール・設定後に、コマンドプロンプトから、確認をします。
- Node.js
>node -v
>v6.3.1
>npm -v
>3.10.3
- code (Visual Studio Code本体)
念のため、code.exe(Visual Studio Code本体)が実行できるか確認しておきましょう。
コマンドプロンプトから、確認します。
>code -v
>1.4.0
実行できなかった場合は、「C:\Program Files (x86)\Microsoft VS Code」(デフォルト)を入れてください。
ジェネレータのインストール
npmコマンドを使って、拡張機能のジェネレータをインストールします。コマンドプロンプトから実行します。
>npm install -g yo generator-code
WARNが出ましたが、解消しないで、進めてます。--save付ければ大丈夫?
npm install -g yo generator-code --save
ひな形の作成
ジェネレータを使って、拡張機能のひな形を作成します。
以下を、実行すると、カレントディレクトリに、コマンド実行中に指定した名称で、フォルダおよび、必要なファイルが作成されます。
>yo code
質問されるので、TypeScript(そのまま、Enter)を選んで、Extention名を「helloworld」にします。
あとは、デフォルトのままで、Enterを押します。
質問 | 回答 | 備考 |
---|---|---|
? What type of extension do you want to create? | New Extention (TypeScript) | 拡張機能のタイプ |
? What's the name of your extension? | helloworld | 拡張機能名 |
? What's the identifier of your extension? | helloworld | 拡張機能のID。公開しないので、そのまま。 |
? What's the description of your extension? | 拡張機能の説明。今のところ、空で大丈夫です。 | |
? What's your publisher name? | helloworld | 公開者。公開しないので、そのまま。 |
? Initialize a git repository? | Yes | gitの初期化。ローカルリポジトリの作成。 |
_-----_ ╭──────────────────────────╮
| | │ Welcome to the Visual │
|--(o)--| │ Studio Code Extension │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? helloworld
? What's the identifier of your extension? helloworld
? What's the description of your extension?
? What's your publisher name? helloworld
? Initialize a git repository? Yes
create helloworld\.vscode\launch.json
create helloworld\.vscode\settings.json
create helloworld\.vscode\tasks.json
create helloworld\typings\node.d.ts
create helloworld\typings\vscode-typings.d.ts
create helloworld\test\extension.test.ts
create helloworld\test\index.ts
create helloworld\.vscodeignore
create helloworld\.gitignore
create helloworld\README.md
create helloworld\vsc-extension-quickstart.md
create helloworld\tsconfig.json
create helloworld\src\extension.ts
create helloworld\package.json
・・・・・・・・・・・
いくつかメッセージ
・・・・・・・・・・・
Your extension helloworld has been created!
To start editing with Visual Studio Code, use the following commands:
cd helloworld
code .
Open vsc-extension-quickstart.md inside the new extension for further instructions
on how to modify, test and publish your extension.
For more information, also visit http://code.visualstudio.com and follow us @code.
開発とデバッグ
Visual Studio Code(VS Code)を起動します。
ジェネレータ実行時のメッセージに書かれている、コマンドを実行します。
>cd helloworld
>code .
はじめに
ひな形作成時のメッセージに出力されている通り、「vsc-extention-quickstart.md」を開いて説明を見てみます。
Markdown形式なので、プレヴュー切り替えでHTMLにして、見ます。「ctrl + shift + v」もしくは、右クリックのプレビュー。
記載内容のざっくりですが、説明です。
- package.jsonとsrc/extension.tsの簡単な説明
- 実行方法。「F5」、もしくは、「ビューバーのデバッグアイコンを押下」
- 実行後の変更は、リロード方法。 「ctrl + r」
- API一式 「node_modules/vscode/vscode.d.ts」に記載
- テストコードの実行。
ctrl + shift + dで、デバッグウィンドウを開き、「Launch Tests」を設定する。
F5を押して、拡張機能がロードされたVS Codeを立ち上げる
テスト結果は、デバッグコンソールに出力される
test/extension.test.ts、もしくは、testフォルダ内に新しいテストファイルをいれますファイル名は、「**.test.ts」のようにします。
主要なファイルの表
ファイル名 | 説明 |
---|---|
vsc-extension-quickstart.md | クイックスタートマニュアル |
package.json | プラグインの定義ファイル |
src/extension.ts | 拡張機能のメインファイル。 |
tsconfig.json | TypeScriptのビルドオプションファイル |
デバッグ
では、実際に動かしてみましょう。
- VS Codeをアクティブにして、「F5」、もしくは、「ビューバー」の「デバッグ」アイコンを押します。
- helloworldの拡張機能が有効になった、新しくVS Codeが開かれます。
- 新しいVS Codeをアクティブにして、コマンドパレットを開きます。「ctrl + shift + p」。
- command指定の「>」をつけたまま、「Hello World」を入力して、プルダウンに表示された「Hello World」を選択します
- コマンドパレット下に、情報タイプのメッセージボックスが開いて、「Hello World!」と表示されれば、成功です。
- 新しいウィンドウを閉じて、終了させます
ファイル詳細
package.json
まずは、定義を見ていきます。
記述されているのは、名称や、バージョンなどの拡張機能の定義情報と、拡張機能でVS Codeやnpmで、使用する機能情報になります。
重要な部分をピックアップして、もう少し、詳しく見ていきます。
{
"activationEvents": [
"onCommand:extension.sayHello"
],
"contributes": {
"commands": [{
"command": "extension.sayHello",
"title": "Hello World"
}]
}
}
- activationEvents
拡張機能がロードされるタイミングです。「onCommand」が指定されているので、コマンド呼び出し時になります。
コマンドの呼び出しは、contributesで指定されている定義で決定されます。
今回の場合は、コマンドパレットから、コマンド「Hello World」が選択されたときに、extension.tsのactivateが一度だけ実行されて、VS Codeに拡張機能として取り込まれます。
- contributes
ここで指定するのは、どのような時に、拡張機能を実行するのか指定します。
今回の場合は、コマンド実行時で、「Hello World」が、指定されたときになります。
「title」は、コマンドパレット内の表示情報となります。コマンドパレット内で、「Hello World」と検索できます。
「command」は、実行するコマンドになります。「comannds」では、複数の「command」が指定できます。
「src/extension.ts」で指定されている、「registerCommand」の引数のcomannd文字列を同じでなくてはなりません。実際のコードは、extension.tsで、指定します。
「contributes」は、他にも「menu」や「ショートカットキー」、などが指定できます。
公式サイト Contribution Points
その他の「package.json」内の説明は、表にまとめました。
名称 | 必須 | タイプ | 説明 |
---|---|---|---|
name | Y | string | 拡張機能の名称。スペースなしの小文字 |
version | Y | string | バージョン。フォーマットは、「MAJOR.MINOR.PATCH」。
|
publisher | Y | string | 公開者名。Marketplaceにアップするときに使用します。 |
engines | Y | object | VS Codeの最小バージョンを指定します。 |
displayName | string | Marketplaceで使用する拡張機能の表示名 | |
description | string | 拡張機能の説明 | |
categories | string[] | 拡張機能の使用するカテゴリを指定。値としては、[Languages, Snippets, Linters, Themes, Debuggers, Other] | |
activationEvents | array | 拡張機能をロードするタイミングを指定。[onLanguage:${language}, onCommand:${command}, onDebug:${type}, workspaceContains:${toplevelfilename}, * | |
main | string | 拡張機能のエントリーポイントを指定 | |
contributes | object | 拡張機能のコントリビューション | |
scripts | object | 様々なタイミングで実行される script コマンド | |
devDependencies | object | 開発時のテストやドキュメンテーションに利用する外部のフレームワークの設定 |
公式サイト Extension Manifest File - package.json
package.jsonの参考資料
extension.ts
では、拡張機能のコードを見ていきます。
以下、がソースファイルの中身です。わかりやすいように、コード内に説明を入れています。
// strictモードの宣言
// コード内のエラー判定が厳しくなり、あいまいなコードに制限がかかる
'use strict';
// VSCodeのモジュールをインポート。
import * as vscode from 'vscode';
// 拡張機能を作成するときには、「activate」関数をexportする必要があります。
// ロード時に一度だけ呼ばれます。
export function activate(context: vscode.ExtensionContext) {
// コンソール出力
console.log('Congratulations, your extension "helloworld" is now active!');
// vscodeモジュールのcommands.registerCommandの呼び出し
// commandは、「extension.sayHellow」で、実行時には、
// 「() => 」引数なしで呼び出され、「vscode.window.showInformationMessage('Hello World!');」が実行されます。
let disposable = vscode.commands.registerCommand('extension.sayHello', () => {
// 情報タイプのメッセージを表示
// コマンドが実行されるたびに、extension.sayHelloが呼ばれて、この関数のみ実行される
vscode.window.showInformationMessage('Hello World!');
});
// 拡張機能が使用されなくなったときに、リソース開放を行うための、設定。
// 今回は、registerCommandの指定をを開放する必要があるので、開放対象に追加する。
context.subscriptions.push(disposable);
}
// 拡張機能が非アクティブ化されたときに、実行されます。
export function deactivate() {
}
大事なことは、「registerCommand」で指定する「'extension.sayHello'」と、実行に必要なコールバックの関数です。
コールバック関数の指定は、アロー関数式で、記述されている無名関数が、実行されるたびに呼ばれます。
「'extension.sayHello'」は、package.jsonで指定されているものと同じでなくてはなりません。
また、使用したリソースを開放するために、「context.subscriptions」に、「push」する必要があります。
デバッグするとわかりますが、activate関数では、それぞれの設定のみが行われて終了します。
activate終了後に、「extension.sayHello」の実行が行われます。
また、activate関数は、最初のロード時にしか、呼び出されません。
備考
拡張機能で、「vscode-icons」を入れていたのですが、ファイルに対して権限が必要で、無視してました。
デバッグ実行の時に、それが例外だして、実行できない状態でした。
できるだけ、まっさらな環境で、作成したほうが、良さそうです。