VS Codeの設定： 括弧と引用符の自動補完について

# はじめに

VSCode を使っていて括弧(bracket)や引用符(quote)を思い通りに補完してくれないことがあります。
これの原因と対策について記事にしたいと思います。

# 環境

Windows 10
Visual Studio Code 1.47.3

# 基本設定

まずは、基本的な設定を確認します。
確認すべき項目は、以下の 3 つです。

- `Editor: Auto Closing Brackets`: 括弧の自動補完の設定
- `Editor: Auto Closing Quotes`: 引用符の自動補完の設定
- `Editor: Auto Surround`: 選択範囲の自動囲みの設定

## 括弧と引用符の自動補完の設定

`Editor: Auto Closing Brackets` と `Editor: Auto Closing Quotes` には、以下の値が選択できます。

- languageDefined: 言語設定に従う。`settings.json`の対象言語に対する設定が有効になる
- beforeWhitespace: カーソルが空白の前にある場合のみ、補完する。
- always: 常に補完する
- never: 補完しない

この記事では、補完を有効にしたいので `never` 以外の値を設定します。
使い勝手を考えて どちらも、`beforeWhitespace` を選択します。

## 選択範囲の自動囲みの設定

`Editor: Auto Surround` には、以下の値が選択できます。

- languageDefined: 言語設定に従う。`settings.json`の対象言語に対する設定が有効になる
- quotes: 引用符のみ囲む。
- brackets: 括弧のみ囲む。
- never: 囲まない

こちらも、`never`以外の値を設定します。
括弧も引用符も囲んでほしいので `languageDefined` を選択します。

## `settings.json`

`settings.json`で設定する場合は、以下のようにします。

```jsonc
  "editor.autoClosingBrackets": "beforeWhitespace",
  "editor.autoClosingQuotes": "beforeWhitespace",
  "editor.autoSurround": "languageDefine",
```

これで自動補完が最大限有効になったはずです。

# Markdown の挙動

上記の設定で`Markdown`ファイルを編集してみます。

```text
()    開き括弧を入力すると閉じ括弧が自動で入力される
{}    開き括弧を入力すると閉じ括弧が自動で入力される
[]    開き括弧を入力すると閉じ括弧が自動で入力される
<>    開き括弧を入力すると閉じ括弧が自動で入力される
"     引用符を入力しても補完されない
'     引用符を入力しても補完されない
`     引用符を入力しても補完されない

(abc) abcを選択してから開き括弧を入力すると選択範囲を囲ってくれる
{     abcを選択してから開き括弧を入力すると上書きされる
[abc] abcを選択してから開き括弧を入力すると選択範囲を囲ってくれる
<     abcを選択してから開き括弧を入力すると上書きされる
"     abcを選択してから開き括弧を入力すると上書きされる
'     abcを選択してから開き括弧を入力すると上書きされる
`abc` abcを選択してから開き括弧を入力すると選択範囲を囲ってくれる
```

設定がおかしいのかもしれませんので変更してみます。
`settings.json`

```jsonc
  "editor.autoClosingBrackets": "languageDefined",
  "editor.autoClosingQuotes": "languageDefined",
  "editor.autoSurround": "languageDefined",
  "[markdown]": {
    "editor.autoClosingBrackets": "always",
    "editor.autoClosingQuotes": "always",
    "editor.autoSurround": "languageDefined",
  },
```

同じように編集しても補完の挙動は変わりません。
そもそも補完対象の括弧や引用符は、 どこか別のところで定義されているようです。

# 対策

個人的には、引用符の挙動を変えたいです。
これから、その対策を示したいと思います。

## 応急処置: 選択範囲の自動囲みの対策

選択範囲の自動囲みに関してのみは、スニペットを使う事でも対策できます。

まずは、`Preferences: Configure User Snippets` でスニペットを定義します。
Snippet file は、`markdown` か `New Global Snippet file` を選択します。
もしくは、既存のファイルを選択します。
選択したファイルに以下のように定義します。

```jsonc
  "enclose\"": {
    // use this from `Insert snippet` command
    "prefix": "\"",
    "body": ["\"${TM_SELECTED_TEXT}\""],
    "description": "enclose"
  },
```

これを保存後、文字列を選択して、`Insert Snippet`コマンドを実行します。
選択肢が出ますので、先ほど作成した`enclose`を選択します。
これで若干の手間が増えましたが自動囲みの対策が出来ました。

## 言語構成(`language-configuration`)を変えることによる対策

根本的な対策をする場合は、別途 Extension (Language Support) を導入するか VS Code の インストールフォルダにある言語構成ファイルを編集する必要があります。
目的に合った Extension があるか分からないのでファイルを編集することにします。

`Markdown` ファイルを編集するときの挙動を変える場合は、
Windows10 の場合、`$InstallDir\resources\app\extensions\markdown-basics` フォルダにある `language-configuration.json` を編集します。
(組み込みのファイルのなのでバックアップを取ると安心です。)

### 自動補完の修正

括弧と引用符の自動補完を修正する場合は、`brackets` と `autoClosingPairs` を修正します。
ここでは、引用符として `` "'` `` を自動補完の対象にしたいと思います。
その場合、以下のように変更します。

```jsonc
"autoClosingPairs": [
    {
      "open": "{",
      "close": "}"
    },
    {
      "open": "[",
      "close": "]"
    },
    {
      "open": "(",
      "close": ")"
    },
    {
      "open": "<",
      "close": ">",
      "notIn": ["string"]
    },
    {
      "open": "\"",
      "close": "\""
    },
    {
      "open": "'",
      "close": "'"
    },
    {
      "open": "`",
      "close": "`"
    },
  ],
```

今回は、引用符のみの追加だったのですが、括弧として認識させたい場合は、`brackets`も編集する必要があります。
例えば、`'` を括弧としたい場合は、

```json
  "brackets": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"],
    ["'", "'"]
  ],
```

とする必要があります。

### 選択範囲の自動囲みの修正

選択範囲の自動囲みを修正する場合は、`brackets` と `surroundingPairs` を修正します。
ここでは、括弧として`{}`, `<>`を、引用符として`"'` を自動囲みの対象にしたいと思います。
その場合、以下のように変更します。

```jsonc
  "brackets": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"],
    ["<", ">"]
  ],
  "surroundingPairs": [
    ["(", ")"],
    ["[", "]"],
    ["{", "}"],
    ["<", ">"],
    ["`", "`"],
    ["_", "_"],
    ["*", "*"],
    ["\"", "\""],
    ["'", "'"]
  ],
```

これで、自動囲みの修正も出来ました。

### 変更を有効にする。

`language-configuration.json` の変更を有効にする場合、VS Code をリロードする必要があります。
そのため、`Developer: Reload Window` コマンドを実行します。

### `settings.json`

言語構成を変えましたので使い勝手を考えて `settings.json` も修正しておきます。
例えば、以下のようにします。

```jsonc
  "editor.autoClosingBrackets": "beforeWhitespace",
  "editor.autoClosingQuotes": "beforeWhitespace",
  "editor.autoSurround": "languageDefined",
```

### Markdown の挙動

再度、`Markdown`ファイルを編集してみます。

```text
()    補完される
{}    補完される
[]    補完される
<>    補完される
""    補完される
''    補完される
''    補完される

(abc) 囲ってくれる
{abc} 囲ってくれる
[abc] 囲ってくれる
<abc> 囲ってくれる
"abc" 囲ってくれる
'abc' 囲ってくれる
`abc` 囲ってくれる
```

期待通りに動作するようです。

# 最後に

これで思い通りに修正することができました。
ただ、自動囲みの方は良いとして、自動補完に関しては邪魔に思う事もありますので修正することになると思います。

また、plaintext(.txt)に関しては、`language-configuration.json`がないために修正しようと思うと非常に大変です。
何かうまい方法はないものでしょうか?

# 参考

[Snippets in Visual Studio Code](https://code.visualstudio.com/docs/editor/userdefinedsnippets)
[Language Configuration Guide](https://code.visualstudio.com/api/language-extensions/language-configuration-guide)