sushi-buffetを支える技術
VSCode の背景にたくさんのお寿司を流す拡張機能を作りました。
twitter.comFlow Many Sushi on VS Code
— KC# (@kcpoipoi) 2019年5月2日
(拡張機能名: Sushi Buffet)
流れるSushi。CSSけっこうがんばった。マーケットプレイスに公開済 pic.twitter.com/9B6YGR6llc
言うまでもありませんが、完全なネタ拡張機能です。寿司だけに。
マーケットプレイスはこちら。
Sushi Buffet とは
お寿司大好きな IT エンジニアの皆様が、コーディング中でも常にお寿司のことを 忘れないようにするための拡張機能です。
大量のお寿司を VSCode の背景に流す。ただそれだけ。
アニメーションはすべて CSS で表現しています。
お寿司を流すのに必要な技術
- Node.js
- TypeScript
- CSS
- ちょっとしたシェルコマンドの知識
どうやってお寿司を流しているのか
VSCode では、背景を操作できる API が提供されていません。
そのため背景を編集するには、VSCode の画面を構成するworkbench.main.css
を直接編集する必要があります。
workbench.main.css とは
VSCode の各種パーツの表現を担当しています。 Windows における標準的なパスは次の場所のようです。
C:\Users\user\AppData\Local\Programs\Microsoft VS Code\resources\app\out\vs\workbench\workbench.main.css
記述が圧縮されているので、解読はあまりおすすめできません。
何をしたのか
シェルコマンド(sed
)でworkbench.main.css
の末尾に次のような記述を追加しました。
/*ext-sushi-buffet-start*/ body{ background-image: url(sushi_akami.png), ... /*寿司25種分のURIを列挙*/ url(sushi_uni.png); background-position: left top, 25% top, 50% top, 75% top, right top, ... /*25種それぞれの寿司についてポジションを設定*/ right 75%,left bottom, 25% bottom, 50% bottom, 75% bottom, right bottom; background-repeat:no-repeat; background-attachment:fixed; background-size:auto 20%; opacity:0.8; animation:slideIn 2.5s ease-in-out 1s 1 normal } @keyframes slideIn { 0% { opacity: 0.8; background-position: 100% top, 150% top, 150% top, 150% top, 150% top, ... /*25種それぞれの寿司についてポジションを設定*/ 150% bottom, 150% bottom, 150% bottom, 150% bottom, 200% bottom; 50% { opacity: 0.8; background-position: -200% top, 150% top, 150% top, 150% top, 150% top, 150% 25%, ... /*25種それぞれの寿司についてp(ry*/ 150% bottom, 150% bottom, 150% bottom, 150% bottom, -100% bottom; } 100% { opacity: 0.8; background-position: left top, 25% top, 50% top, 75% top, right top, ... /*25種それz(ry*/ left bottom, 25% bottom, 50% bottom, 75% bottom, right bottom; } } /*ext-sushi-buffet-end*/
シェルコマンドはどう記述したか
拡張機能開発は Node.js 上で行っているため、child-process
パッケージのexec
メソッドで実行しました。
import * as cp from 'child-process'; const delContent = `/\\*ext-${this.extName}-start\\*/.*/\\*ext-${this.extName}-end\\*/`; //1. 既に workbench.main.css が編集されている場合、一度追加部分を消す(s|${delContent}||) //2. 新しく文を追加する($a ${content}) //3. 空白行が発生するので消す(/^[<space><tab>]*$/d) //4. -i オプションを付加しているのでそのまま上書き(${this.mainCssPath}) cp.exec(`sed -i -e "s|${delContent}||g" -e "$a ${content}" -e "/^[<space><tab>]*$/d" "${this.mainCssPath}"`, (err, stdout, stderr) => { if (err) { console.log(err); } else { console.log(stdout); } });
${content}
には、先ほど提示した CSS の文字列を突っ込みます。
-e
で複数の条件を付けられるので便利ですね。
大変だったところ
- シェルコマンド全然わからん(
cd
とかls
くらいしかわからん)workbench.main.css
のパスをシェルコマンドの引数にしたら、Microsoft VS Code
の半角スペースで分割されてエラー吐いて詰む
$a
で挿入すると余計な改行コード入って反映されへん- 空白行の消し方わからん
workbench.main.css
に空白行が入るとちゃんと反映されない
- 拡張機能にリソースファイルを置いたときの取得方法わからん
- CSS 触ったことない
- ネット上に情報が無さすぎる
全体的に初めての試みが多すぎた開発でした。
感想
なんでわざわざシェルコマンドで挿入したのかといえば、
workbench.main.css
があまりにも長く、
「末尾に追記するだけなのに、プログラム上で中身取得する必要ないのでは?」
というイキり発想が降りてきたためです。
結果的にコマンドだけでコンパクトに構成できたので、 開発者的には満足です。
あと CSS アニメーションを Infinite とかにすれば永遠にお寿司流せるかも。