VSCodeでfreezedの出力先をひとつにまとめる

## はじめに
flutter の有名なパッケージである [freezed](https://pub.dev/packages/freezed) パッケージの出力ファイルが煩雑になっていたので一か所にまとめます。
今までは[こちら](https://qiita.com/e-frogs/items/89a9b7fe58d349f26bf3)を参考にさせていただいて、以下のように各生成元ファイルの位置に generated フォルダを生成してそこに詰め込んでいました。
```
 .
 └── - /data
     ├── - /generated
     │   ├── - xxx.g.dart
     │   └── - xxx.freezed.dart
     ├── - xxx.dart
     └── - /sample_direcotry
         ├── - yyy.dart
         └── - /generated
             ├── - yyy.g.dart
             └── - yyy.freezed.dart
```

出力ファイルがどこにも格納されていないよりは綺麗で良いのですが、generated フォルダが散乱するのは見た目があまり良くないです。
かといって lib 直下に generated フォルダを作ってそこに詰め込もうとすると、part 以降の出力先パスをいちいち書き込まないといけません。
この問題を VSCode のスニペットを使って解決しようとしました。
環境は Windows です。

## スニペットでごり押す
解決法のひとつとして、 VSCode のスニペット機能を使って相対パスを自動で書き込むようにしました。
今回出力先は `lib/_generated/` 以下になります。
generated に アンダースコアをつけた理由は VSCode のフォルダ表示順番で一番上にするためです。
別に generated という名前に変えても問題ないです。

build.yamlを以下のように設定し、出力先を設定します。
```build.yaml
targets:
  $default:
    builders:
      source_gen|combining_builder:
        options:
          build_extensions:
            '^lib/{{}}.dart': 'lib/_generated/{{}}.g.dart'
      freezed:
        options:
          build_extensions:
            '^lib/{{}}.dart': 'lib/_generated/{{}}.freezed.dart'
```

VSCode のスニペットに以下の設定を追加します。
```json
 	"Freezed class template generated": {
         "prefix": "frz",
         "description": "Create a Freezed class",
         "body": [
            "import 'package:freezed_annotation/freezed_annotation.dart';",
            "import 'package:flutter/foundation.dart';",
            "part '${TM_DIRECTORY/^(.*?lib\\\\?)|([^\\\\]+\\\\?)/${2:+../}/g}_generated${TM_DIRECTORY/^(.*?lib)|(\\\\)/${2:+/}/g}/${TM_FILENAME_BASE}.freezed.dart';",
            "part '${TM_DIRECTORY/^(.*?lib\\\\?)|([^\\\\]+\\\\?)/${2:+../}/g}_generated${TM_DIRECTORY/^(.*?lib)|(\\\\)/${2:+/}/g}/${TM_FILENAME_BASE}.g.dart';",
            "",
            "@freezed",
            "class ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/g}} with _$${1} {",
            "\tconst factory ${1}({",
            "\t\t${2:required String id},",
            "\t}) = _${1};",
            "\tfactory ${1}.fromJson(Map<String, dynamic> json) => _$${1}FromJson(json);",
            "}",
         ]
     },
```

part 以降にあるものは lib 直下の _generated までの相対パスに加えて、 lib 以降のディレクトリ構造をそのまま _generated フォルダ内に転記しています。
つまり、`lib/sample/xxx.dart` の 出力先は `lib/_generated/sample/xxx.freezed.dart` になるわけです。

最終的に以下のような構造で出力されるようになるはずです。
```
 .
 └── /lib
     ├── /_generated
     │   ├── /data
     │   │   ├── xxx.freezed.dart
     │   │   ├── xxx.g.dart
     │   │   └── /yyy
     │   │       ├── yyy.g.dart
     │   │       └── yyy.freezed.dart
     │   └── /sample_directory
     │       ├── zzz.g.dart
     │       └── zzz.freezed.dart
     ├── /data
     │   ├── xxx.dart
     │   └── /yyy
     │       └── yyy.dart
     └── /sample_directory
         └── zzz.dart
```


**注意点1**
windows 環境ではパスが `\` で区切られていますが、他の環境では違います。使っているスニペットは以下のような構造になっているので、必要がある場合は適宜調整してください。
`${TM_DIRECTORY/(正規表現1)|(正規表現2)/${2:正規表現2の置換文字列}/正規表現のオプション}`
`\\\\`を`\/`にすれば大丈夫かも？
VSCode スニペットについての詳細は[公式](https://code.visualstudio.com/docs/editor/userdefinedsnippets)を参照してください。

**注意点2**
検証はしていませんが、lib までのパスを削除するという動作をしている部分があるため、プロジェクトルートフォルダまでのパスに lib というフォルダがある場合は動作不良を起こす可能性があります。


## おわりに
ようやく煩雑な freezed 生成ファイルから解放されます。

正規表現と VSCode のスニペットを初めてまともに触ったので、冗長なところがあるかもしれません。もっと綺麗に書く方法があれば教えていただけると助かります。
また、freezed の part パスに絶対パスを指定する方法があれば教えていただけると助かります。

### 参考
+ https://qiita.com/e-frogs/items/89a9b7fe58d349f26bf3
+ https://userweb.mnet.ne.jp/nakama/
+ https://pub.dev/packages/freezed
+ https://www-creators.com/archives/1804
+ https://code.visualstudio.com/docs/editor/userdefinedsnippets
+ https://torikatsu923.hatenablog.com/entry/2022/02/07/235634