# 画面設計書 23-範囲フォーマット

## 概要

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

### 本画面の処理概要

範囲フォーマット機能は、ユーザーが選択したコード範囲のみを自動的に整形する機能です。ドキュメント全体ではなく、特定の部分だけをフォーマットしたい場合に使用します。

**業務上の目的・背景**：大規模なコードベースでは、ファイル全体のフォーマットが不要な場合や、特定の変更箇所のみをスタイルに合わせて整形したい場合があります。範囲フォーマット機能により、変更した部分のみを素早く整形でき、差分レビューの際にも必要最小限の変更に抑えることができます。これにより、コードレビューの効率化とコミット履歴のクリーンな維持が可能になります。

**画面へのアクセス方法**：エディタ（VS Code等）で、以下の方法で範囲フォーマット機能を呼び出します：
- コードを選択した状態でショートカットキー（Windows: Ctrl+K Ctrl+F、Mac: Cmd+K Cmd+F）
- コードを選択した状態で右クリックメニューから「Format Selection」を選択
- コマンドパレットから「Format Selection」を実行

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

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

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 40 | 範囲フォーマット (textDocument/rangeFormatting) | 主機能 | 選択範囲のコード整形を実行する主処理 |

## 画面種別

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

## URL/ルーティング

LSPメソッド: `textDocument/rangeFormatting`

## 入出力項目

### 入力パラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument | TextDocumentIdentifier | はい | 対象ドキュメントの識別子 |
| range | Range | はい | フォーマット対象の範囲 |
| range.start | Position | はい | 開始位置（line, character） |
| range.end | Position | はい | 終了位置（line, character） |
| options | FormattingOptions | はい | フォーマットオプション |

### 出力パラメータ

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

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| range | Range | 編集対象範囲（フォーマット適用行） |
| newText | string | 整形後のコード |

## イベント仕様

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

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

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

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

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

## メッセージ仕様

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

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| Lua.format.enable が false | nullを返却（フォーマットをスキップ） |
| code_formatモジュールが利用不可 | nullを返却 |
| フォーマット処理でエラー | エラーログを出力し、nullを返却 |
| ファイル状態が取得できない | nullを返却 |

## 備考

- code_formatのrange_format関数を使用して範囲指定のフォーマットを実行
- 開始行と終了行はcode_formatモジュールから返却される（実際の整形範囲）
- ドキュメント全体フォーマット（No.22）と同様に.editorconfigの設定を反映
- `Lua.format.enable` 設定でフォーマット機能全体の有効/無効を制御

---

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

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

### 推奨読解順序

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

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

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

**読解のコツ**: range_format関数は整形後のテキストに加え、実際に整形が適用された開始行と終了行を返却します。

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

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

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

**主要処理フロー**:
1. **1297行目**: `m.register 'textDocument/rangeFormatting'` でハンドラを登録
2. **1303行目**: URIを取得
3. **1310行目**: `Lua.format.enable` 設定を確認
4. **1314-1315行目**: provider/formatting の設定更新
5. **1317-1318行目**: core/rangeformattingでフォーマット実行
6. **1324-1329行目**: 結果をTextEdit配列に変換

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

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

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

**主要処理フロー**:
- **5-9行目**: ファイル状態の取得とcode_formatモジュールのロード
- **10-13行目**: code_formatが利用不可の場合は早期リターン
- **15-16行目**: `codeFormat.range_format()` で範囲フォーマット実行
- **18-24行目**: エラーハンドリング
- **26-31行目**: TextEditを構築して返却

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

```
textDocument/rangeFormatting (provider.lua:1297-1333)
    │
    ├─ config.get(uri, 'Lua.format.enable') - 設定確認
    │
    ├─ pformatting.updateConfig(uri) (provider/formatting.lua:41-76)
    │      │
    │      └─ .editorconfig設定読み込み
    │
    └─ core/rangeformatting.lua (1-33行目)
           │
           ├─ codeFormat.range_format(uri, text, startLine, endLine, options)
           │
           └─ TextEdit[] を返却
```

### データフロー図

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

RangeFormattingRequest {       1. 設定確認                      TextEdit[] {
  textDocument,                2. .editorconfig読み込み           range: {
  range: {                     3. code_format.range_format()        start: startLine,
    start: {line: 5},             ├─ 範囲内の字句解析                end: endLine
    end: {line: 10}               ├─ 構文解析                      },
  },                              └─ 整形規則適用                 newText: 整形後
  options                      4. TextEdit生成                  }
}
```

### 関連ファイル一覧

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