VSCodeでLSP(Extensionの実装方法を調べる編)

[LSP]VSCodeでLSP(クライアント側のサンプルを読む編)で LSPのクライアント側の実装を見てみたものの、
Extension の実装も見ておかないと理解できなさそうだったのでこちらも見てみる。
参照したのは以下。
https://code.visualstudio.com/docs/extensions/example-hello-world

下準備

Node.js のインストール。
そのあと npm で yo と generator-code をインストールする。

npm install -g yo generator-code

Extension のテンプレートの生成

テンプレート生成したいフォルダに移動して以下を実行

yo code

最初にテンプレートの種類を聞かれるので「New Extension(TypeScript)」を選択。
後はExtension名とかいろいろ。
ちなみに、Nodist を使って Node.js をインストールしてた時は、
「Trying to copy from a source that does not exist:…」
というエラーが出た。
Nodist をやめて普通に Node.js をインストールして使うと正常に実行できた。

実行してみる

VSCode を立ち上げて生成したフォルダを開き、F5 を実行すると、
拡張機能開発ホストが立ち上がる(VSCode の別インスタンス)。
その状態で Ctrl + Shift + P で "Hello World" と打つと右下にポップアップで「Hello World」と表示される。

実装を読む

main 文に該当するのは src/extension.ts ファイルの activate() 関数。
package.json の activationEvents に記載のタイミングで実行される。
逆に終了時は deactivate() が呼ばれるとのこと。

'use strict';
import * as vscode from 'vscode';

// これが main文
export function activate(context: vscode.ExtensionContext) {
    // ログ出力。実行されたらデバッグコンソールに出力される。
    // ※ここは一度だけ通る
    console.log('Congratulations, your extension "test" is now active!');

    // 'extension.sayHello' はコマンドの名前。
    // ※ package.json にも記述する
    let disposable = vscode.commands.registerCommand('extension.sayHello', () => {
        // ※このスコープはコマンドを実行する度に通る
        // 右下に表示されたインフォーメーションメッセージはこれ
        vscode.window.showInformationMessage('Hello World!');
    });
    context.subscriptions.push(disposable);
}

// 終了時に呼ばれるデストラクタみたいなもの
export function deactivate() {
}

package.json を読む

実装と紐づいている箇所としては、activationEvents あたり。

{
    "name": "test", ←★yo code 時に入力した内容
    "displayName": "test",←★yo code 時に入力した内容
    "description": "test",←★yo code 時に入力した内容
    "version": "0.0.1",
    "engines": {
        "vscode": "^1.29.0"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [
        "onCommand:extension.sayHello"
        ↑★vscode.commands.registerCommand() の第1引数と同じ
    ],
    "main": "./out/extension",
    "contributes": {
        "commands": [
            {
                "command": "extension.sayHello",
                ↑★vscode.commands.registerCommand() の第1引数と同じ
                "title": "Hello World"
                ↑★コマンドパレットで入力するのはこっち
            }
        ]
    },
   :
}