monolithic kernel

Visual Studio Code の拡張機能を複数の環境で同期する

シェルやエディタの設定を Git で管理して、複数の環境で簡単に同期できるようにしている人は多いと思う。その流れで、Visual Studio Code (VSCode) の設定や拡張機能も同期したいと思い調べてみたところ、設定はすんなり同期できたもの、拡張機能については標準ではできなさそうだった。

ただ、CLI で拡張機能をインストールする仕組みは用意されていることがわかった。以下のように、インストールされている拡張機能の確認、インストール、アンインストールできる。

% code --list-extensions
jebbs.plantuml
MS-CEINTL.vscode-language-pack-ja
ms-python.python
ms-vscode.cpptools
ms-vscode.Go
rebornix.ruby
redhat.vscode-yaml
vscodevim.vim
vscoss.vscode-ansible
Zignd.html-css-class-completion
% code --install-extension vscodevim.vim
Installing extensions...
Installing extension 'vscodevim.vim' v1.8.1...
Extension 'vscodevim.vim' v1.8.1 was successfully installed.
% code --uninstall-extension vscodevim.vim
Uninstalling vscodevim.vim...
Extension 'vscodevim.vim' was successfully uninstalled!

詳細なドキュメントは以下にある。

これらを利用し、拡張機能を同期する仕組みを自分で書いてみた。save-extensions でインストールされている拡張機能を extensions.txt に書き出しておいて、sync-extensionsextensions.txt に記述されている内容を VSCode の状態を同期する。具体的には、インストールされていない拡張機能があればインストールし、逆に記述されていないのにインストールされている拡張機能は削除する。

#!/bin/sh
# save-extensions
code --list-extensions | sort > "$(cd "$(dirname $0)"; pwd)/extensions.txt"
#!/usr/bin/env ruby
# sync-extensions
require 'set'

installed_extensions = Set.new(`code --list-extensions`.lines.map(&:chomp))
saved_extensions = Set.new(open("#{File.dirname $0}/extensions.txt").each_line.map(&:chomp))

install_extensions = saved_extensions - installed_extensions
uninstall_extensions = installed_extensions - saved_extensions

unless install_extensions.empty?
  system 'code', *install_extensions.map {|e| ['--install-extension', e]}.flatten
end

unless uninstall_extensions.empty?
  system 'code', *uninstall_extensions.map {|e| ['--uninstall-extension', e]}.flatten
end

書いてみて、ここまでのものが必要なのかと我に返ったが、CLI で拡張機能まわりをいじれること自体は便利なので、簡単なスクリプトを書くと管理が楽になるとは思う。