本当にわからない VSCode の設定

この記事は [eeic アドベントカレンダー](https://qiita.com/advent-calendar/2019/eeic) 16 日目の記事です。

# VSCode わからん

VSCode 全然わからん。

この記事は Atom が大好きなのにメンテモードになってしまいそのうえ Atom おもすぎてそろそろしんどくなってきた僕が VSCode を使って得た感想と、おすすめの VSCode との向き合い方を紹介する記事です。

VSCode は公式ドキュメントが充実しているので、公式の [Tips and Tricks](https://code.visualstudio.com/docs/getstarted/tips-and-tricks) のページを読んでおくと幸せになれることが多い。
まずは公式ドキュメントを読め（なおこの内容は結構かぶっている模様）。

Cmd+D（同名選択）とか矩形選択とかすら使えずに VSCode 使うのはもったいないので、ちゃんと公式ドキュメントを 1 日かけて読むべき。ちなみに同名選択をやりすぎたときは Cmd+U で戻れる。

普通のことを書いても仕方がないので、誰でも書ける普通のことは書きません。

# チャンネル

Stable ビルドと [Insider ビルド](https://code.visualstudio.com/insiders/)がある。環境分離した状態で共存できる。

Remote Development など近未来的な一部の拡張は Insider の方でしか使えなかったりするので、Insider を使っている人も多いかも。

ただ Insider はめちゃくちゃアップデートが多い上にときどきそこそこ致命的なバグがあったりするので、そういう（挙動がおかしくて）絶叫（しちゃう）マシンみたいなのに耐えられる人にしか（個人的には）オススメできない。

僕は絶叫マシン大好きなので Insider ビルド。ブラウザは Chromium Edge Canary。Safari も Technology Preview。みんなも乗ろうぜ絶叫マシン。

ちなみに Remote Development は最近（半年前くらい）Stable 版でも使えるようになったらしい。もう Insider ビルドはやめよう。

# VSCode はエディタである

巷の VSCode 記事には、何か拡張を入れると最強になるもう IDE いらん俺は VSCode と生きていくみたいなことが書いてある記事もあるが、所詮 VSCode は Emacs や vim と同様本体も拡張もオープンソースのテキストエディタなので、IDE ではない。

本体自体もよくできているし拡張性も高く便利な拡張はいっぱいあるが、所詮はテキストエディタなのでテキストを編集する以外の機能はおまけと思って期待せずに使うほうがよいし、意外と拡張自体の設定も難しい。
ちゃんとしたデバッグとか補完とかを求めるなら、Visual Studio とか JetBrains のソフトとかを入れたほうが、きっともっとずっといろんな景色が見える。

私が初めて触った IDE は NetBeans 3.5.1 で、そのとき私は小学校低学年でした。ただし IDE でも Eclipse お前だけはダメだ。

# コマンドパレットはすべての基本

Atom 同様すべてのコマンドは、Command(Ctrl)+Shift+P からアクセスできる。これさえ覚えておけばショートカットキーを覚える必要はないし、開いたコマンドパレットにショートカットキーが書いてあるので覚えたければそこから覚えられる。
まあ実際コマンドパレットとかいうのも所詮たかだか有限個のコマンドしか並んでいないので、これも全部見たほうがいい。うそです。

ショートカットキーの一覧もある。Cmd+K Cmd+Sで出せる（さすが Visual Studio の姉妹らしく、2 つのショートカットキーの連続をショートカットキーとして扱えるようになっている）。ここからキーバインドの編集もできる。もちろんコマンドパレットから Open Keyboard Shortcuts とかしても出せる。

# Shell command

コマンドパレットから、code（もしくは code-insiders）というコマンドを PATH に追加してくれるという機能が使える。

だが、アプリケーションの中に入っている code コマンド（mac だと `/Applications/Visual\ Studio\ Code\ -\ Insiders.app/Contents/Resources/app/bin/code` とか）にエイリアスを貼ったほうがたぶん早い。同じ機能が使える。

# VSCode の設定

VSCode って結構カスタマイズできるように見えて、Chrome みたく本当にカスタマイズしたい場所は全然カスタマイズできなかったりするんだよな。

## 設定の仕方

本体は JSON だが、別に GUI でもおよそ設定できるので、そちらでもよい。
いっぱい設定項目があるので、朝から晩までアニメでも見ながらすべての設定を眺めるとときどき便利な設定に遭遇するかもしれない。
JSON は GUI の設定を開いたときに右上に出るなんか紙をひっくり返しそうなアイコンをクリックすると開ける。もちろんコマンドパレットから（ry

VSCode の設定の本体は、なんか闇が深そうなユーザディレクトリにある settings.json というファイル。Mac だと `~/Library/Application Support/Code/User/settings.json` とか。
Atom はすべて `~/.atom` にあったが、**VSCode の場合は `~/.vscode` だけでは環境の複製が完結しない**。こちらのディレクトリには拡張の本体と起動時引数の情報（argv.json）が入っている。
ちなみに拡張はディレクトリをリストしているだけっぽいので、`~/.vscode` に加えて設定ファイルのあるディレクトリをコピーすればたぶん環境を移せる。
環境設定を同期できる拡張もあった気がする。

JSON は単純な key-value になっていて、key は . 区切りで階層的になっている。value 側は配列でもオブジェクトでも文字列でも数値でも null でもなんでも構わない（仕様による）。

```json
{
    ... // いっぱいある
    "latex-workshop.latex.tools": [
        {
            "args": [
                "%DOC%.tex"
            ],
            "command": "houcluttex",
            "env": {
                "PATH": "/Users/ishotihadus/.rbenv/shims:/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin"
            },
            "name": "houcluttex"
        }
    ],
    ... // いっぱいある
}
```

設定として無意味な部分（その設定を使うものがない場合）は、その部分がちょっと暗くなって教えてくれる。

特別な key として、言語依存設定がある。言語の名前を `[ ]` で囲むことになっている。

```json
{
    ... // いっぱいある
    "[ruby]": {
        "editor.tabSize": 2
    },
    ... // いっぱいある
}
```

言語名は、画面右下の言語名の部分をクリックして言語一覧を表示したときのカッコ内に書いてある文字列を使うらしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78668/57db7134-3c98-beec-bf1a-22ad732f4109.png)

JSON を書くときはキー名の補完が効いて解説も教えてくれるが、言語の名前だけは補完に表示されないものがあるっぽいので注意する。

また、言語依存設定は GUI では設定できない気がする（ので結局 JSON を書く能力を求められる）。

デフォルト設定は [Getting Started のページ](https://code.visualstudio.com/docs/getstarted/settings)にすべて書いてある。Getting Started したい人たちに対してちょっと厳しくないか。

ちなみにこの JSON はコメントなど若干拡張記法も使えるらしい。

## 設定ファイルのソート

いっぱい設定すると JSON ファイルがめっちゃグチャグチャになって涙がひと粒も出なくなって心がこわれそうになるので、[Sort JSON objects](https://marketplace.visualstudio.com/items?itemName=richie5um2.vscode-sort-json) をインストールして Sort JSON (by alphanum) とかを走らせると幸せになれる（コメントは吹っ飛ぶ）。

## おすすめ設定

おすすめ設定とかいうの、完全に個人の趣味だし、読者である君が自分で全部の設定を上から下まで見ていったほうが多分いい。

フォントとか誰でも思いつきそうなのは省いている。
ちなみにフォントは [Cica](https://github.com/miiton/Cica) がおすすめ。Powerline も使えるので端末でも使える。

### ファイルの拡張子と言語の関係を変える

Files: Associations。GUI では設定できないので JSON から設定する。稀に使う。

```json
    "files.associations": {
        "*.m": "matlab"
    },
```

### でかいファイルを扱うやつ

デフォルトはユーザを守るように設計してあるので、変える場合は自己責任で。

Files: Max Memory For Large Files MB（`files.maxMemoryForLargeFilesMB`）をでかくすると、ファイルを開くときにめっちゃじゃぶじゃぶメモリを使わせられるようになる。デフォルトでも 4096 なので結構でかいけど。

Editor: Large File Optimizations（`editor.largeFileOptimizations`）をオフにすると、ドナルド・トランプの態度くらいでかいファイルでもシンタックスハイライトなどが動くようになる。VSCode のデフォルトは冷静なので、大きなファイルを食らうと無視するようになっている。このオプションをオフにするとマジでデカいファイルでも愚直に処理しだして危険なので、絶叫マシンにはもってこい。

### Extension のリコメンドを消す

Extensions: Ignore Recommendations（`extensions.ignoreRecommendations`）をオンにする。リコメンドが出た瞬間にうるせえもう二度と出てくんなボタンを押しても設定できる。

### フォーカスのない状態でクリックされたときの判定をマシにする

Window: Click Through Inactive（`window.clickThroughInactive`）をオフにする。

デフォルトだとウインドウにフォーカスがない状態でも、クリックするとボタンやカーソルなどの当たり判定を受けてしまい、意味もなくただ時を潰えたサンドグラスになってしまうので、クリックしてもフォーカスだけをもらってクリック自体の影響がでないようにできる。

## キーバインド

キーバインドも同様に設定できる。GUI もあって、こちらも実体は JSON になっている。

VSCode のキーバインドは若干意味不明で、Mac だとタブの切り替えが Ctrl+数字になっていたり気持ち悪いところがある（ブラウザや Atom はすべて Cmd+数字）。
そういう人のために、なんとびっくり公式から [Atom のキーバインドにする拡張](https://marketplace.visualstudio.com/items?itemName=ms-vscode.atom-keybindings)がリリースされており、しかも意外とちゃんとメンテされている。
ちなみに Sublime Text キーバインドも公式からリリースされている（そんなテキストエディタ覚えてるやついるか?）。

なお[実はこっそりキーバインドのチートシートを公式が pdf で配布している](https://code.visualstudio.com/docs/getstarted/keybindings#_keyboard-shortcuts-reference)。VSCode の公式は最強。

## 設定できないもの

設定したいのにできないもの。

- カスタム JS
    - 拡張から以外は実行できないはず
- カスタム CSS
    - 最適化のためビルド済みの CSS 以外は読み込めないらしい（色だけはテーマとして変えられる）
    - そのためカスタム CSS が使える拡張はアプリケーション本体を書き換える方法をとっている
- 初期ウィンドウサイズ
    - 最大化、フルスクリーン、前と同じ、デフォルトくらいしか選べない
    - デフォルトの位置とサイズは変えられない

# Remote Development

VSCode の最強にして最凶の拡張。
ssh 先もそうだが、WSL や Docker などのコンテナに対しても、接続先の環境にまるで VSCode を置いたかのような使い方ができるようになる。非常に便利。

ちなみに、Remote Development という拡張はただの SSH / Containers / WSL の 3 種類セットをインストールするだけの拡張なので、普通はそれぞれ必要なものだけをインストールすればよい。

## 仕組み

実体は、ホスト側に .vscode-server などという怪しいディレクトリを作り node を始めとしたバイナリを流し込みたった 65536 個しかないポートの 1 つを勝手に奪い（内部でポートフォワーディングをしているらしい）、メモリと CPU をバカ食いする node のサーバを建てるという凶悪な仕様になっている。
しかもなんと最高なことに、向こうのサーバでダウンロードに失敗するとこちらでダウンロードして scp して注ぎ込む仕様にすらなっている（設定で変えられる）。鬼か。
**ssh ができるからといって Remote Development でアクセスするのは最高にマナーがない行為なので、接続先に十分なリソースの余裕があることを確認してから（あるいは管理者の許可を得てから）使うべきである**。
Google Compute Engine の f1-micro とかにやるのは普通にやめたほうがいい。

## 設定・拡張の扱い

ワークスペース設定＞リモート設定＞ユーザ（手元）設定の順に優先される。
なので、linter のパスをリモートと手元で別々にするみたいなことももちろんできる。
リモート設定は .vscode-server のディレクトリを適当に掘ったとこに作られる。

拡張は、手元と共有する拡張とそうでない拡張に分類されて、後者は明示的に入れないと拡張としては利用できない。
テーマやシンタックスハイライトなどの UI 系拡張は共有拡張、C/C++ 拡張などコンパイル・デバッグが走ったりコマンドを呼び出す必要がある拡張は分離拡張になる（拡張内のタグで決まっている?）。
分離拡張だけでなく共有拡張もリモート設定ができるらしい。

## Remote - SSH

ssh で使う場合は ssh の config を使うようになっているので、ワイルドカードのホスト名の設定とかもちゃんと反映されるらしいのだが、Host で明示されていないホストはリストに載らないので、以下のような虚無な config を書いておく必要がある（ssh config は先に書いたものが優先されて、後に同じオプションが出てくるときは無視されるので、これは正しく動作する）。

```ssh_config
Host wild*
    User ishotihadus
    Port 12345
    ProxyCommand ssh fumidai-server nc %h %p

Host wild01
    HostName wild01
```

# おすすめ言語別設定

リコメンドされてるときもあるが、どういう根拠でリコメンドしているのかよくわからない。

## C/C++

公式から出ている C/C++ の拡張を入れるだけでだいたい事足りる。

### 設定

ワーキングディレクトリに .vscode のディレクトリを作ってそこにコンフィグが書ける。
C/C++ Configuration みたいなのをコマンドパレットから実行すると、GUI でコンフィグが書けたりする。

ただ、いちいち書くのも面倒だし、勝手にディレクトリを追加されるのも癪に障るので、C_Cpp.default 系の設定をあらかじめしておく（特に includePath）とラク。

### フォーマット

コードのフォーマットも効くが、これは clang-format に準拠している。
~/.clang-format に設定を書いてもいいし、`C_Cpp.clang_format_style` に直接書いてもよい。
デフォルトのフォーマットは Visual Studio になっているが、個人的にあまり好みではないので Google をベースにチューニングしてある。デフォルトなら WebKit が好きかな。
[clang-format をチューニングするツール](https://zed0.co.uk/clang-format-configurator/)もあるので使うとよい。

VSCode は独自に clang-format の実装を持っているが、最新の設定に対応できていなかったりするので、clang-format を別途入れて `C_Cpp.clang_format_path` でパスをしておくほうがおすすめ。

以下は僕の .clang-format。VSCode 内部の clang-format は `AllowShortIfStatementsOnASingleLine: Never` に対応できなかった気がする。

```clang-format
---
BasedOnStyle: Google
AlignAfterOpenBracket: Align
AlignOperands: 'false'
AlignTrailingComments: 'false'
AllowShortBlocksOnASingleLine: 'false'
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: Empty
AllowShortLoopsOnASingleLine: 'false'
BreakStringLiterals: 'true'
ColumnLimit: '120'
ContinuationIndentWidth: '2'
DerivePointerAlignment: 'false'
FixNamespaceComments: 'true'
IncludeBlocks: Merge
IndentCaseLabels: 'false'
IndentWidth: '4'
IndentWrappedFunctionNames: 'true'
MaxEmptyLinesToKeep: '2'
PointerAlignment: Right
SortIncludes: 'false'
Standard: Cpp03

...
```

## C# #

個人的には結構好きな言語。

マイクロソフトお手製言語なので公式拡張もしっかりできていて、IntelliSense とかが効くので実用に足る。
もう Visual Studio いらん。

インストール時の挙動が怪しいので、.NET Core SDK を先にインストールしておくほうが無難。

ちなみに Unity でも使える。

C# は Rider 使ったほうがいい。

## Ruby

普通に編集するのであれば [Ruby](https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby) のほうだが、Solargraph を使っていいなら [Ruby Solargraph](https://marketplace.visualstudio.com/items?itemName=castwide.solargraph) を使うとよい。Solargraph は gem を入れる必要があるしそのものが重いので若干アレだが、かなりよく予測が動くので非常に便利。通常はどちらかだけでいい。

Solargraph は設定が結構オフめになっているので、`solargraph.commandPath` の指定と適当なオプションを全部オンにしておく必要がある。あと Solargraph はデフォルトだと gem の予測が全然使えないのであらかじめ yard gems しておく必要がある。

Solargraph 拡張のフォーマットは rubocop ベース。Ruby の方は内部でフォーマッタを持ってなさそう（追加で入れる）。デフォルトの rubocop コンフィグはこれはこれでクセがあるので、~/.rubocop.yml をやはりチューニングする必要がある。波線が引かれるたびに吟味してカスタマイズしていくとよい。僕の .rubocop.yml は長いので省略する。

## MATLAB

まず、拡張子 .m が Objective-C にとられるので、これを前の方で書いた設定で排除する。

[MATLAB](https://marketplace.visualstudio.com/items?itemName=Gimly81.matlab) の拡張が便利。スニペットが使える。
`matlab.matlabpath` と `matlab.mlintpath` を指定しておくと、MATLAB エディタと同じ MATLAB 公式の linter が使える。この linter は非常によくできているので、warning が出たときは素直に従うといい MATLAB コードが書ける。
JetBrains もそうだが、さすが金のかかるプロプライエタリは質が違う。

## LaTeX

[LaTeX Workshop](https://marketplace.visualstudio.com/items?itemName=James-Yu.latex-workshop) を入れておくのがおすすめ。

### ビルド設定

設定が面倒くさいうえにビルド方法がファイルによって違うので、意外と設定が厄介。
解決方法は 2 つあって、ワークスペース設定を毎回する方法と、設定が書きやすいツールをデフォルトに入れておいてそっちの設定を毎回書くという方法がある。前者は柔軟に設定できるがいちいち設定が面倒くさいのと、VSCode 以外でビルドできないという欠点がある。後者は latexmk などを使えば解決できるがそのツールを使いこなすのが面倒くさい。
僕は後者をとっている。というか、後者をとるために[ツールを作った](https://github.com/Ishotihadus/houcluttex)。
あとディレクトリごとに yaml を書けばよい。

```json
{
    "latex-workshop.latex.recipes": [
        {
            "name": "houcluttex",
            "tools": [
                "houcluttex"
            ]
        }
    ],
    "latex-workshop.latex.tools": [
        {
            "args": [
                "%DOC%.tex"
            ],
            "command": "houcluttex",
            "env": {
                "PATH": "/Users/ishotihadus/.rbenv/shims:/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin"
            },
            "name": "houcluttex"
        }
    ],
}
```

Makefile を書いてしまうとかの手もある。ClutTeX の作者はそういう使い方を推奨しているらしい。

### pdf の表示

内部で pdf のビューワを pdf.js ベースか何かで持っている。なので、他の pdf ビューワ拡張を入れるとコンフリクトする。

中身としては HTTP サーバを立ててそこにアクセスしているだけなので、latex のファイルは VSCode で pdf のリアルタイムプレビューはブラウザで表示みたいなこともできる（そういうボタンがある）。
デュアルディスプレイのときにエディタとプレビューを分離できるので便利。

### その他

あとは `latex-workshop.intellisense.package.enabled` をオンにしておくとパッケージの補完も効いて便利。

# おすすめ拡張

## [SSH FS](https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs)

Remote Development がなかった時代の覇権。

Atom の remote-edit(-ni) みたいな感じで、こちらに明示的にダウンロードしなくてもリモートのファイルをいじれる。
Remote Development を使いたくないときにも便利。

GUI で設定できるが項目数が多く複雑なので、慣れてきたら json で書いたほうが早い。
ホストがグループ化できるので Remote Development と比較して散らばらなくて好き。

## [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)

ソースコードのスペルチェックができる。デフォルトでも結構かしこく、コマンド名などスペルチェックしてほしくない場所はスペルチェックされない。

ただ、すべての言語でスペルチェックをされると最高にイライラするので、スペルチェックされる言語を指定しておくとよい。

```json
{
    "cSpell.enabledLanguageIds": [
        "latex",
        "markdown",
        "plaintext",
        "text"
    ],
}
```

## [Material Theme](https://marketplace.visualstudio.com/items?itemName=Equinusocio.vsc-material-theme)

人気あるテーマ。うるさくないので使っている。デフォルトテーマだといかにもﾏｲｸﾛｿﾌﾄｫという感じがして気に入らない。うるさい。

## [background-cover-ishotihadus](https://marketplace.visualstudio.com/items?itemName=ishotihadus.background-cover-ishotihadus)

背景画像をランダムに変えるやつ。カスタム CSS も使える。これは宣伝。

上にも変えたように、こういう拡張は VSCode 本体を破壊する拡張なので、気をつけて使ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78668/a7ea3ea6-34d4-4dc9-3293-262027abafe3.png)

# パフォーマンス・チューニング

Atom の timecop と同様に、コマンドパレットから「Developer: Startup Performance」を開くと起動時の統計情報が出せる。単位が書いてないがミリ秒らしい。

Extension Activation Stats の欄に拡張の起動時間が書いてあるので、起動を重くしている拡張がわかる。

# おわりに

VSCode わからん。