vscode-backgroundの背景画像をフォルダからランダムで画像表示できるように改造する

vscode には背景画像を表示して痛エディタ化する事が出来る拡張機能 [vscode-background](https://marketplace.visualstudio.com/items?itemName=shalldie.background) があるのですが、パネル3枚に設定した順番でしか背景画像を表示することが出来ません。
これだけだと面白味が足りないので、**コマンドで再起動**するたびに指定した**フォルダからランダムに背景画像を表示**できるように改造してみました。

![今回のカスタマイズを行うと背景画像をグループごとにまとめることが可能です。リスタートのコマンドを押すたびに違うアニメのランダム表示が楽しめます。](https://qiita-image-store.s3.amazonaws.com/0/293569/1ceb8a0f-e51e-36cf-7553-f294a9cc25f4.png)

### 記事修正

<font color="DodgerBlue"><b>2018/11/09</b>
新しくvscode全体にカバー画像を表示できるプラグイン [background-cover](https://marketplace.visualstudio.com/items?itemName=manasxx.background-cover) も追加されました。
こちらはカスタムせずにフォルダからランダムに画像を表示できる機能があるので、 [こちらの記事](https://qiita.com/hotsun/items/e83f89e26003867dc565) も参考にしてください。</font>

<font color="Blue"><b>2020/02/21</b>
アップデートで動かなくなっているみたいなので、全面的に書き直しました。
拡張機能のアップデートにも対応しやすい形に変更しています。
</font>




## vscode-backgroundのカスタム内容について

- フォルダから画像をランダム選択できるようにする(複数のフォルダ指定可)
- パス指定による画像設定も4枚以上可能にしてランダム選択できるようにする(フォルダ指定が優先です)
- 再起動のショートカットを設定してランダム切り替えをしやすくする

## オリジナルの拡張機能をインストール出来るようにする
インストールされている拡張機能をそのまま修正しても、拡張機能のアップデートでカスタマイズ内容がリセットされてしまうので、[vsixを使ったvscodeのアップデートに負けにくいCSSや拡張機能のカスタマイズ方法](https://qiita.com/BigFly3/items/495994f0443d85eadb7d)を参考にして独自の拡張機能を作ってからカスタマイズをしていきます。
※すでにvscode-backgroundをインストールしている場合はアンインストールしてください。

### 1. マーケットプレイスでvscode-backgroundのvsixをダウンロードする
   [vscode-background](https://marketplace.visualstudio.com/items?itemName=shalldie.background)のページの右にある、【Download Extension】からダウンロードします。

![market.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293569/3de9b55c-1870-cd1b-820a-01a0514e17db.jpeg)


### 2. ダウンロードしたvsixを解凍する
中身はZIPなので普通の解凍ツールで解凍できます。

### 3. package.jsonを修正する
オリジナルの拡張機能にするため最低限 【name】か【publisher】を変更します。
以下は参考例です。

```json:解凍したフォルダ/extension/package.json
{
    "name": "background-random-customize",
    "displayName": "background-random",
    "description": "痛エディタをより楽しむためのカスタマイズ",
    "version": "1.1.23",
    "publisher": "hotsun",
    "author": "shalldie",
    //省略 
}
```
### 4. 再度ZIP化してvsixを作る
以下の画像のように3つを選択してZIPファイルを作り、拡張子をvsixにします。

![vsix.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293569/b33353cc-ad67-221f-6be2-4560a00b128c.jpeg)

    【extention.zip】→【extention.vsix】

カスタマイズ時に、また同じ作業をするので名前は適当で大丈夫です。



### 5. 作ったvsixをインストールする
vscodeの拡張機能パネルを開き、右上からメニューを開き【vsixからインストール】で先ほどのvsixをインストールします。

![拡張機能パネル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293569/5a6dcc4f-f55e-95b4-6421-2bf362c94a0f.jpeg)

こんな感じでオリジナル拡張機能としてインストール出来ます。
このファイルをカスタムベーズとして修正し、vsixを再インストールすることで更新していきます。

## 背景画像をランダム選択するカスタマイズ手順
複数の画像ファルダからランダムに１つのフォルダを選択し、その中から画像をランダムに取得できるようにします。
複数のパネルにランダム表示した場合、画像の種類に統一性がないとバランスが悪いのでフォルダごとにカテゴライズするのが目的です。

### 1. background.jsの2箇所を修正する

if (!config.useDefault)のところをthis.getImageList()を呼ぶように修正する

```javascript:shalldie.background-1.1.23/extension/out/background.js
    install(refresh){
        ... 略
        // 5.hack 样式
        let arr = []; // 默认图片
        if (!config.useDefault) { // 自定义图片
            //arr = config.customImages;
            arr = this.getImageList();  //getImageList()を呼ぶように修正
        }
        ... 略
    }
```

install(refresh)の後ろにthis.getImageList()を追加する

```javascript:shalldie.background-1.1.23/extension/out/background.js
    install(refresh){
        ... 略
    }
    //install()の後に追加する
    getImageList() { 
        let config = this.config;
        let folders = config.customImageFolders;
        let arr = [];
        if (folders.length > 0) { //フォルダの設定があればランダムで一つ選択
            let fdpath = folders[Math.floor(Math.random() * folders.length)];
            let files = fs_1.default.readdirSync(path_1.default.resolve(fdpath));
            files.filter((s) => {
                return s.endsWith('.png') || s.endsWith('.jpg') || s.endsWith('.jpeg') || s.endsWith('.gif') || s.endsWith('.webp') || s.endsWith('.bmp');
            }).forEach((file) => {
                arr.push(path_1.default.join(fdpath, file).toString().replace(/\\/g, '/'));
            });
        } else { //なければ既存のcustomImagesから画像を取得
            arr = config.customImages;
        }
        if (config.useRandom) { //ランダム使用モードなら並び替え
            for (let i = arr.length - 1; i > 0; i--) {
                let r = Math.floor(Math.random() * (i + 1));
                let tmp = arr[i];
                arr[i] = arr[r];
                arr[r] = tmp;
            }
        }
        return arr;
    }
```
※install()に直接かける内容ですが、他でも呼び出したい内容なので別にしています。

### 2. package.jsonに新しいコンフィグを追加する
background.customImagesの下にuseRandomとcustomImageFoldersを追加

```json:shalldie.background-1.1.23/extension/package.json
"background.customImages": {
    "type": "array",
    "default": [],
    "description": "Your custom Images. 自己定制背景图"
},
"background.useRandom": {
    "type": "boolean",
    "default": false,
    "description": "Use random order."
},
"background.customImageFolders": {
    "type": "array",
    "default": [],
    "description": "Your custom image folders. (selected randomly) "
}
```

### 3. 再度zip化でvsixを作成しvscodeに再インストールする
ここまで出来たらランダムカスタマイズが出来るようになっているのでvsixを作って、もう一度インストールします。
インストールしたら右下の【今すぐ再度読み込む】で再起動します。


### 4. vscodeの基本設定(setting.json)にbackgroundのセッティングを追加する
【ctrl + shift + p 】でコマンドパレットを開き、**Preferences:Open Settings(JSON)**を検索してsetting.jsonにbackgroundの設定をします。
※今回拡張機能の名前を変更していますが、configはbackgroundのままなので、以前の設定があればそのまま流用出来ます。

```json:【vscode】setting.json
"background.useDefault": false, //デフォルトの画像(東方の画像)を使いたい場合のみ true 
"background.enabled": true, //背景画像を非表示にしたい場合はここを false にする
"background.useFront": true, //背景画像をミニマップなどの上に持ってくるかどうか（テキスト選択は出来る）
"background.useRandom" : true, //ランダムに並び替えるかどうか（ false だとフォルダは名前順）
//拡張機能標準の画像設定パス　以下のパスパターンいづれかで記述　ランダムにしたい場合は４つ以上も可
"background.customImages": [ 
    "/path/to/folder/img01.png",
    "C:/path/to/folder/img02.png",
    "file:///C:/path/to/folder/img03.png",
],
//画像が置いてあるフォルダパス　以下のパスパターンいづれかで記述　customImagesより優先される
"background.customImageFolders": [ 
    "c:\\path\\to\\folder\\",
    "c:\\path\\to\\folder",
    "c:/path/to/folder/",
    "c:/path/to/folder",
    "/path/to/folder/",
    "/path/to/folder",
],
"background.style": {//背景共通のcss
    "content": "''",
    "pointer-events": "none",
    "position": "absolute",
    "z-index": "99999",
    "width": "100%",
    "height": "100%",
    "background-position": "100% 100%", //右下
    "background-repeat": "no-repeat",
    "background-size": "auto 40%", //coverとか好みで設定する。例は右下に高さ40％の基準で設置
    "opacity": 0.3  //透過設定 デフォルト画像は透過が入ってるので opacity:1でも良い
},
```

右下のボタンから再起動するとフォルダから画像をランダム表示できるようになっていると思います。上手くいかない場合は再度確認してください。


## ショートカットコマンドから再起動して背景画像を切り替えできるようにする

ここまでのカスタマイズだけだと、設定を何かしら修正して右下のボタンから再起動しないと画像が切り替わりません。
せっかくランダム表示出来るようにしたので、ショートカットから再起動できるようにします。

#### 1. background.jsにrefresh用の記述を追加する
先ほどのgetImageList()の下に以下を追記

```javascript:shalldie.background-1.1.23/extension/out/background.js
    getImageList(){
        ... 略
    }
    refresh() { //installの処理からメッセージを出さずrestart出来るようにしたもの
        let config = vscode_1.default.workspace.getConfiguration('background'); 
        this.config = config; 
        if (!config.enabled) {
            this.uninstall();
            vscode_1.default.commands.executeCommand('workbench.action.reloadWindow');
            return;
        }
        let arr = []; 
        if (!config.useDefault) { 
            arr = this.getImageList();
        }
        let content = getCss_1.default(arr, config.style, config.styles, config.useFront).replace(/\s*$/, ''); 
        let cssContent = this.getCssContent();
        cssContent = this.clearCssContent(cssContent);
        cssContent += content;
        this.saveCssContent(cssContent);
        vscode_1.default.commands.executeCommand('workbench.action.reloadWindow');
        return;
    }
```

#### 2. extension.jsにrefresh()をコマンドから呼び出せるよう登録する

activate()の一番下にrefreshコマンドを追記

```javascript:shalldie.background-1.1.23/extension/out/extension.js
    activate(){
        ... 略
   //refreshコマンドを追加
    const disposable2 = vscode_1.default.commands.registerCommand( 'extension.background.refresh', () => background_1.default.refresh() );
    context.subscriptions.push(disposable2);
    }
```

#### 3. package.jsonにコマンドとショートカットを追記する
**commands** 部分にrefreshを追加して、その下に **keybindings** も追加します。
※ショートカットの **key** は自分が使いやすいように設定してください。

```javascript:shalldie.background-1.1.23/extension/package.json
    "commands": [
        {
            "command": "extension.background.info",
            "title": "Background - Info"
        },
        {
            "command": "extension.background.refresh",
            "title": "Background - Refresh"
        }
    ],
    "keybindings": [
        {
            "command": "extension.background.refresh",
            "key": "ctrl+shift+f6"
        }
    ],
```

#### 4. 再度zip化でvsixを作成しvscodeに再インストールする
【今すぐ再度読み込む】で再起動後、ショートカットが動作すれば完成です。

### 注意点
- 拡張機能自体の仕様なのですが本体のCSSが修正される仕組みなのでシステムが壊れているというメッセージが出ます。  
    → これはメッセージ上の歯車を開き、【今後表示しない】を選ぶと本体のアプデまで非表示可能です。![break-editor2.png](https://qiita-image-store.s3.amazonaws.com/0/293569/cec5d661-310e-c6ca-b391-830bbd2a4545.png)

### 最後に

同じ要領でカスタマイズしていくことで、さらにオリジナルのカスタマイズを試すことが出来ると思います。
お好みで全部日本語化してみたり、CSSのカスタマイズを追加したり色々お試しください。
今回の修正には入れていませんが、getCss.jsを弄ればのパネル4枚以上の場合の表示を追加したみたり、コンソールパネルにも画像出したりとかも出来ると思います。