VSCodeで拡張機能を自作開発入門編「開発環境から自作の設定ファイルを作りつつその設定を呼び出すまで」

## 今回やりたいこと

１.自作の拡張機能の設定ファイルを作ってユーザーが自由に設定できるようにさせたい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304752/3e575d3c-6a3a-9770-013b-f6abfb532936.png)

2.こんな風に独自のコマンドを入力すると値が取れてくるようにしたい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304752/37501492-521b-7177-e619-48318380833d.png)

を実現する方法です。

自分のメモ的にメモしてみました。

検索力が弱いのか、記事が見つからなかったのですでにあったらごめんなさいと言いながら載せておきます。

## 自作開発できる環境準備

https://qiita.com/HelloRusk/items/073b58c1605de224e67e

こちら参考になるかと思います。

やることは簡単で、

````powershell
yarn add yo generator-code
````

を開発に打ち込んで、禅問答を繰り返してプロジェクトを開始していけばいいのです。

設定方法を参考にしたい方は、こちらを参考に見ながら良いところを盗みつつ職人のように設定してみるといいと思います。

https://qiita.com/HelloRusk/items/073b58c1605de224e67e


自分は、なんとなくの感覚で、今日はTypeScriptでま、いっか😃という思いでTypeScriptとコマンドはエラーばかり出てヤーン😆って気分だったので`yarn`を選びました。

まぁそんなこんなでプロジェクトが立ち上がると思います。

## プロジェクト内のフォルダの説明

`src/extension.ts`は、メインでコマンドを実行するところです。

なるほどと・・・

````ts
// モジュール読み込むから消して欲しくないでござる。
import * as vscode from 'vscode';

// 拡張機能が有効になったときに実行されるでござる。
export function activate(context: vscode.ExtensionContext) {
  // コマンドを書いて欲しいでござる。
  let disposable = vscode.commands.registerCommand('sample.helloWorld', () => {
    // ここからなんかしたいことを書くのでござる
    // 今回は設定で設定した値を取ってくるのでござるよ（何を言っているのかよくわからんという苦情は受けつないでござる）
    // ここまで関数を書くのでござる。
  });

  // 拡張機能を無効化にした時のリソース解放に使うための設定でござる。
  context.subscriptions.push(disposable);
}

// プラグインを削除した時に使うコマンドでござるよ。
export function deactivate() {}
````

全部、日本人らしい心でコメントをしたので、これを読んだ読者さんは私が何も言わずとも、わかってくれるでしょう。

そして、`/package.json`というものが作成されているので、こちらにコマンドと設定を記載すればいいのだとなんとなくわかります。

こちらが、設定ファイルを設定するためのマニュアルです。他にも、コンテキストメニューを押した時にコマンドを追加できたり画面全体のUIを決めたりすることもできます。

https://code.visualstudio.com/api/references/contribution-points#Configuration-schema

イベント発火などはこちらが参考になります。

https://code.visualstudio.com/api/references/activation-events

やはり、公式を見るのが一番ですね。


## 設定ファイルの作り方

まず、私の設定ファイルをお見せしましょう。

````json
{
  "name": "sample",
  "displayName": "VScodeToNotion",
  "description": "",
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.77.0"
  },
  "categories": [
    "Other"
  ],
  "main": "./dist/extension.js",
  "contributes": {
    "commands": [
      {
        "command": "sample.helloWorld",
        "title": "Hello World"
      }
    ],
    "configuration": {
      "title": "helloWorldSettings",
      "properties": {
        "sample.api": {
          "type": "string",
          "default": "",
          "description": "APIを設定してください"
        },
        "sample.databaseId": {
          "type": "string",
          "default": "",
          "description": "データーベースIDを設定してください"
        }
      }
    }
  },
  "scripts": {
    "vscode:prepublish": "yarn run package",
    "compile": "webpack",
    "watch": "webpack --watch",
    "package": "webpack --mode production --devtool hidden-source-map",
    "compile-tests": "tsc -p . --outDir out",
    "watch-tests": "tsc -p . -w --outDir out",
    "pretest": "yarn run compile-tests && yarn run compile && yarn run lint",
    "lint": "eslint src --ext ts",
    "test": "node ./out/test/runTest.js"
  },
  "devDependencies": {
    "@types/vscode": "^1.77.0",
    "@types/glob": "^8.1.0",
    "@types/mocha": "^10.0.1",
    "@types/node": "16.x",
    "@typescript-eslint/eslint-plugin": "^5.59.1",
    "@typescript-eslint/parser": "^5.59.1",
    "eslint": "^8.39.0",
    "glob": "^8.1.0",
    "mocha": "^10.2.0",
    "typescript": "^5.0.4",
    "ts-loader": "^9.4.2",
    "webpack": "^5.81.0",
    "webpack-cli": "^5.0.2",
    "@vscode/test-electron": "^2.3.0"
  }
}

````

こんな感じで作っています。

実際に編集している箇所はここです。

````JSON
  "activationEvents": [
    "onCommand:sample.helloWorld"
  ],
  "main": "./dist/extension.js",
  "contributes": {
    "commands": [
      {
        "command": "sample.helloWorld",
        "title": "Hello World"
      }
    ],
    "configuration": {
      "title": "helloWorldSettings",
      "properties": {
        "sample.api": {
          "type": "string",
          "default": "",
          "description": "APIを設定してください"
        },
        "sample.databaseId": {
          "type": "string",
          "default": "",
          "description": "データーベースIDを設定してください"
        }
      }
````

`contributes`を追加して、「Hello World」というコマンドで、`extension.ts`に書かれた「helloWorld」関数を実行するようにしています。

設定ファイルの書き方は、[公式サイト](https://code.visualstudio.com/api/references/contribution-points#contributes.configuration)を参考に、良いところを盗みつつ職人気取りで書きました。

そして、実際のコマンドを書いた`extension.ts`はこちらです。

````ts
// モジュール読み込むから消して欲しくないでござる。
import * as vscode from 'vscode';

// 拡張機能が有効になったときに実行されるでござる。
export function activate(context: vscode.ExtensionContext) {
  // コマンドを書いて欲しいでござる。
  let disposable = vscode.commands.registerCommand('sample.helloWorld', () => {
    // ここからなんかしたいことを書くのでござる
    // 今回は設定で設定した値を取ってくるのでござるよ
    // （何を言っているのかよくわからんという苦情は受けつないでござる）
    // モジュール名を入れるでござる。package.jsonのnameから取れるでござるよ
    const config = vscode.workspace.getConfiguration('sample');
    // ここにconfigurationのプロパティを入れる　今回の場合は、api
    const configValue = config.get('api');
    const message = vscode.window.showInformationMessage(String(configValue), {
      modal: true,
    });
    // ここまで関数を書くのでござる。
  });

  // 拡張機能を無効化にした時のリソース解放に使うための設定でござる。
  context.subscriptions.push(disposable);
}

// プラグインを削除した時に使うコマンドでござるよ。
export function deactivate() {}
````

## デバッグモードの実行の仕方

さて実際にテストできるのか確かめたいですね。

vscodeに「Run Extension」という下部メニューに表示されているはずなので、出てなかったら右クリックでデバッグの表示にチェックすると良いでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304752/8fe1902d-9e30-c621-29f4-5b0cad7bf3be.png)

これを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304752/a19129ae-8e76-6372-0a31-a82c00540a33.png)


心のままに、Runします。

そうするとデバッグモードのVSCodeが出てきます。

コマンドでも、GUIでも構わないので設定に移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304752/8916768a-93c1-0d8c-7c7b-9e264cc3e7d4.png)

検索画面に「hello」と入力するとそれに応じたかのように、VSCodeさんは、helloの設定画面を返してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304752/fcb67db1-7150-ea23-1c3f-ba85d12b5fbf.png)

自分で好きに設定しておくと良いでしょう。

ここを空白にしていると、後で、空白で返されます。
（自分がしたことは自分の身に返ってくるということがわかりますね。）


さて、そんな感じで、ここまで設定して、「Ctrl + Shift + P」で「Hello World」を実行すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304752/751dc730-a677-bf78-f637-43a9ce5d1d1d.png)

ちゃんと値が返ってくることがわかりました。

## まとめ

設定ファイルを設定したのに、どうやって値を取得するのか悩んだ方はこれを機に悩みを解消させましょう。

私はこの設定をするのに二時間ほど悩んだ気がします。