# 画面設計書 22-フォーマット

## 概要

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

### 本画面の処理概要

フォーマット機能は、Luaソースコード全体を自動的に整形し、一貫したコーディングスタイルを適用する機能です。外部のcode_formatモジュールと連携してコード整形を実行します。

**業務上の目的・背景**：チーム開発において、一貫したコードスタイルを維持することは、コードの可読性向上とレビュー効率化に重要です。手動でのインデント調整や空白の整理は時間がかかり、エラーが発生しやすいため、自動フォーマット機能により開発者の生産性を向上させます。また、.editorconfigファイルによるプロジェクト固有の設定をサポートすることで、プロジェクト間での設定共有が容易になります。

**画面へのアクセス方法**：エディタ（VS Code等）で、以下の方法でフォーマット機能を呼び出します：
- ショートカットキー（Windows: Shift+Alt+F、Mac: Shift+Option+F）
- コマンドパレットから「Format Document」を実行
- 保存時自動フォーマット設定が有効な場合、ファイル保存時に自動実行

**主要な操作・処理内容**：
1. エディタからフォーマットリクエストを受信
2. `Lua.format.enable` 設定を確認（無効な場合は処理をスキップ）
3. .editorconfigファイルから設定を読み込み
4. code_formatモジュールを使用してコードを整形
5. 整形結果をTextEditとしてエディタに返却

**画面遷移**：独立した機能として動作し、特定の画面遷移はありません。フォーマット結果は現在のエディタ画面に直接反映されます。

**権限による表示制御**：特別な権限制御はありません。ただし、`Lua.format.enable` 設定がfalseの場合は機能が無効化されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 39 | ドキュメントフォーマット (textDocument/formatting) | 主機能 | ドキュメント全体のコード整形を実行する主処理 |

## 画面種別

LSP機能（コードフォーマット）

## URL/ルーティング

LSPメソッド: `textDocument/formatting`

## 入出力項目

### 入力パラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument | TextDocumentIdentifier | はい | 対象ドキュメントの識別子 |
| options | FormattingOptions | はい | フォーマットオプション |
| options.tabSize | number | はい | タブサイズ |
| options.insertSpaces | boolean | はい | スペースをタブの代わりに挿入するか |

### 出力パラメータ

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

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| range | Range | 編集対象範囲（ドキュメント全体） |
| newText | string | 整形後のコード |

## イベント仕様

### 1-フォーマット要求

1. エディタが `textDocument/formatting` リクエストを送信
2. サーバーが `Lua.format.enable` 設定を確認
3. provider/formatting.lua で.editorconfig設定を読み込み
4. code_formatモジュールでコードを整形
5. 整形結果をTextEdit配列として返却

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

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

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

## メッセージ仕様

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

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| Lua.format.enable が false | nullを返却（フォーマットをスキップ） |
| code_formatモジュールが利用不可 | nullを返却 |
| フォーマット処理でエラー | エラーログを出力し、nullを返却 |
| 整形前後でテキストが同じ | nullを返却（変更なし） |

## 備考

- code_formatは外部のLuaフォーマッターモジュール（C++実装）
- .editorconfigファイルによるプロジェクト固有の設定をサポート
- `Lua.format.defaultConfig` で初期設定をカスタマイズ可能
- 非標準シンボル（`//` コメント等）のサポートも設定可能

---

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

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

### 推奨読解順序

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

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

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

**読解のコツ**: TextEdit は range（編集範囲）と text（新しいテキスト）のペアで構成されます。

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

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

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

**主要処理フロー**:
1. **1259行目**: `m.register 'textDocument/formatting'` でハンドラを登録
2. **1265行目**: URIを取得
3. **1272行目**: `Lua.format.enable` 設定を確認
4. **1276-1277行目**: provider/formatting の設定更新
5. **1279-1280行目**: core/formattingでフォーマット実行
6. **1286-1291行目**: 結果をTextEdit配列に変換

#### Step 3: 設定読み込み処理を理解する

.editorconfigファイルからの設定読み込み処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | formatting.lua | `script/provider/formatting.lua` | updateConfig関数（41-76行目）の設定読み込みロジックを確認 |

**主要処理フロー**:
- **42-46行目**: デフォルト設定の初期化（初回のみ）
- **49-64行目**: ディレクトリを遡りながら.editorconfigを検索
- **60-63行目**: 見つかった.editorconfigをcode_formatに登録

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

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

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

**主要処理フロー**:
- **5-8行目**: code_formatモジュールのロード（失敗時は早期リターン）
- **14行目**: `codeFormat.format(uri, text, options)` でフォーマット実行
- **16-22行目**: エラーハンドリング
- **24-26行目**: 変更がない場合はnullを返却
- **28-33行目**: TextEditを構築して返却

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

```
textDocument/formatting (provider.lua:1259-1295)
    │
    ├─ config.get(uri, 'Lua.format.enable') - 設定確認
    │
    ├─ pformatting.updateConfig(uri) (provider/formatting.lua:41-76)
    │      │
    │      ├─ codeFormat.set_default_config() - 初回設定
    │      │
    │      └─ codeFormat.update_config() - .editorconfig読み込み
    │
    └─ core/formatting.lua (4-35行目)
           │
           ├─ codeFormat.format(uri, text, options)
           │
           └─ TextEdit[] を返却
```

### データフロー図

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

FormattingRequest {       1. 設定確認                         TextEdit[] {
  textDocument,           2. .editorconfig読み込み             range: 全体,
  options                 3. code_format.format()              newText: 整形後
}                            ├─ 字句解析                      }
                             ├─ 構文解析
                             └─ 整形規則適用
                          4. TextEdit生成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPリクエストハンドラの登録・処理 |
| formatting.lua | `script/core/formatting.lua` | ソース | フォーマット処理のコアロジック |
| formatting.lua | `script/provider/formatting.lua` | ソース | .editorconfig設定の読み込み・管理 |
| config.lua | `script/config.lua` | ソース | 設定値の管理 |
| converter.lua | `script/proto/converter.lua` | ソース | LSPプロトコル型変換 |
