File Tree Generator を公開【Visual Studio Code 拡張機能】

# VisualStudio Code の拡張機能を作成
Visual Studio Codeの拡張機能を作成してみました。
その名も　「**File Tree Generator**」
![filtree_icon.png](https://qiita-image-store.s3.amazonaws.com/0/113090/04698155-086e-3991-cf36-6103da7d651d.png)
[File Tree Generator](https://marketplace.visualstudio.com/items?itemName=Shinotatwu-DS.file-tree-generator#overview)


ファイル構成のツリーをテキストに起こしてくれる機能です。
（どんどん使ってくれよな！！）

## 経緯　　
qiita書くときとか、チョチョっとファイル構成を共有するときに、
「けいせん」と変換して下記の様に記述していました。


```
src
 ┣ test
 ┃ ┣ extension.test.ts
 ┃ ┗ index.ts
 ┗ extension.ts
```

いちいち「けいせん」と変換し、頑張って入力しても、これに時間割かれるのは不本意です。
そこで、ファイル構成のツリーを瞬時に作成してくれものが無いかと探したところ、
Macには「tree」というコマンドツールがある様です。

しかし、どうせならエディターで出力出来たら便利じゃん？と思い、
VisualStudioの拡張機能として作ってみることにしました。

## 使い方
![image.png](https://qiita-image-store.s3.amazonaws.com/0/113090/319fedc6-f8bd-e28c-d30b-a9f35aabcb9d.png)

1. VisualStudioCode に「file tree generator」をインストール
2. エクスプローラーでルートにしたいディレクトリを右クリックし「Generate to tree」を押す
3. ファイル構成のツリーが表示されるので好きにコピー＆ペーストするといい
![file-tree-generator-sample.gif](https://qiita-image-store.s3.amazonaws.com/0/113090/0c4a56b0-2866-b217-0251-d31eee0b60a2.gif)



## 作り方
下方に掲載している記事を参考にextensionsの作成に取り掛かりました。

### 作り始め
公式で作成に取り掛かるためのテンプレートが用意されているため、
インストールと実行から始めます。
以下は、公式のAPIドキュメントに掲載されているものです。
実際に手を動かす際は公式ドキュメントを参考にしてください。

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

extensionsのinitializeです。

```
yo code

# ? What type of extension do you want to create? New Extension (TypeScript)
# ? What's the name of your extension? HelloWorld
### Press <Enter> to choose default for all options below ###

# ? What's the identifier of your extension? helloworld
# ? What's the description of your extension? LEAVE BLANK
# ? Enable stricter TypeScript checking in 'tsconfig.json'? Yes
# ? Setup linting using 'tslint'? Yes
# ? Initialize a git repository? Yes
# ? Which package manager to use? npm

code ./helloworld
```

### 編集
展開されたテンプレートを元に、今回実装したい機能に向けて編集していきます。

カスタマイズしていく際にも、公式APIドキュメントを参考にしました。
https://code.visualstudio.com/api/extension-guides/overview

拡張機能を実行/開始させるには、コマンドに登録する必要があります。
package.json の`contributes` にコマンド名や実行方法、紐付ける機能などを記述していきます。

以下はFile Tree Generator での抜粋です。

```json
"contributes": {
    "commands": [
        {
            "command": "extension.generateTree",
            "title": "Generate to Tree"
        }
    ],
    "menus": {
        "explorer/context": [
            {
                "when": "explorerResourceIsFolder",
                "command": "extension.generateTree",
                "group": "cmdGroup@1"
            }
        ]
    }
},
```

extension.ts の冒頭の抜粋です。
注目頂きたいのは、`registerCommand` で指定する名称が、
package.json の`"command"` と同じにする事で拡張機能のコマンドを関連づけています。

```ts
'use strict';

import * as vscode from 'vscode';
const fs = require('fs');
const path = require('path');

export function activate(context: vscode.ExtensionContext) {

    let disposable = vscode.commands.registerCommand('extension.generateTree', (el) => {
        // directory and file ditective function
        let entryTrees = function (trgPath: string, deps: number) {
        :
        :
        }
    }
}

```

中身の編集については公式APIドキュメントを参考ください。
何度も公式・公式と言ってますが、公式は本当に参考になると思います。

### テストの実行
テンプレートを作成した時に、テストも含まれています。
作成時にMochaを使う様に選択していたので、Mocha用のsampleが作られています。

```
📦src
 ┣ 📂test
 ┃ ┣ 📜extension.test.ts
 ┃ ┗ 📜index.ts
 ┗ 📜extension.ts
```

extension.test.ts　にtestを記述していきます。
この機能ではtree がしっかりジェネレートされるかだけ見てます。
下記は一部抜粋です。

```typescript
import * as assert from 'assert';
import * as ext from '../extension';

suite("Extension Tests", function () {

    // Defines a Mocha unit test
    test("generate tree", function() {
        let result = ext.entryTrees(__dirname, 0);
        assert.equal(' ┣ <span………', result);
    });
});
```

テストの実行は、VS　codeのデバッグメニューから実行できます。
<img width="350" alt="スクリーンショット 2019-01-12 15.25.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/113090/2b1f66dc-445a-72a4-2ff8-83d2f527cdc6.png">
「extension test」を選んで実行するだけでtestされます。


### 留意点（自分がつまづいた事）
#### VS codeに他の拡張機能が入っていると干渉するものがある
python 系のlint やJupiter などの拡張機能が有効だとデバッグ出来ない事があリます。

#### import している `vscode` モジュールは、VS code自体のversion によって機能が色々と違う
`yo code` した時のVS Codeのversionによって、公式ドキュメントと同じ様に出来ない事があります。
自分は中身で`vscode.window.createWebviewPanel()`という関数を読んでいたのですが、１.29.1以降でないと含まれていない機能の様でした。
package.json のversionにお気をつけください。

```
"engines": {
    "vscode": "^1.29.1"
},
```

#### 拡張機能の実行方法はpackage.jsonで定義する
上述の`"contributes"` 内に`"menus"` を記述しています。
これは、ファイルエクスプローラ画面でcontext（つまり右クリックメニュー）に、
メニューとして追加しています。

コマンドパレットでの入力による起動がデフォルトになっていますが、
他にもウィンドウ下部のバーにボタンを追加したり、テキストエディターウィンドウ内で
右クリックメニューに追加したりと様々あります。

#### 公開がちょいと面倒
extensions　を公開する際は、package.jsonに公開情報を、
使い方やリリースノートなどをREADME.mdに記述して公開します。

公開する際は、コマンド入力でできるため、この様な準備が必要です。

```
# 例
$ vsce create-publisher example-developer
```

vsce コマンドが使えなかったりするので、その辺のパス通しや設定も必要になるかもしれません。
ですが、検索すれば簡単に見つかります。

公開方法の詳細は、下部の参考に載せている記事が大変重宝しますので参照ください。

#### source
https://github.com/sntw-5569/file-tree-generator


## 参考
▼作成にあたり参考にさせて頂きました。
[Visual Studio Code はじめての拡張機能開発](https://qiita.com/rma/items/8c53077d1355ab8fa4c6)
[Your First Extension（Official）](https://code.visualstudio.com/api/get-started/your-first-extension)

▼公開にあたり参考にさせて頂きました。
[VSCode 拡張機能を作って公開してみた : non-italic-monokai](http://neos21.hatenablog.com/entry/2018/05/05/080000)