# 画面設計書 2-コード補完

## 概要

本ドキュメントは、Lua Language Serverの「コード補完」機能の設計を記載したものである。LSP（Language Server Protocol）の `textDocument/completion` メソッドに対応し、エディタ上でコード入力中に補完候補をポップアップ表示する機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：
Luaコードを開発する際、変数名・関数名・キーワードなどの入力を補助することで、タイピング量を削減し、スペルミスを防止する。また、利用可能なAPIやメソッドを一覧表示することで、コードの発見性を向上させる。本機能は、開発者の生産性を大幅に向上させ、正確なコードを素早く記述するために不可欠である。

**画面へのアクセス方法**：
エディタ（VS Code等）上でLuaファイルを開き、文字を入力することで自動的に補完候補が表示される。また、Ctrl+Space（手動トリガー）や `.`（ドットトリガー）、`:`（コロントリガー）で明示的に補完を呼び出すことも可能。

**主要な操作・処理内容**：
1. エディタからLSPサーバーへ `textDocument/completion` リクエストを送信
2. カーソル位置と入力中のテキストを解析
3. ローカル変数、グローバル変数、フィールド、キーワードなどの補完候補を収集
4. 候補をスコア順にソートし、ラベル・詳細・スニペットを構築
5. 補完リストをエディタへ返却
6. エディタが補完ポップアップを表示

**画面遷移**：
- 遷移元：エディタのコード編集画面（文字入力）
- 遷移先：補完アイテム詳細（completionItem/resolve）
- 関連遷移：補完確定後、自動requireコマンドが実行される場合あり

**権限による表示制御**：
本機能に権限による表示制御はない。ただし、`Lua.completion.enable` 設定により機能全体の有効/無効を切り替えることができる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | 自動補完 (textDocument/completion) | 主機能 | 入力中に補完候補を提供する主処理 |
| 10 | 補完項目解決 (completionItem/resolve) | 補助機能 | 補完候補の詳細情報を遅延取得 |
| 11 | 自動require (auto-require) | 補助機能 | モジュールの自動require文挿入 |
| 12 | 後置補完 (postfix) | 補助機能 | 後置記法による補完処理 |

## 画面種別

情報表示（ポップアップリスト）

## URL/ルーティング

LSPメソッド: `textDocument/completion`

**リクエストパラメータ**:
```json
{
  "textDocument": {
    "uri": "file:///path/to/file.lua"
  },
  "position": {
    "line": 10,
    "character": 5
  },
  "context": {
    "triggerKind": 1,
    "triggerCharacter": "."
  }
}
```

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument.uri | string | Yes | 対象ファイルのURI |
| position.line | integer | Yes | カーソル位置の行番号（0始まり） |
| position.character | integer | Yes | カーソル位置の列番号（0始まり） |
| context.triggerKind | integer | No | トリガー種別（1: 手動, 2: 文字, 3: 再トリガー） |
| context.triggerCharacter | string | No | トリガー文字（".", ":", "(", ",", "#"など） |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isIncomplete | boolean | 結果が不完全かどうか（追加候補がある可能性） |
| items | CompletionItem[] | 補完候補のリスト |
| items[].label | string | 補完候補の表示名 |
| items[].kind | integer | 補完候補の種別（Variable, Function, Keywordなど） |
| items[].detail | string | 型情報などの詳細 |
| items[].sortText | string | ソート用テキスト |
| items[].filterText | string | フィルタ用テキスト |
| items[].insertText | string | 挿入されるテキスト |
| items[].insertTextFormat | integer | 挿入テキストの形式（1: PlainText, 2: Snippet） |
| items[].textEdit | TextEdit | テキスト編集情報 |
| items[].additionalTextEdits | TextEdit[] | 追加のテキスト編集（require文挿入など） |
| items[].documentation | MarkupContent | ドキュメント情報 |
| items[].command | Command | 補完確定後に実行するコマンド |
| items[].data | object | resolve時に使用するデータ |

## 表示項目

### 補完ポップアップ表示内容

| 表示項目 | 形式 | 説明 |
|---------|------|------|
| ラベル | テキスト | 補完候補名（関数名、変数名など） |
| アイコン | アイコン | 候補種別を示すアイコン（Function, Variable等） |
| 詳細 | テキスト | 型情報や値のプレビュー |
| ドキュメント | Markdown | LuaDocからの説明文 |

## イベント仕様

### 1-補完リクエスト処理

1. エディタが文字入力を検出し、LSPサーバーへ `textDocument/completion` リクエストを送信
2. `provider.lua` の `textDocument/completion` ハンドラが呼び出される
3. `Lua.completion.enable` 設定を確認、無効の場合は `nil` を返却
4. ワークスペースの準備状態を確認、未完了の場合は `nil` を返却
5. `core/completion/completion.lua` の `completion` 関数を呼び出し
6. 以下の補完ソースから候補を収集：
   - ローカル変数（`checkLocal`）
   - グローバル変数（`checkGlobal`）
   - フィールドアクセス（`checkField`）
   - キーワード（`checkKeyWord`）
   - テーブルフィールド（`checkTableField`）
   - 自動require（`checkModule`）
   - LuaDoc補完（`tryLuaDoc`）
7. 候補をスコア順にソート
8. レスポンスとしてエディタへ返却

### 2-トリガー文字別処理

| トリガー文字 | 処理内容 |
|-------------|---------|
| `.` | フィールドアクセス補完 |
| `:` | メソッド補完（OOP） |
| `(` | 関数引数のドキュメント補完 |
| `,` | 引数区切り後の補完 |
| `#` | テーブル長さ演算子後の補完 |
| `{` | テーブルコンストラクタ内の補完 |
| 改行 | 設定により無視 |

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

本機能はデータベース操作を行わない（読み取り専用）。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| WINDOW_PROCESSING_COMPLETION | 情報 | 処理中表示 | 補完処理実行中 |
| COMPLETION_IMPORT_FROM | 情報 | "Import from {path}" | 自動require候補表示時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが存在しない | `nil` を返却 |
| `Lua.completion.enable` が `false` | `nil` を返却 |
| ワークスペース未準備 | `nil` を返却 |
| 補完候補なし | `nil` を返却 |
| 処理時間が0.1秒超過 | 警告ログ出力 |

## 備考

- `Lua.completion.autoRequire` 設定により自動require機能を制御可能
- `Lua.completion.callSnippet` 設定により関数呼び出しのスニペット形式を制御
- `Lua.completion.showParams` 設定によりパラメータ表示を制御
- `Lua.completion.showWord` 設定によりワークスペース単語補完を制御
- `Lua.completion.workspaceWord` 設定によりワークスペース全体からの単語補完を制御
- 最大候補数は `Lua.completion.maxSuggestCount` で制御

---

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

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

### 推奨読解順序

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

補完機能で扱うデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | define.lua | `script/proto/define.lua` | CompletionItemKind の定義を理解 |
| 1-2 | parser/guide.lua | `script/parser/guide.lua` | ASTノードの操作方法を理解 |

**読解のコツ**: `define.CompletionItemKind` で補完候補の種別が定義されている。

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

処理の起点となるプロバイダーファイルを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` | LSPメソッドの登録とリクエスト処理 |

**主要処理フロー**:
1. **621-730行目**: `textDocument/completion` ハンドラの定義
2. **625行目**: `Lua.completion.enable` 設定チェック
3. **633行目**: `core.completion` モジュールの呼び出し
4. **651行目**: `core.completion` 関数実行
5. **663-720行目**: レスポンスアイテムの構築

#### Step 3: コア補完ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | completion.lua | `script/core/completion/completion.lua` | 補完処理のメインロジック |
| 3-2 | keyword.lua | `script/core/completion/keyword.lua` | キーワード補完 |
| 3-3 | auto-require.lua | `script/core/completion/auto-require.lua` | 自動require補完 |
| 3-4 | postfix.lua | `script/core/completion/postfix.lua` | 後置補完 |

**主要処理フロー（completion.lua）**:
- **346-412行目**: `checkLocal` - ローカル変数補完
- **414-449行目**: `checkModule` - 自動requireモジュール補完
- **672-676行目**: `checkGlobal` - グローバル変数補完
- **680-688行目**: `checkField` - フィールドアクセス補完
- **807-877行目**: `checkKeyWord` - キーワード補完
- **2379-2397行目**: `completion` - メイン補完関数
- **2400-2403行目**: `resolve` - 補完アイテム解決

#### Step 4: 補助モジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | look-backward.lua | `script/core/look-backward.lua` | 後方参照ユーティリティ |
| 4-2 | matchkey.lua | `script/core/matchkey.lua` | キーマッチングロジック |

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

```
textDocument/completion (provider.lua:621)
    │
    ├─ config.get('Lua.completion.enable')
    │
    ├─ workspace.isReady(uri)
    │
    ├─ files.getState(uri)
    │
    └─ core.completion(uri, pos, triggerCharacter)
           │
           ├─ tryCompletions()
           │      │
           │      ├─ getComment() → tryLuaDoc()
           │      │
           │      ├─ postfix()
           │      │
           │      ├─ tryTable()
           │      │
           │      ├─ trySpecial()
           │      │      ├─ checkUri()
           │      │      ├─ checkLenPlusOne()
           │      │      └─ checkEqualEnum()
           │      │
           │      ├─ tryCallArg()
           │      │
           │      ├─ tryArray()
           │      │
           │      ├─ tryWord()
           │      │      ├─ checkField()
           │      │      ├─ checkLocal()
           │      │      ├─ checkGlobal()
           │      │      ├─ checkKeyWord()
           │      │      ├─ checkTableField()
           │      │      └─ checkModule()
           │      │
           │      ├─ tryIndex()
           │      │
           │      └─ trySymbol()
           │
           └─ return results
```

### データフロー図

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

textDocument.uri    ───▶ files.getState(uri)     ───▶  AST State
position            ───▶ converter.unpackPosition ───▶  内部位置
triggerCharacter    ───▶ トリガー判定            ───▶  補完種別
                         │
                         ▼
                    checkLocal/Global/Field      ───▶  候補リスト
                    checkKeyWord
                    checkModule
                         │
                         ▼
                    スコアリング・ソート          ───▶  ソート済みリスト
                         │
                         ▼
                    アイテム構築                  ───▶  CompletionItem[]
                         │
                         ▼
                    response構築                  ───▶  LSP Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPプロバイダー・エントリーポイント |
| init.lua | `script/core/completion/init.lua` | ソース | 補完モジュールエントリー |
| completion.lua | `script/core/completion/completion.lua` | ソース | 補完処理のメインロジック |
| keyword.lua | `script/core/completion/keyword.lua` | ソース | キーワード補完定義 |
| auto-require.lua | `script/core/completion/auto-require.lua` | ソース | 自動require機能 |
| postfix.lua | `script/core/completion/postfix.lua` | ソース | 後置補完機能 |
| matchkey.lua | `script/core/matchkey.lua` | ソース | キーマッチング |
| look-backward.lua | `script/core/look-backward.lua` | ソース | 後方参照ユーティリティ |
| hover/name.lua | `script/core/hover/name.lua` | ソース | 名前取得（補完ラベル用） |
| hover/args.lua | `script/core/hover/args.lua` | ソース | 引数取得（スニペット用） |
| define.lua | `script/proto/define.lua` | ソース | 定数定義 |
| converter.lua | `script/proto/converter.lua` | ソース | LSP位置変換 |
