# 画面設計書 19-折りたたみ範囲

## 概要

本ドキュメントは、Lua Language Serverの「折りたたみ範囲（textDocument/foldingRange）」機能の画面設計書である。この機能は、コードの折りたたみ可能な範囲を提供する。

### 本画面の処理概要

この機能では、ドキュメント内の折りたたみ可能な範囲（関数、ブロック、コメント等）を特定し、その開始行と終了行を返却する。エディタはこの情報を使用して、コードの折りたたみ機能を提供する。

**業務上の目的・背景**：大規模なファイルでは、すべてのコードを一度に表示すると全体像の把握が困難になる。折りたたみ機能により、現在作業していない部分を非表示にし、注目したい部分に集中できる。特に関数定義やif/for等の制御構造を折りたたむことで、コードの構造を素早く把握できる。

**画面へのアクセス方法**：ファイルを開くと自動的に折りたたみ範囲情報が取得される。エディタの行番号の横に折りたたみアイコン（+/-）が表示され、クリックすることで折りたたみ/展開を切り替えられる。

**主要な操作・処理内容**：
1. ドキュメントのASTを取得する
2. 関数、制御構造（if/while/for/repeat）、テーブル、文字列、コメントを走査する
3. 各要素の開始位置と終了位置から折りたたみ範囲を生成する
4. region/endregionコメントによるカスタム折りたたみ範囲を処理する
5. LSP形式の折りたたみ範囲配列を返却する

**画面遷移**：折りたたみ範囲は表示のみの機能であり、他の機能への直接的な遷移はない。

**権限による表示制御**：特になし。LSPプロトコルレベルでの認証・権限管理は行わない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 42 | コード折りたたみ (textDocument/foldingRange) | 主機能 | コードの折りたたみ可能な範囲を提供する主処理 |

## 画面種別

LSP機能（折りたたみ情報提供）

## URL/ルーティング

LSPメソッド: `textDocument/foldingRange`

## 入出力項目

### 入力項目（リクエストパラメータ）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument | TextDocumentIdentifier | Yes | 対象ドキュメントのURI |

### 出力項目（レスポンス）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| foldingRanges | FoldingRange[] | 折りたたみ範囲配列 |

### FoldingRange構造

| 項目名 | 型 | 説明 |
|--------|-----|------|
| startLine | number | 開始行（0-based） |
| endLine | number | 終了行（0-based） |
| kind | string | 折りたたみ種別（region/comment） |

## 表示項目

| 表示項目 | 説明 |
|---------|------|
| 折りたたみアイコン | 行番号横の+/-アイコン |
| 折りたたみプレビュー | 折りたたみ時に表示される省略テキスト |

## イベント仕様

### 1-foldingRangeリクエスト処理

1. クライアントからtextDocument/foldingRangeリクエストを受信
2. ドキュメントのASTを取得
3. care関数テーブルに従って各種構造を走査
4. function/do/if/loop/in/while/repeat/table/stringの折りたたみ範囲を生成
5. コメント（comment.short/comment.long/comment.clong）の折りたたみ範囲を生成
6. region/endregionコメントのペアリングを処理
7. doc.class/doc.aliasの折りたたみ範囲を生成
8. 開始行と終了行が異なる範囲のみをフィルタリング
9. LSP形式に変換してレスポンスを返却

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

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

この機能はデータベース操作を行わない。ソースコードを解析するのみで、変更は行わない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| foldingRangeリクエスト | なし | SELECT（読み取り） | ソースコードの解析のみ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| - | 成功 | （折りたたみ範囲配列返却） | 正常終了時 |
| - | 成功 | null | 折りたたみ範囲がない場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが見つからない | nullを返却 |
| ASTの取得に失敗 | nullを返却 |
| ファイルが存在しない | nullを返却 |

## 備考

- 折りたたみ種別: region（コードブロック）、comment（コメント）
- regionコメント対応: `--region` / `--#region` で開始、`--endregion` / `--#endregion` で終了
- repeatブロックは`until`キーワードで終了するため、keyword配列が4要素の場合のみ処理
- hideLastLineフラグ: trueの場合、最終行を折りたたみ範囲に含める（doc.class/doc.alias等）
- 関数のbindDocsがある場合、ドキュメントコメントも折りたたみ対象となる
- 開始行と終了行が同じ場合は折りたたみ範囲として返却されない

---

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

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

### 推奨読解順序

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

まず、FoldingRangeの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | folding.lua | `script/core/folding.lua` (7-14行目) | 関数の折りたたみ処理 - 基本構造 |

**読解のコツ**: 折りたたみ範囲はstart（開始位置）、finish（終了位置）、kind（種別）、hideLastLine（最終行表示フラグ）で構成される。

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

処理の起点となるプロバイダー登録を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` (1142-1181行目) | textDocument/foldingRangeの登録 |

**主要処理フロー**:
1. **1142行目**: `m.register 'textDocument/foldingRange'`でハンドラー登録
2. **1148行目**: `core/folding`モジュールを呼び出し
3. **1158行目**: `core(uri)`で折りたたみ範囲を取得
4. **1164-1177行目**: 各範囲をLSP形式に変換

#### Step 3: コア処理を理解する

折りたたみ範囲生成のコアロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | folding.lua | `script/core/folding.lua` | 折りたたみ範囲生成の全体構造 |
| 3-2 | folding.lua | `script/core/folding.lua` (6-22行目) | care['function'] - 関数の折りたたみ |
| 3-3 | folding.lua | `script/core/folding.lua` (31-41行目) | care['if'] - if文の折りたたみ |
| 3-4 | folding.lua | `script/core/folding.lua` (66-79行目) | care['repeat'] - repeat文の折りたたみ |
| 3-5 | folding.lua | `script/core/folding.lua` (96-121行目) | care['comment.short'] - region/endregion処理 |
| 3-6 | folding.lua | `script/core/folding.lua` (138-155行目) | care['doc.class'] - LuaDocの折りたたみ |
| 3-7 | folding.lua | `script/core/folding.lua` (159-184行目) | メイン関数 |

**主要処理フロー**:
- **168-174行目**: guide.eachSourceでASTソースを走査し、care関数テーブルに対応する処理を実行
- **175-181行目**: state.commsでコメントを走査し、care関数テーブルに対応する処理を実行
- **96-121行目**: region/endregionコメントのスタックベースペアリング

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

```
textDocument/foldingRange (provider.lua:1142-1181)
    |
    +-- workspace.awaitReady (ワークスペース準備待機)
    |
    +-- files.exists (ファイル存在確認)
    |
    +-- files.getState (AST取得)
    |
    +-- core/folding (folding.lua:159-184)
           |
           +-- guide.eachSource (ASTソース走査)
           |      |
           |      +-- care['function'] (7-22行目)
           |      +-- care['do'] (23-30行目)
           |      +-- care['if'] (31-41行目)
           |      +-- care['loop'] (42-49行目)
           |      +-- care['in'] (50-57行目)
           |      +-- care['while'] (58-65行目)
           |      +-- care['repeat'] (66-79行目)
           |      +-- care['table'] (80-87行目)
           |      +-- care['string'] (88-95行目)
           |      +-- care['doc.class'] (138-146行目)
           |      +-- care['doc.alias'] (147-155行目)
           |
           +-- コメント走査 (175-181行目)
                  |
                  +-- care['comment.short'] (96-121行目)
                  |      +-- region/endregionペアリング
                  +-- care['comment.long'] (122-129行目)
                  +-- care['comment.clong'] (130-137行目)
```

### データフロー図

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

FoldingRangeParams             provider.lua                        FoldingRange[]
+------------------+           +------------------+                 +------------------+
| textDocument.uri |  ------>  | files.getState   |                 | startLine        |
+------------------+           +------------------+                 | endLine          |
                                      |                             | kind             |
                                      v                             +------------------+
                               folding.lua
                               +----------------------+
                               | guide.eachSource     |
                               |   care['function']   |  -------->
                               |   care['if']         |
                               |   care['table']      |
                               | コメント走査         |
                               |   care['comment.*']  |
                               |   region/endregion   |
                               +----------------------+
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPメソッドハンドラー登録 |
| folding.lua | `script/core/folding.lua` | ソース | 折りたたみ範囲生成コアロジック |
| converter.lua | `script/proto/converter.lua` | ソース | 位置変換処理 |
| files.lua | `script/files.lua` | ソース | ファイル管理・AST取得 |
| guide.lua | `script/parser/guide.lua` | ソース | AST操作ユーティリティ |
| utility.lua | `script/utility.lua` | ソース | 文字列トリム等のユーティリティ |
