# 画面設計書 24-入力時フォーマット

## 概要

本ドキュメントは、Lua Language Serverにおける「入力時フォーマット」機能の画面設計書です。LSPプロトコルの `textDocument/onTypeFormatting` リクエストに対応し、タイピング時の自動整形を実行します。

### 本画面の処理概要

入力時フォーマット機能は、特定の文字（改行文字）を入力した際に、自動的にコードの整形を行う機能です。主に改行時のインデント調整を行います。

**業務上の目的・背景**：コーディング中にリアルタイムでフォーマットを適用することで、開発者が手動でインデントを調整する手間を省きます。特にLuaのブロック構造（if-then-end、function-end等）において、適切なインデントレベルを自動的に維持することで、コードの可読性と一貫性を保ちます。これにより、開発者はロジックの記述に集中でき、フォーマットの煩わしさから解放されます。

**画面へのアクセス方法**：エディタ（VS Code等）でコードを記述中に、トリガー文字（改行）を入力すると自動的にこの機能が呼び出されます。ユーザーが明示的に実行する操作は不要で、タイピング中にシームレスに動作します。

**主要な操作・処理内容**：
1. ユーザーがトリガー文字（`\n`）を入力
2. エディタが `textDocument/onTypeFormatting` リクエストを送信
3. `Lua.typeFormat.config` 設定を取得
4. code_formatモジュールのtype_format関数を使用してフォーマット実行
5. 整形結果をTextEditとしてエディタに返却

**画面遷移**：独立した機能として動作し、特定の画面遷移はありません。フォーマット結果はカーソル位置周辺に直接反映されます。

**権限による表示制御**：特別な権限制御はありません。タイピング時に自動的に実行されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 41 | 入力時フォーマット (textDocument/onTypeFormatting) | 主機能 | タイピング時の自動整形を実行する主処理 |

## 画面種別

LSP機能（入力時自動フォーマット）

## URL/ルーティング

LSPメソッド: `textDocument/onTypeFormatting`

## 入出力項目

### 入力パラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument | TextDocumentIdentifier | はい | 対象ドキュメントの識別子 |
| position | Position | はい | 入力時のカーソル位置 |
| ch | string | はい | 入力されたトリガー文字 |
| options | FormattingOptions | はい | フォーマットオプション |

### 出力パラメータ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| edits | TextEdit[] | 適用するテキスト編集のリスト |
| edits[].range | Range | 編集範囲 |
| edits[].newText | string | 整形後のテキスト |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| range | Range | 編集対象範囲 |
| newText | string | 整形後のコード（タブはスペースに変換される場合あり） |

## イベント仕様

### 1-入力時フォーマット要求

1. ユーザーが改行文字を入力
2. エディタが `textDocument/onTypeFormatting` リクエストを送信
3. サーバーがトリガー文字（`\n`）を確認
4. `Lua.typeFormat.config` 設定を取得
5. code_formatモジュールのtype_format関数でフォーマット実行
6. 整形結果をTextEdit配列として返却

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 入力時フォーマット要求 | - | - | データベース操作なし（読み取り専用） |

## メッセージ仕様

| メッセージID | 種別 | 表示内容 | 発生条件 |
|-------------|------|----------|----------|
| - | - | - | 通常メッセージは表示されない |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| code_formatモジュールが利用不可 | nullを返却 |
| ファイル状態が取得できない | nullを返却 |
| トリガー文字が改行以外 | 処理をスキップ |
| TESTモードが有効 | nullを返却 |

## 備考

- トリガー文字は `\n`（改行）のみ
- `Lua.typeFormat.config` でフォーマット設定をカスタマイズ可能
- タブ文字はオプションに応じてスペースに変換される（insertSpaces = true の場合）
- ワークスペースの準備完了を待ってから処理を実行
- abortByFileUpdate属性により、ファイル更新時にリクエストがキャンセルされる

---

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

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

### 推奨読解順序

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

LSPプロトコルで定義されるTextEdit型とFormattingOptions型の構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | type-formatting.lua | `script/core/type-formatting.lua` | 返却されるresults構造（22-27行目）を確認 |

**読解のコツ**: type_format関数はresultオブジェクトを返却し、newTextとrangeを含みます。

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

LSPリクエストハンドラがどのように呼び出されるかを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` | `textDocument/onTypeFormatting` ハンドラ（1335-1372行目）を確認 |

**主要処理フロー**:
1. **1335行目**: `m.register 'textDocument/onTypeFormatting'` でハンドラを登録
2. **1336-1341行目**: capabilityの登録（firstTriggerCharacter: '\n'）
3. **1345行目**: URIを取得
4. **1346行目**: ワークスペース準備完了を待機
5. **1353-1355行目**: core/type-formattingでフォーマット実行
6. **1359-1368行目**: タブをスペースに変換し、結果を返却

#### Step 3: コアフォーマット処理を理解する

実際の入力時フォーマット処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | type-formatting.lua | `script/core/type-formatting.lua` | 入力時フォーマット処理（1-49行目）を確認 |

**主要処理フロー**:
- **4-7行目**: typeFormat関数の定義、トリガー文字の確認
- **8-16行目**: code_formatモジュールのロードとファイル状態の取得
- **17-20行目**: 位置変換とtypeFormat設定の取得
- **20-21行目**: `codeFormat.type_format()` でフォーマット実行
- **22-28行目**: 結果をresultsに追加

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

```
textDocument/onTypeFormatting (provider.lua:1335-1372)
    │
    ├─ workspace.awaitReady(uri) - ワークスペース準備待機
    │
    ├─ progress.create() - 進捗表示
    │
    └─ core/type-formatting.lua (31-48行目)
           │
           ├─ typeFormat関数 (4-29行目)
           │      │
           │      ├─ config.get(uri, 'Lua.typeFormat.config')
           │      │
           │      └─ codeFormat.type_format(uri, text, line, character, options, typeFormatOptions)
           │
           └─ results[] を返却
```

### データフロー図

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

OnTypeFormattingRequest {      1. トリガー文字確認（'\n'）       TextEdit[] {
  textDocument,                2. ワークスペース準備待機           range: {
  position: {                  3. typeFormat設定取得                start, end
    line: 10,                  4. code_format.type_format()        },
    character: 0                  ├─ 現在行の解析                 newText: 整形後
  },                              └─ インデント調整             }
  ch: '\n',                    5. タブ→スペース変換
  options                      6. TextEdit生成
}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPリクエストハンドラの登録・処理 |
| type-formatting.lua | `script/core/type-formatting.lua` | ソース | 入力時フォーマット処理のコアロジック |
| converter.lua | `script/proto/converter.lua` | ソース | LSPプロトコル型変換・位置変換 |
| config.lua | `script/config.lua` | ソース | 設定値の管理（Lua.typeFormat.config） |
| files.lua | `script/files.lua` | ソース | ファイル状態の管理 |
