# 画面設計書 17-コード補完（textDocument/completion）

## 概要

D言語、dietテンプレート、DMLファイルに対するコード補完を提供するLSPメソッドの設計書である。DCDによる識別子補完、スニペット補完、自動インポート補完を統合的に提供する。

### 本画面の処理概要

本画面は、LSP標準の `textDocument/completion` リクエストを処理し、カーソル位置に応じた補完候補リストを返却する処理を担当する。D言語ソースファイル、dietテンプレートファイル、DMLファイル、dscanner.iniファイルのそれぞれに対応した補完を提供する。

**業務上の目的・背景**：コード補完はIDEの中核機能であり、開発者の生産性を大幅に向上させる。D言語固有の識別子補完（DCD）、スニペット補完、自動インポート補完、ドキュメントコメント補完を統合的に提供することで、D言語開発のワークフローを効率化する。

**画面へのアクセス方法**：エディタ上でコード入力中にトリガー文字（`.`, `=`, `/`, `*`, `+`, `-`）を入力するか、手動で補完を起動する（通常 Ctrl+Space）ことで、textDocument/completionリクエストがクライアントからサーバーに送信される。

**主要な操作・処理内容**：
1. クライアントからtextDocument/completionリクエストを受信
2. ドキュメントのファイルタイプに応じて処理を分岐
3. D言語: DCD補完、ドキュメントコメント補完、スニペット補完、自動インポート補完を並列実行
4. dietテンプレート: dietc補完とDCD補完を組み合わせ
5. DML: DlangUI補完
6. dscanner.ini: 設定フィールド補完
7. 補完リスト（CompletionList）を返却

**画面遷移**：補完候補選択後、completionItem/resolve（No.18）が呼ばれて詳細情報が解決される。コードアクション（No.19）やインポート追加がトリガーされる場合もある。

**権限による表示制御**：権限による表示制御は存在しない。ただし、設定 `d.enableAutoComplete` がfalseの場合はDCD補完が無効化される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | 自動補完 (textDocument/completion) | 主機能 | カーソル位置に応じたDCD補完・スニペット補完・自動インポート補完を統合的に提供する |
| 14 | スニペット補完 | 補助機能 | コード補完の一部としてコンテキストに応じたスニペット候補を提供する |
| 15 | 自動インポート補完 | 補助機能 | コード補完の一部として未インポートモジュールからのシンボル候補を提供する |

## 画面種別

LSPレスポンス（補完リスト）

## URL/ルーティング

LSP標準メソッド: `textDocument/completion`

- リクエスト: `TextDocumentPositionParams`
- レスポンス: `CompletionList`

## 入出力項目

| 項目名 | 型 | 入力/出力 | 説明 |
|--------|-----|----------|------|
| textDocument.uri | DocumentUri | 入力 | 対象ドキュメントのURI |
| position.line | uint | 入力 | カーソル行番号 |
| position.character | uint | 入力 | カーソル列番号 |
| isIncomplete | bool | 出力 | 補完リストが不完全かどうか（常にfalse） |
| items | CompletionItem[] | 出力 | 補完候補の配列 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| label | テキスト | 補完候補の表示名 |
| kind | アイコン | 候補の種類（関数、変数、クラス等） |
| detail | テキスト | 候補の詳細（型情報、定義等） |
| documentation | マークダウン | DDocドキュメント |
| insertText | テキスト | 挿入されるテキスト |
| sortText | テキスト | ソート用文字列（プレフィックスにより優先度制御） |
| labelDetails | テキスト | 追加のラベル情報（戻り値型、パラメータ等） |

## イベント仕様

### 1-D言語ファイルの補完

D言語ファイルの場合、以下の4種類の補完を並列実行する:

1. **DCD補完**（completeDCDフラグ有効時）: DCDComponentのlistCompletionを呼び出し、識別子リストを取得。convertDCDIdentifiersで CompletionItemに変換
2. **ドキュメント補完**（completeDocフラグ有効時）: DscannerComponentで次の定義を取得し、DDocコメントテンプレートを生成（///、/**、/++形式）
3. **スニペット補完**（completeSnippetsフラグ有効時）: SnippetsComponentからコンテキストに応じたスニペット候補を取得
4. **自動インポート補完**（completeIndexフラグ有効時）: IndexComponentからプレフィックスに一致するシンボルを検索し、未インポートモジュールからの候補を提供

### 2-dietテンプレートファイルの補完

1. dietc.completeでdietテンプレート固有の補完を取得
2. D言語コード埋め込み部分ではDCD補完を使用

### 3-DMLファイルの補完

1. DlanguiComponentのcompleteを呼び出し、DlangUI固有の補完を取得
2. クラス名、プロパティ名、色、列挙値等の補完をサポート

### 4-dscanner.iniの補完

1. DscannerComponentのlistAllIniFieldsから設定フィールド一覧を取得
2. iniセクション（StaticAnalysisConfig, ModuleFilters）の補完
3. 設定値（"disabled", "enabled", "skip-unittest"）の補完

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | なし | なし | データベースアクセスなし（読み取り専用操作） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 条件 |
|-------------|------|---------------|------|
| なし | なし | なし | エラーメッセージの表示は行わない |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| インスタンスがnull | 空のCompletionList.initを返却 |
| 未対応の言語ID | 空のCompletionList.initを返却 |
| コメント内のカーソル | DDocコメント（///、/**、/++）の場合はドキュメント補完、それ以外は空のリストを返却 |
| DCDComponentが未初期化 | DCD補完をスキップし、他の補完のみ提供 |

## 備考

- トリガー文字は `.`, `=`, `/`, `*`, `+`, `-` の6文字で、initialize時のサーバーケイパビリティで宣言される
- ソートプレフィックスにより補完候補の優先順位が制御される: ドキュメント(0_) > DCD(2_) > スニペット(2_5_) > 自動インポート(3_)
- argumentSnippets設定がtrueの場合、関数補完時にスニペット形式でパラメータが挿入される
- 自動インポート補完はd.enableIndexおよびd.enableAutoImportCompletions設定が両方trueの場合のみ有効

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | complete.d | `source/served/commands/complete.d` | ソートプレフィックス定数（34-39行目）: sortPrefixDoc, sortPrefixSnippets, sortPrefixDCD, sortPrefixAutoImport |
| 1-2 | complete.d | `source/served/commands/complete.d` | convertFromDCDType関数（41-85行目）: DCDの型コードからCompletionItemKindへの変換 |

**読解のコツ**: DCDの型コードは1文字の識別子（c=class, f=function等）で表現される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | complete.d | `source/served/commands/complete.d` | provideComplete関数（304-396行目）がメインエントリーポイント。ファイルタイプ別の分岐を行う |

**主要処理フロー**:
1. **307行目**: ドキュメント取得とインスタンス選択
2. **311行目**: dscanner.iniファイル判定
3. **384行目**: D言語 -> provideDSourceComplete呼び出し
4. **386行目**: diet -> provideDietSourceComplete呼び出し
5. **388行目**: DML -> provideDMLSourceComplete呼び出し

#### Step 3: D言語補完の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | complete.d | `source/served/commands/complete.d` | provideDSourceComplete関数（550-644行目）: 4種類の補完を並列実行 |
| 3-2 | complete.d | `source/served/commands/complete.d` | provideAutoImports関数（735-839行目）: 自動インポート補完の実装 |
| 3-3 | complete.d | `source/served/commands/complete.d` | convertDCDIdentifiers関数（1099-1343行目）: DCD識別子からCompletionItemへの変換 |

**主要処理フロー**:
- **615-629行目**: joinAllで4種類の補完を並列実行（DCD、Doc、Snippets、AutoImport）
- **631-643行目**: DCD結果の統合

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

```
textDocument/completion
    |
    +-- provideComplete() [complete.d:304]
            |
            +-- [dscanner.ini] listAllIniFields [complete.d:314]
            |
            +-- [D言語] provideDSourceComplete() [complete.d:550]
            |       |
            |       +-- joinAll(
            |       |       DCD: listCompletion [complete.d:617]
            |       |       Doc: provideDocComplete [complete.d:620]
            |       |       Snippets: provideSnippetComplete [complete.d:623]
            |       |       AutoImport: provideAutoImports [complete.d:628]
            |       |   )
            |       |
            |       +-- convertDCDIdentifiers() [complete.d:1099]
            |
            +-- [diet] provideDietSourceComplete() [complete.d:491]
            |       +-- dietc.complete
            |       +-- DCD: listCompletion
            |
            +-- [DML] provideDMLSourceComplete() [complete.d:398]
                    +-- DlanguiComponent.complete
```

### データフロー図

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

TextDocumentPosition   +-- provideComplete()            +-- CompletionList
(uri, line, char)           |                                  |
                             +-- ファイルタイプ判定              +-- items[]
                             |                                       - label
                             +-- [D] DCD補完                         - kind
                             +-- [D] ドキュメント補完                - detail
                             +-- [D] スニペット補完                  - documentation
                             +-- [D] 自動インポート補完              - insertText
                             |                                       - sortText
                             +-- [diet] dietc補完                    - labelDetails
                             +-- [DML] DlangUI補完
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| complete.d | `source/served/commands/complete.d` | ソース | メイン実装（provideComplete, provideDSourceComplete等） |
| extension.d | `source/served/extension.d` | ソース | initialize関数でcompletionProviderのケイパビリティ設定（273-279行目） |
| types.d | `source/served/types.d` | ソース | Configuration構造体（enableAutoComplete等の設定） |
| ddoc.d | `source/served/utils/ddoc.d` | ソース | DDocコメントのMarkdown変換ユーティリティ |
