[VS Code]同じ構文はスニペットを作って快適にコーディングしよう！

# スニペットによる快適なコーディング

コードを書いていると、度々同じ構文を書くことがあると思います。
例えば、条件式やループ、変数や関数宣言 などなど...

同じ構文を何度も手入力するのは手が疲れますし、打ち間違える可能性もあります。
また、打ち間違いによって発生するエラー対応に時間がかかるため、開発効率が悪くなってしまいます。
こういった問題は、VS CodeなどのエディタやIDEに搭載されているスニペット機能を使うことで解消することができます。

スニペット(Snippets)とは、条件式やループ、変数や関数宣言などの構文を簡単に入力できるようにするテンプレートです。
スニペットを用意して、エディタ上でトリガーとなる文字列を入力すると候補が表示され、選択することで貼り付けることができます。
![snippets呼び出し.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/8ce3cc13-db71-d361-3c97-4e27c8cc5b65.gif)

本記事では、VS Codeでのスニペットの導入方法と使い方について説明します。

## 前提

Visual Studio Code(version 1.60)　

## 導入方法

スニペットの導入方法は大きく分けて２種類あります。

- マーケットプレイスからインストール
- スニペットを自作

### マーケットプレイスからインストール

![スクリーンショット 2021-09-06 13.32.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/ee0780a8-e59c-48ca-946f-d7149a20c33c.png)
上記のアイコンをクリックするか、ショートカットキー(Mac:command+shift+x, Win:control+shift+x)を入力してマーケットプレイスの一覧を開き、検索欄に```@category:"snippets"```と入力すると、フィルタ機能が働いて言語またはフレームワークなどに対応したスニペットの拡張機能が表示されます。
拡張機能の説明文をよく読み、問題が無ければ青い[Install]ボタンを押してインストールします。
![スクリーンショット 2021-09-08 10.17.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/dd3500e3-998c-2a6c-9aff-c86254c3889e.png)
インストール後ファイルを開き、拡張機能の説明文に書かれているトリガ名を入力すると、候補が表示されます。
![スクリーンショット 2021-09-08 16.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/e92ac25a-403f-e54f-3e01-b2192cadb4c8.png)
候補を選択するとテンプレートが展開されます。
![スクリーンショット 2021-09-08 16.43.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/9e4f4d71-123d-c854-102a-95a68302d7df.png)

#### マーケットプレイスからインストールのメリット

- インストールすればすぐに使える。
- メジャーどころの言語やフレームワークに対しては大体揃っている。

#### マーケットプレイスからインストールのデメリット

- テンプレートの内容とトリガー名をセットで覚える必要があるため、学習コストが発生する。

### スニペットを自作
VS Code側で指定されたjsonファイルを用意・編集することで、簡単に追加することができます。
この指定されたjsonファイルを呼び出すには、まず下記の操作を行います。

- Mac: メニュー「Code > 基本設定 > User Snippets」
- Mac: ショートカット「command+shift+p」を入力後、「snippets」と入力して「Preferences: Configure User Snippet」を選択
- Win: メニュー「ファイル > ユーザー設定 > ユーザースニペット」
- Win: ショートカット「control+shift+p」を入力後、「snippets」と入力して「Preferences: Configure User Snippet」を選択

すると、下記の候補が表示されます。
![スクリーンショット 2021-09-08 11.15.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/8f1a167e-0ab8-2352-b203-96ebaaaa055c.png)
候補に登録したい言語が表示されていない場合、入力欄「Select Snippets File or Create Snippets」に言語名を入力すると、フィルタ機能により候補を絞り込むことができます。
下記の画像は「type」と入力して候補を絞った様子です。
![スクリーンショット 2021-09-08 11.16.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/4ccd5120-a503-16ec-5f85-b3747402857c.png)
候補を選択すると、jsonファイルが開きます。
簡単な説明がコメントアウトされた状態で表示されます。
(**VS Codeのスニペット用jsonは、"//"によるコメントアウトが可能**)
![スクリーンショット 2021-09-08 11.32.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/deed9db1-7a0d-f0c4-6fcf-d0f918936798.png)

この中で、7行目から14行目がスニペットになります。
コメントアウトを外すと、次のようになります。

```json
{
  "Print to console": {
    "prefix": "log",
    "body": [
      "console.log('$1');",
      "$2"
    ],
    "description": "Log output to console"
  },
}
```

保存すると自動的に登録が完了しますので、登録した言語のファイルを開き、「log」と入力して候補を表示すると、次のようになります。
![スクリーンショット 2021-09-08 11.55.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/2640caee-1073-b90b-1ef1-8900ae855af8.png)

候補を選択すると、テンプレートが展開されて、```console.log('');```の```('```と```')```の間にカーソルが移動します。
また、タブキーを入力すると、カーソルが次の行の先頭に移動します。
![スクリーンショット 2021-09-08 11.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/a62be578-21bd-c747-49f7-2e4079849a7d.png)

#### スニペット名
```json
"Print to console": {
    ...
}
```

上記の例では、**Print to console**がスニペット名となります。
スニペットの候補を表示した際に、緑の枠で囲った位置に文字列が表示されます。
省略は不可ですが。空文字```""```は可能です。
![スニペット名.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/6ca8d6b7-12b1-879d-31a2-1ba8fb587086.png)

#### prefix

```json
"prefix": "log"
```

上記の例では、"log"がこのスニペットの候補を出すためのトリガーとなります。
省略は不可で、１ワード以上の登録が可能です。
複数のワードは```[ ]```で囲い、カンマ区切りで書くことで登録することができます。

```json:例
"prefix":["log", "console", "print"]
```

#### body: 基本

```json
"body": [
    "console.log('$1');",
    "$2"
],
```

上記の例では、

```json
"console.log('$1');",
"$2"
```
が、テンプレートの内容となります。
**カンマで区切ることことで、改行コードが挿入**されます。

#### body: インデントの挿入について
テンプレート内でインデントを挿入したい場合は```\t```を1つ書くことで、インデント１回分が挿入されます。
下記は２重ループの例となります。

```json:例
"body": [
    "for(){",
    "\tfor(){",
    "\t\ti+j;",
    "\t}",
    "}"
],
```

テンプレートを展開すると、

```javascript:例
for(){
  for(){
    i+j;
  }
}
```

#### body: プレースホルダー
bodyの```$1```や```$2```はそれぞれプレースホルダーとなり、テンプレートを展開した際に```$1```を書いたい位置にカーソルが移動し、タブキーを押すとカーソルが```$2```を書いた位置へ移動します。
プレースホルダーが複数存在する場合は、番号に対して昇順で移動します。
また、同じ番号が複数存在する場合、マルチカーソルとなり同時入力が可能となります。
![multi.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/7dc045b8-2575-c77a-37e0-7402ffc3bc94.gif)

#### body: 初期値
$1を```${1:foo}```と書くと、文字列**foo**が初期値として設定されます。
文字を入力しないでタブキーを押すとこの初期値で確定して、次のプレースホルダーへ移動します。
文字を入力した場合、fooが消えて任意の文字が入力されます。

#### body: 選択肢
$1を```${1|true,false|}```と書くと、初期値を選択式にすることができます。
テンプレートを展開すると、次のように選択肢が表示されます。
![スクリーンショット 2021-09-08 15.12.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/52e8a615-3469-4efd-a10c-cbdbca795150.png)

#### body: 変数
テンプレートの中に```$TM_FILENAME_BASE```や```${1:TM_FILENAME_BASE}```と書くと、スニペットを呼び出したときに編集中のファイル名が自動的に挿入されます。
この```TM_FILENAME_BASE```はVS Code側であらかじめ用意された変数です。
これ以外にも様々な変数が用意されており、下記のサイトに変数の説明の内容を確認できます。
https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables


#### body: 文字列を示すダブルクォーテーションについて
bodyの内容はダブルクォーテーション```"```で囲われています。
言語によりますが、文字列もダブルクォーテーション```"```を使う場合、次のように書くとエラーになります。

```json:例
"body": [
    "console.log("$1");"
]
```
これは、```"console.log("```で区切られてしまうことが原因です。

このエラーを回避する方法は２種類あります。

- ダブルクォーテーションをエスケープする```\"```
- シングルクォーテーション```'```を用いる

##### ダブルクォーテーションをエスケープする( ```\"``` )
ダブルクォーテーションをエスケープすると回避できます。
前述の例を修正すると、次のようになります。

```json:例
"body": [
    "console.log(\"$1\");"
]
```

##### シングルクォーテーション```'```を用いる
言語仕様にもよりますが、文字列をシングルクォーテーション```'```で囲えるのであれば、これを利用して回避することができます。
前述の例を修正すると、次のようになります。

```json:例
"body": [
    "console.log('$1');"
]
```

例で使用している言語はJavaScript(TypeScrip)のためシングルクォーテーション```'```を使うことができますが、言語によってはこれを使うことができません。
その場合は**ダブルクォーテーションをエスケープする```\"```**方法で回避してください。

#### description

```json
"description": "Log output to console"
```

このスニペットの説明文となります。
![description.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890567/56439f6a-0f58-ddae-edc7-238e3b436bd9.png)

#### 自作スニペットのメリット

- テンプレートの内容とトリガー名は自由に決められるため、学習コストがそれほどかからない。
- 一度学習したことを自作スニペットにまとめておけば、学習内容や構文の書き方を思い出しやすい。

#### 自作スニペットのデメリット

- 元のコードからスニペット化するときの文字列の書き換え(ダブルクォーテーションのエスケープやインデントから\tに変換など)に慣れる必要がある。

## 終わりに
VS Codeでのスニペットの導入方法と使い方について説明しました。

自作スニペットは、メリットにも書きましたがテンプレート内容を自由に決められて、トリガー名も自分の命名規約で名付けられるので、マーケットプレイスから導入するよりも自由度が高いため、個人的にはこちらを推していきたいと考えています。

そこで今後、自作スニペットの実践編として
- **スニペット登録の雛形を呼び出すための**スニペット
- コードからスニペットのbody内容を作成する手法
の記事を書きたいと思います。

記事を最後までみていただき、ありがとうございました。