VSCode 2024.3 Updates 紹介

# VSCode 2024.3 Updates 紹介

みんな大好き VSCode はおよそ月次で New Feature たちがリリースされる。
最新の2024年3月の新機能の中からいくつかピックアップして簡単な例を添えて紹介したいと思う。
なお、以下 json の設定は全て `settings.json` で行うものとする。User settings か Workspace settings かは、設定項目によって適宜調整するべし。また、リリースされた全機能を網羅しているわけではないのでご了承いただきたい。

## 動作確認環境

- Mac: Apple M1 Pro/macOS Sonoma バージョン 14.4
- VSCode: version 1.88.0

参考: [March 2024 (version 1.88)](https://code.visualstudio.com/updates/v1_88)

それでは、レッツ **Cmd + Shift + P  > Preferences: Open User Settings(JSON)♪**

## ファイルのカスタムラベル

### できるようになったこと🎉

エディタ上部のタブの表示名をカスタマイズできるようになった。
例えば、同じ名前のファイルが複数フォルダ化に存在する場合など、それらを区別する時に利用するなどが有用なケースとして考えられる。

### 設定方法⚙️

前提として、以下のようなディレクトリ構成であるとする:

```sh
src/api
├── fitbit
│   └── manageToken.ts
└── notion
    └── manageToken.ts
```

これに対して、以下のような設定を行う。

```settings.json
{
  "workbench.editor.customLabels.enabled": true,// default: true
  "workbench.editor.customLabels.patterns": {
    "**/api/**/*Token.ts": "/manage-${dirname}-token.${extname}"
  }
}
```

`workbench.editor.customLabels.patterns` には複数項目を設定でき、使用できる変数としては以下がある。
- `${filename}`: ファイル名
- `${extname}`: 拡張子名
- `${dirname}`: ディレクトリ名
- `${dirname(N)}`: 最上部から N 階層目のディレクトリ名

結果は以下の通り。
- `workbench.editor.customLabels.enabled`: **true** の場合

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/91dcdc33-df80-986f-b9b0-d3f4a3d1d8d4.png width="500px">

- `workbench.editor.customLabels.enabled`: **false** の場合

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/0a9634d1-2d1d-3c16-ddf3-b26d203deacc.png width="500px">


本設定は、プロジェクトごとのディレクトリ構成に依存する場合もあることを考慮すると、**Workspace settings で設定した方が良い内容である。**

## 複数エディタの同時スクローリング

### できるようになったこと🎉

複数エディタを開いているとき、全てのエディタに対してスクローリングを有効にできるようになった。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/eafe52a7-470e-745e-4da2-86360903ce6b.gif width="1000px">


### 設定方法⚙️

`Cmd + Shift + P` > **View: Toggle Locked Scrolling Across Editors** 選択で、VSCode フッター部分に `Scrolling Locked` の表示がされると有効になっている。その表示をクリックするか、再度同じコマンドを実行することで、同時スクロールは無効になる。


## Diff エディタ Stage/Revert 改良

### できるようになったこと🎉

Diff エディタにおいて、変更箇所をブロックごとに Stage/Revert できるようにボタンが追加された。また、**任意の変更箇所をマウス選択した状態で上記操作を行うと、選択箇所のみ Stage/Revert できる。**（gif 参照）


<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/5ef7dfb1-b0d1-8af3-a75a-d6e4498b0d9c.gif width="1000px">


### 設定方法⚙️

```settings.json
{
  "diffEditor.renderGutterMenu": true,// default: true
}
```

## Extension のアップデートがスムーズに

### できるようになったこと🎉

Extension アップデート時、Extension のリスタートをすれば良くなった。
以前は、VSCode 自体のリロード（≒リスタート）が必要であった。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/e2f5886f-0102-a238-4016-de3192043afa.png width="500px">


※Extension 単位ではなく、一つの「Restart Extensions」をクリックするとアップデートがある全ての Extension がリスタートされる。


### 設定方法⚙️

特になし


## Extension(Python 関係) への issue 作成がスムーズに

### できるようになったこと🎉

Extension に関するバグレポートやフィーチャーリクエストなどの GitHub issue 作成は VSCode 上から行うことが可能だが、いくつかの Extension に対する issue 作成時に入力が推奨される必要（環境情報etc）を自動で埋めてくれるようになった。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/8a3bf0dc-6782-2087-f3a1-889d8f9a524f.gif width="1000px">


### 設定方法⚙️

1. `Cmd + Shift + P` > **Help: Report Issue...**
2. 上の gif 動画のような Issue Reporter が別ウィンドウで立ち上がるので、**File on**: `An extension` を選択し、**Extension**: `Python` または `Python Debugger` を選択する。


## ミニマップにセクション表示

### できるようになったこと🎉

エディタの右サイドに表示されるミニマップに、セクション名を表示できるようになった。これにより、ファイルのどこで何をやっているのかを把握しやすくなることが期待される。

### 設定方法⚙️

```settings.json
{
  "editor.minimap.enabled": true,// pre-requisite, default: true
  "editor.minimap.showRegionSectionHeaders":true,// default: true
  "editor.minimap.showMarkSectionHeaders": true,// default: true
  "editor.minimap.sectionHeaderFontSize": 14,// default: 9
}
```

以下の例のように、セクション名として表示したい部分のサフィックスに `// #region` または　`// Mark:` を記述する。

```ts
// #region IMPORT
import { createPage, updatePage } from '@/api/notion/page';
import { retrieveDatabase, queryDatabase, createDatabase as createNotionDatabase } from '@/api/notion/database';
import { DayjsDate } from '@/util/day';
import { retrieveRefreshToken, issueTokenPair } from '@/api/fitbit/manageToken';
import { storeDatabaseId, retrieveNotionDatabaseId } from '@/api/notion/manageDatabaseId';
import { fetchData } from '@/usecases/fitbit';

// MARK: env
const NOTION_ACCESS_TOKEN = process.env.NOTION_ACCESS_TOKEN as string;
const NOTION_PARENT_PAGE_ID = process.env.NOTION_PARENT_PAGE_ID as string;
const ENV1 = process.env.ENV1 as string;
const ENV2 = process.env.ENV2 as string;
const ENV3 = process.env.ENV3 as string;
const ENV4 = process.env.ENV4 as string;

// MARK: implementation
export const createDBPage = async (day: string, newNotionDatabaseId: string | null) => {
...

```

こんな感じのミニマップが出来上がる。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/791d4982-71e0-0d33-ff8a-784981e5df35.png width="２00px">


`editor.minimap.*` 系の設定で色々いじれるみたいだ。

## Quick Search で検索ヒットのファイル名を Sticky 表示

### できるようになったこと🎉

Quick Search コマンド実行時、検索文字列がヒットした部分を含むファイル名を Sticky に表示され、みやすくなった。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/7789dbea-ee09-8ab4-6c14-dbee8dbdb472.png width="500px">


### 設定方法⚙️

1. `Cmd + Shift + P` > **Search: Quick Search(Experimental)**
2. `%` の後に任意の入力を行い、検索結果のファイル名部分が Sticky になっていることを確認する。


## GitHub Copilot コマンドの改良

### できるようになったこと🎉

#### `@workspace /new`

チャットプロンプトに、「 `@workspace /new` + _\<prompt\>_」を打ち込むと、 _prompt_ の内容に応じたサンプルプロジェクトのディレクトリ構成および各ファイルのコンテンツを提案してくれる。
 例えば、チャット「@workspace /new _calculator_」とお願いすると、以下のようなものを提案してくれた。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/b05adac9-ea33-2971-9548-62c1a6c9ac49.png width="300px">


`src/calculator.js` の中身は次のとおり:

```js
class Calculator {
  add(a, b) {
    return a + b;
  }

  subtract(a, b) {
    return a - b;
  }

  multiply(a, b) {
    return a * b;
  }

  divide(a, b) {
    if (b === 0) {
      throw new Error("Cannot divide by zero");
    }
    return a / b;
  }
}

module.exports = Calculator;
```

続けて、プロンプトに二つ目の願い「use javascript instead of typescript」を行い得られた結果がこちら:

```ts
class Calculator {
  add(a: number, b: number): number {
    return a + b;
  }

  subtract(a: number, b: number): number {
    return a - b;
  }

  multiply(a: number, b: number): number {
    return a * b;
  }

  divide(a: number, b: number): number {
    if (b === 0) {
      throw new Error("Cannot divide by zero");
    }
    return a / b;
  }
}

export default Calculator;
```

ちなみに最後のプロンプトは、現在アクティブのファイルに対して行われる。

#### `@terminal /explain`

`@terminal /explain #terminalLastCommand` で、ターミナルで最後に実行したコマンドの説明を、`@terminal /explain #terminalSelection` で、ターミナルで選択した箇所の説明をしてくれる。（画像割愛）


### 設定方法⚙️

特になし。（GitHub Copilot/GitHub Copilot Chat の Extension が必要）


## 所感

- GitHub Copilot が相変わらずすごい。AI アシスタントとしてのプログラミングをいかにうまく使いこなすかが今後数年トレンドになるかも。
- VSCode でコミット管理する方が良い気がしてきた。他のアプリ(e.g. Sourcetree)などと比べても活発に機能改善が行われ、コンテキストスイッチがないのが大きい。
- 初めましての機能が多いため、アップデート前がどのような状態だったか体験しておらず、比較が難しかったりする。「アップデート内容を眺めてから アップデート前の状態を確認 → アップデート → アップデート後の状態を確認」が良いのだろうか（面倒くさい。。