# 画面設計書 68-スニペット登録（served/addDependencySnippet）

## 概要

本ドキュメントは、serve-d LSPサーバーのカスタムリクエスト `served/addDependencySnippet` の画面設計書である。依存関係に基づくスニペットをserve-d全体に登録する機能を提供する。

### 本画面の処理概要

本リクエストは、外部ツールやエディタ拡張がD言語の依存関係に関連するカスタムスニペットをserve-dに動的に登録するための機能を提供する。

**業務上の目的・背景**：D言語のパッケージマネージャ（DUB）のエコシステムでは、特定のライブラリに特化したコードスニペットを提供することで開発効率が向上する。例えば、特定のライブラリがプロジェクトの依存関係に含まれている場合のみ有効になるスニペットを登録できる。このリクエストにより、エディタ拡張が動的にスニペットを追加し、コンテキスト対応の補完候補を拡張できる。`--provide context-snippets` オプションでserve-dを起動した場合にSnippetsComponentが有効になる。

**画面へのアクセス方法**：LSPクライアントから `served/addDependencySnippet` カスタムリクエストを送信することでアクセスする。

**主要な操作・処理内容**：
1. クライアントから必要な依存関係リストとスニペット情報を受信する
2. SnippetsComponentの存在を確認する
3. SerializablePlainSnippetからPlainSnippetへの変換を実行する
4. SnippetsComponentにスニペットを登録する
5. 登録結果（true/false）を返却する

**画面遷移**：
- 遷移元：エディタ拡張のスニペット登録処理
- 遷移先：なし（登録結果の返却のみ。登録されたスニペットはtextDocument/completionで表示される）

**権限による表示制御**：`--provide context-snippets` オプションでserve-dを起動した場合のみSnippetsComponentが利用可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | スニペット登録 (served/addDependencySnippet) | 主機能 | 依存関係に基づくスニペットをserve-d全体に登録する |

## 画面種別

カスタムLSPリクエスト（登録操作型）

## URL/ルーティング

LSPカスタムメソッド: `served/addDependencySnippet`

## 入出力項目

### リクエストパラメータ（AddDependencySnippetParams）

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| requiredDependencies | string[] | はい | このスニペットが有効になるために必要なDUB依存関係のリスト |
| snippet | SerializablePlainSnippet | はい | 登録するスニペット情報 |

### SerializablePlainSnippet構造

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| levels | int[] | はい | スニペットが有効な文法スコープ（SnippetLevel列挙値） |
| shortcut | string | はい | スニペットのショートカットキーワード |
| title | string | はい | スニペットのタイトル・ラベル |
| snippet | string | はい | スニペット展開時のテキスト（$変数・プレースホルダ付き） |
| documentation | string | はい | スニペットのMarkdownドキュメント |
| plain | string | いいえ | プレーンテキストのフォールバック |
| unformatted | bool | いいえ | trueの場合フォーマットせずに挿入する |
| imports | string[] | いいえ | スニペット挿入時に自動追加するimport文のリスト |

### レスポンス

| 項目名 | 型 | 説明 |
|--------|------|------|
| (戻り値) | bool | 登録成功: true、SnippetsComponent未ロード: false |

## 表示項目

本リクエスト自体は表示を伴わないが、登録されたスニペットはその後のtextDocument/completionレスポンスの補完候補に含まれるようになる。

## イベント仕様

### 1-スニペット登録リクエスト受信

1. クライアントから `served/addDependencySnippet` リクエストを受信する
2. `backend.has!SnippetsComponent` でSnippetsComponentの存在を確認する
3. SnippetsComponentが存在しない場合、falseを返却する
4. SerializablePlainSnippetからPlainSnippetへの変換：
   - `snippet.tupleof` をイテレートし、各フィールドをstatic assertで名前一致を確認しながらコピーする
   - int列挙値のキャストを含む変換を実施する
5. `backend.get!SnippetsComponent.addDependencySnippet(params.requiredDependencies, snippet)` で登録する
6. trueを返却する

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| スニペット登録 | SnippetsComponent（インメモリ） | INSERT | 依存関係スニペットの追加 |

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|---------|--------------|
| なし | - | - | 本リクエストはエラーメッセージを直接クライアントに表示しない |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| SnippetsComponentが未ロード | falseを返却する |

## 備考

- `--provide context-snippets` オプションでserve-dを起動しないとSnippetsComponentが登録されず、常にfalseが返却される
- PlainSnippetとSerializablePlainSnippetはフィールド構成が同一であることがstatic assertで保証されている
- 登録されたスニペットは、指定されたrequiredDependenciesがプロジェクトの依存関係に含まれている場合にのみ補完候補として提示される
- levelsフィールドはSnippetLevel列挙値（global, method, value等）に対応し、スニペットが提示される文法コンテキストを制限する

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protoext.d | `source/served/lsp/protoext.d` | 行224-248のAddDependencySnippetParams, SerializablePlainSnippet構造体 |

**読解のコツ**: SerializablePlainSnippetはLSPプロトコル上でシリアライズ可能なスニペット表現。内部のPlainSnippetはworkspace-dライブラリ側の型であり、フィールド構成は同一。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | complete.d | `source/served/commands/complete.d` | `addDependencySnippet` 関数（行1399-1415）がエントリーポイント |

**主要処理フロー**:
1. **行1399-1400**: `@protocolMethod("served/addDependencySnippet")` で定義。パラメータは `AddDependencySnippetParams`
2. **行1402-1403**: SnippetsComponentの存在確認、未ロード時はfalse返却
3. **行1404**: PlainSnippet変数を宣言
4. **行1405-1412**: `tupleof` を使用したコンパイル時フィールドコピー（static assert付き）
5. **行1413**: `addDependencySnippet(params.requiredDependencies, snippet)` で登録
6. **行1414**: true返却

### プログラム呼び出し階層図

```
served/addDependencySnippet リクエスト
    |
    +-- addDependencySnippet(AddDependencySnippetParams)    [complete.d:1400]
           |
           +-- backend.has!SnippetsComponent                [存在確認]
           |
           +-- SerializablePlainSnippet -> PlainSnippet     [型変換]
           |
           +-- SnippetsComponent.addDependencySnippet()     [workspace-d]
```

### データフロー図

```
[入力]                              [処理]                          [出力]

AddDependencySnippetParams ---> addDependencySnippet()       --> bool
  |                                |
  +-- requiredDependencies         +-- SnippetsComponent確認
  +-- snippet                      +-- 型変換（tupleof）
      +-- levels                   +-- SnippetsComponentに登録
      +-- shortcut
      +-- title
      +-- snippet text
      +-- documentation
      +-- imports
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| complete.d | `source/served/commands/complete.d` | ソース | addDependencySnippet関数の実装 |
| protoext.d | `source/served/lsp/protoext.d` | ソース | AddDependencySnippetParams, SerializablePlainSnippet構造体の定義 |
| types.d | `source/served/types.d` | ソース | 共通型定義 |
