# 機能設計書 45-コード折りたたみ

## 概要

本ドキュメントは、Doom Emacsにおけるコード折りたたみ機能の設計仕様を記述する。hideshow、vimish-fold、outline-mode、treesit-foldの4つのフォールディングシステムを統合し、一貫したインターフェースでコードブロックの展開・折りたたみを行う。

### 本機能の処理概要

**業務上の目的・背景**：大規模なソースコードを読む際、全ての詳細を同時に見る必要はなく、関数定義やクラス定義などの構造的な単位で折りたたんで概要を把握したい場合がある。本機能は、複数のフォールディングバックエンドを統合し、言語やコンテキストに応じた最適な折りたたみを提供する。

**機能の利用シーン**：
- 大規模なソースファイルの構造を把握する場合
- 関数やクラスの実装詳細を一時的に隠す場合
- 特定のコードブロックのみに集中したい場合
- カスタム折りたたみ領域を定義したい場合

**主要な処理内容**：
1. コードブロックの折りたたみ・展開（+fold/toggle）
2. 全ての折りたたみの展開・折りたたみ（+fold/open-all, +fold/close-all）
3. 再帰的な展開（+fold/open-rec）
4. 折りたたみ間のナビゲーション（+fold/next, +fold/previous）
5. カスタム折りたたみ領域の作成（vimish-fold）
6. Tree-sitterベースの折りたたみ（treesit-fold）

**関連システム・外部連携**：
- hideshow: Emacs組み込みのフォールディング
- vimish-fold: カスタム折りたたみ領域
- outline-mode: アウトラインベースのフォールディング
- treesit-fold: Tree-sitterベースのフォールディング
- evil-vimish-fold: Evil統合

**権限による制御**：特になし（全ユーザーが利用可能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面関連なし（エディタ機能） |

## 機能種別

テキスト表示制御 / ナビゲーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| +fold-ellipsis | string | No | 折りたたみ表示文字列（デフォルト: " [...] "） | - |
| count | integer | No | ナビゲーションでスキップする折りたたみ数 | - |
| level | integer | No | 折りたたみレベル | 正の整数 |

### 入力データソース

- ユーザーのキーボード入力（Evilキーバインド: za, zo, zc等）
- 現在のカーソル位置

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| overlay | overlay | 折りたたみを表すオーバーレイ |
| display | string | 折りたたみ表示（ellipsis） |

### 出力先

- バッファ表示（折りたたみオーバーレイ）
- フリンジ（折りたたみインジケータ）

## 処理フロー

### 処理シーケンス

```
1. 折りたたみコマンド呼び出し（+fold/toggle等）
2. フォールディングシステム判定
   ├─ vimish-fold: カスタム折りたたみがあるか
   ├─ outline: 見出し行か
   ├─ treesit-fold: Tree-sitter利用可能か
   └─ hideshow: ブロック開始位置か
3. 対応するバックエンドの処理呼び出し
4. オーバーレイの表示更新
```

### フローチャート

```mermaid
flowchart TD
    A[折りたたみコマンド] --> B{システム判定}
    B -->|vimish-fold| C[vimish-fold-toggle]
    B -->|outline| D[outline-toggle-children]
    B -->|treesit-fold| E[treesit-fold-toggle]
    B -->|hideshow| F[hs-toggle-hiding]
    B -->|該当なし| G[何もしない]

    C --> H[表示更新]
    D --> H
    E --> H
    F --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | システム優先順位 | vimish-fold > outline > treesit-fold > hideshow | 常時 |
| BR-02 | 自動hs-minor-mode | hideshowコマンド実行時に自動でhs-minor-mode有効化 | hideshow使用時 |
| BR-03 | コメント非折りたたみ | hs-hide-allでコメントは折りたたまない | hs-hide-comments-when-hiding-all = nil |
| BR-04 | 折りたたみ永続化 | vimish-foldの折りたたみはセッション間で永続化 | vimish-fold使用時 |

### 計算ロジック

フォールディングシステム判定:
```elisp
(defun +fold--vimish-fold-p ()
  (and (featurep 'vimish-fold)
       (cl-some #'vimish-fold--vimish-overlay-p
                (overlays-at (point)))))

(defun +fold--hideshow-fold-p ()
  (when (+fold--ensure-hideshow-mode)
    (save-excursion
      (ignore-errors
        (or (funcall hs-looking-at-block-start-p-func)
            (funcall hs-find-block-beginning-func))))))
```

## データベース操作仕様

本機能はデータベースを使用しない。vimish-foldの永続化はファイルシステムに保存。

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 折りたたみ保存 | vimish-fold-dir | WRITE | カスタム折りたたみの永続化 |
| 折りたたみ復元 | vimish-fold-dir | READ | 保存された折りたたみの復元 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | user-error | 折りたたみ位置が見つからない | エラーメッセージ表示 |
| - | error | hs-minor-modeがサポートされないモード | 静かに失敗 |

### リトライ仕様

リトライ処理は実装されていない。

## トランザクション仕様

トランザクション処理は不要。

## パフォーマンス要件

- 折りたたみ操作: 即座
- 全展開/折りたたみ: バッファサイズに依存

## セキュリティ考慮事項

特になし。

## 備考

- Evilユーザーは`za`, `zo`, `zc`等のVim標準キーバインドが利用可能
- `zf`でカスタム折りたたみ領域を作成（vimish-fold）
- org-modeでは`+fold-ellipsis`がorg-ellipsisに適用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/editor/fold/config.el` | 変数定義、hideshow/vimish-fold設定 |

**読解のコツ**:
- **3-8行目**: `+fold-ellipsis`変数（折りたたみ表示文字列）
- **10-13行目**: `+fold-hideshow-folded-face`（折りたたみ表示のフェイス）
- **19-35行目**: Evilキーバインド設定

#### Step 2: コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | fold.el | `modules/editor/fold/autoload/fold.el` | 統合コマンド定義 |

**主要処理フロー**:
- **137-148行目**: `+fold/toggle`（トグル処理）
- **160-171行目**: `+fold/open`（展開処理）
- **174-183行目**: `+fold/close`（折りたたみ処理）
- **186-223行目**: `+fold/open-all`, `+fold/close-all`

#### Step 3: システム判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fold.el | `modules/editor/fold/autoload/fold.el` | 判定関数 |

**主要処理フロー**:
- **24-27行目**: `+fold--vimish-fold-p`
- **29-32行目**: `+fold--outline-fold-p`
- **34-42行目**: `+fold--hideshow-fold-p`
- **44-48行目**: `+fold--treesit-fold-p`

#### Step 4: hideshow拡張を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | config.el | `modules/editor/fold/config.el` | hs-special-modes-alist拡張 |

**主要処理フロー**:
- **61-93行目**: 追加言語のhideshow設定（yaml, ruby, latex等）

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

```
+fold/toggle (ユーザーコマンド)
    │
    ├─ +fold--vimish-fold-p
    │      └─ vimish-fold-toggle
    │
    ├─ +fold--outline-fold-p
    │      └─ outline-toggle-children
    │
    ├─ +fold--treesit-fold-p
    │      └─ treesit-fold-toggle
    │
    └─ +fold--hideshow-fold-p
           ├─ +fold--ensure-hideshow-mode
           │      └─ hs-minor-mode
           └─ hs-toggle-hiding

+fold/next (ナビゲーション)
    │
    ├─ hideshow invisible points検索
    │
    ├─ vimish-fold-next-fold
    │
    ├─ outline-next-visible-heading
    │
    └─ treesit-fold overlays検索
```

### データフロー図

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

ユーザー操作          ┌──────────────────────┐
(za, zo, zc等) ───▶  │ +fold/* コマンド      │
                      └──────────────────────┘
                               │
                               ▼
                      ┌──────────────────────┐
                      │ システム判定          │
                      │ (vimish/outline/     │
                      │  treesit/hideshow)   │
                      └──────────────────────┘
                               │
                               ▼
                      ┌──────────────────────┐
                      │ バックエンド処理      │ ───▶ オーバーレイ更新
                      └──────────────────────┘       フリンジ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/editor/fold/config.el` | ソース | モジュール設定、hideshow/vimish-fold設定 |
| fold.el | `modules/editor/fold/autoload/fold.el` | ソース | 統合コマンド、システム判定 |
| hideshow.el | `modules/editor/fold/autoload/hideshow.el` | ソース | hideshowヘルパー関数 |
| packages.el | `modules/editor/fold/packages.el` | 設定 | 依存パッケージ定義 |
