VSCode のコマンドラインについてちょっとだけ書く

はじめに

これは Visual Studio Code Advent Calendar 2016の9日目の記事です。

VSCode について何か書こうと、自分に使命を課すように、アドベントカレンダーに登録したものの、実際には何について書こうと悩んだあげく、ヌルい内容になってるかもしれませんが(だって、今 12/8 22:00なんだもん、さすがに何か書かないと!)、温かい目で読んで頂けるとありがたいです。

VSCode のコマンドライン

VSCode をインストールすると、 code というコマンドがインストールされ、さらに既定ではパスも通されることは、インストーラを見ていれば分かると思いますが、 code コマンドをどこまで使いこなしているでしょうか?

code コマンド

Windows だと、 C:\Program Files (x86)\Microsoft VS Code\bin には、 code.cmd と、 cmd というファイルが存在しています。

f:id:espresso3389:20161208222142p:plain

普通に、いろんな所から code って叩いて起動するのは、当然、 code.cmd なんですが、 code とは? ってなりますよね。で、これは、本来、 node とか npm 系の文化なんでしょうけど、 Cygwin もちゃんとサポートするぜ的な感じでシェルスクリプトが提供されてるんですね。 とはいうものの、実は、 Windows 10 Insider Preview Build 14951 以降の WSL (Bash on Windows) だと、 code ってコマンドを打つと、こっちのシェルスクリプトが実行されて、 VSCode が起動します・・・が、残念ながらパスの解析ができないので、カレントディレクトリのファイルをファイル名だけで指定した場合以外はファイルを開くことは出来ません。 さらに、cli.js というファイルを新規で開いてしまいます。

さて、とりあえず、 --help の内容でも見てみましょう。

Visual Studio Code 1.7.2

Usage: code.exe [options] [paths...]

Options:
  -d, --diff                  Open a diff editor. Requires to pass two file
                              paths as arguments.
  -g, --goto                  Open the file at path at the line and column (add
                              :line[:column] to path).
  --locale <locale>           The locale to use (e.g. en-US or zh-TW).
  -n, --new-window            Force a new instance of Code.
  -p, --performance           Start with the 'Developer: Startup Performance'
                              command enabled.
  -r, --reuse-window          Force opening a file or folder in the last active
                              window.
  --user-data-dir <dir>       Specifies the directory that user data is kept
                              in, useful when running as root.
  --verbose                   Print verbose output (implies --wait).
  -w, --wait                  Wait for the window to be closed before
                              returning.
  --extensionHomePath         Set the root path for extensions.
  --list-extensions           List the installed extensions.
  --show-versions             Show versions of installed extensions, when using
                              --list-extension.
  --install-extension <ext>   Installs an extension.
  --uninstall-extension <ext> Uninstalls an extension.
  --disable-extensions        Disable all installed extensions.
  --disable-gpu               Disable GPU hardware acceleration.
  -v, --version               Print version.
  -h, --help                  Print usage.

このコマンドラインのオプションについては、1.8.0 系(VSCode Insiders)でも、--extensionHomePath--extensions-dir に変わっているだけで、特に変更はないようです。

code --diff

code に引数として、ファイル名を渡して開くというのを除けば、もっとも利用価値がありそうなのは、 --diff オプションでしょう。CUI 大好き人間でも、ターミナル上で diff を読み解くのはさすがに辛いので、こういうときはグラフィカルなエディタの登場価値は大いにあります。

ここでは、上で説明した、オプション一覧の差分でも見てみますか。

code --diff .\stable.txt .\insiders.txt

バージョンが異なること、VSCode Insiders のコマンド名は、 code-insiders であること、あとは、先ほど言及した、 --extensionHomePath が変わったことなどが直ぐに分かると思います。

で、 VSCode の diff の素敵なのは、2個目のファイルの方(通常、新しい方)をその場で修正しながら差分を確認できる所なんですよね。これは便利(いや、他のエディタにもこの機能がある奴は知っていますけど・・・)。

f:id:espresso3389:20161208222204g:plain

code --list-extensions

--list-extensions はインストールされている拡張の一覧を「表示」します。

PS C:\Users\kawasaki\Desktop> code --list-extensions
abusaidm.html-snippets
austin.code-gnu-global
cssho.vscode-svgviewer
...

敢えて、「表示」を強調したのは、つい最近まで、本当に、「表示」しか出来なかったんです。 要は、リダイレクト出来ませんでした。 Issue としては、

Strange CLI behavior: CLI does not seem to write to either stdout (FD 1) or stderr (FD 2), making output impossible to redirect. #8585

で、この問題は実は、Electron の問題で、

Windows stdout writes directly to console and cannot be captured #4552

に影響を受けていました。で、この問題は既に直っており、どうやら、VSCode にも反映されている様です。「様です」というのは、実際、現状の安定版(1.7.2)ではちゃんとリダイレクトできるようになっているのですが、この Issue は close されてないという意味ですね。

で、リダイレクトしたかった理由は、それが出来ると、設定のバックアップをするスクリプトが書けるようになるからですね。 本来なら、 Dropbox で自動バックアップ!とか言いたいんですが、それをやると結構な頻度で、複数マシン間の競合とか発生して誰も幸せにならないので、最近は、自分の好きなタイミングでスクリプト実行の方が良いと思っています。

Code の設定をバックアップ

バックアップのバッチファイル(!)はこんな感じです。僕は基本的に、Windows の人なのでこれで十分なんですが、まぁ、 bashスクリプトを書くのも全然難しくないはずです。

@echo off

set CURDIR=%~dp0
set PROGDIR=%ProgramFiles(x86)%\Microsoft VS Code
set APPNAME=Code
set EXENAME=%PROGDIR%\bin\code
set VSCODEDIR=%APPDATA%\%APPNAME%\User
set CONFIGDIR=%CURDIR%\config

mkdir "%CONFIGDIR%" 2>NUL
copy /Y "%VSCODEDIR%\*.json" "%CONFIGDIR%"

call "%EXENAME%" --list-extensions > "%CONFIGDIR%\extensions.txt"

これを実行すると、 VSCode 安定版の設定と拡張の一覧「だけ」をバックアップします。 設定ファイル群は、

%APPDATA%\Code\User\*.json

をバックアップすればバックアップできますが、動的なデータは、sqlite の DB 的な奴で管理されています。 この辺もバックアップしても良いのでしょうが、バージョン間のデータ整合性とか、様々な事を勘案するとあまり積極的にバックアップすべき物ではない気がします。

ただし、DB 類をバックアップしないと、カラーテーマの設定などは保存できないようです。 この辺も .json に保存して欲しいんですけどね。

Code の設定をリストア

リストア側は、もうちょっと面倒です。 最後の for /f ... の部分で、 --install-extension というオプションを利用して、バックアップ時にインストールされていた拡張を一つずつインストールし直しています。もちろん、既にインストールされている拡張は普通にスキップされるので特に問題にはなりません。

@echo off

set CURDIR=%~dp0
set CONFIGDIR=%CURDIR%\config

set PROGDIR=%ProgramFiles(x86)%\Microsoft VS Code
set APPNAME=Code
set EXENAME=%PROGDIR%\bin\code
call :copy_files

goto :EOF

:copy_files
if not exist "%EXENAME%" goto :EOF

set VSCODEDIR=%APPDATA%\%APPNAME%\User
copy /Y "%CONFIGDIR%\*.json" "%VSCODEDIR%"

for /f %%e in ('type "%CONFIGDIR%\extensions.txt"') do (
    call "%EXENAME%" --install-extension %%e
)
goto :EOF

あとがき

まぁ、人と被らない内容を考えた結果、微妙にヌルい内容になってしまったので、これでどの程度、人の参考になるのかは未知数ですが、VSCode を活用するには是非とも知っておいた方が良い内容だと思います。多分。

で、 VSCode の安定版に関しては、実は、ちょうど、今日明日ぐらいで、 November/December Iteration Plan のコードフリーズって何それ?って感じですが、要はそろそろ、新しい VSCode の安定版がリリースされるって事です。

November/December Iteration Plan #15099

本当は、Iteration Plan っていうのは、月ごとになってて、いつも通りなら、VSCode の安定版は、各 Iteration Plan 完了後にリリースされる感じなんですが、あちらの国では、12 月後半はほとんど休みなので、12 月単独の Iteration Plan っていうのは、意味がないわけですね。なので、11 月の Iteration Plan は、ちょっとだけ長くなっています。

なので、来週末(向こうの日付で15日/16日) or 再来週の初めぐらいには、今年最後の VSCode 安定版がリリースされることになるでしょう。

この新しい安定版には、普通の人にも分かりやすいところで言うと、

  • カラー絵文字が使えるようになる
  • hotexit という、VSCode 終了時に編集中のファイルを明示的に保存しなくてもバックアップしてくれて、次回起動時に自動的に復帰してくれる機能
  • 設定ファイルの編集支援機能(かなり強力!)

などが導入される予定です。

絵文字がカラーになるので、拙作のsushi-vscodeで🍣を眺めて楽しんでくれると非常に嬉しいです。