# 機能設計書 35-ポップアップウィンドウ管理

## 概要

本ドキュメントは、Doom Emacsにおけるポップアップウィンドウ管理機能の設計を記載する。この機能は、一時的なバッファ（ヘルプ、コンパイル結果、補完候補等）を制御されたポップアップウィンドウで表示し、Emacsのウィンドウ管理を改善する。

### 本機能の処理概要

**業務上の目的・背景**：Emacsの標準ウィンドウ管理では、ヘルプバッファやコンパイル結果などの一時バッファがメインの作業領域を侵食し、ウィンドウレイアウトが乱れることが多い。ポップアップ管理システムは、これらの一時バッファを予測可能な位置とサイズで表示し、ESCキーで簡単に閉じられるようにすることで、作業効率を大幅に向上させる。

**機能の利用シーン**：
- ヘルプバッファの表示
- コンパイル結果の表示
- 補完候補の表示
- ターミナルバッファの表示
- undo-treeの表示
- Manページの表示

**主要な処理内容**：
1. display-buffer-alistを使用したポップアップルールの定義
2. ポップアップウィンドウの作成・表示・配置
3. TTL（Time To Live）による自動クローズ
4. ESCキーによるポップアップクローズ
5. ポップアップの記憶と復元
6. 各種パッケージとの統合ハック

**関連システム・外部連携**：
- Emacsのdisplay-buffer-alist
- 各種パッケージ（org, helm, evil, persp-mode等）

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | Popup | 主機能 | 一時的なバッファのポップアップ表示制御 |

## 機能種別

UI制御 / ウィンドウ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| predicate | string/function | Yes | バッファマッチング条件 | 正規表現または関数 |
| :side | symbol | No | 表示位置 | 'top/'bottom/'left/'right |
| :size | float/int/fn | No | ウィンドウサイズ | 0-1の浮動小数点または整数 |
| :slot | integer | No | 横方向の配置位置 | 整数 |
| :vslot | integer | No | 縦方向の配置位置 | 整数 |
| :ttl | int/bool/fn | No | 自動クローズまでの秒数 | 整数、t、nil、または関数 |
| :quit | bool/symbol/fn | No | ESCでの閉じ動作 | t/'other/'current/nil/関数 |
| :select | bool/fn | No | 表示後にフォーカス | t/nil/関数 |
| :modeline | bool/fn/list | No | モードライン表示 | t/nil/関数/フォーマット |

### 入力データソース

- バッファ名
- display-buffer呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| popup-window | window | 作成されたポップアップウィンドウ |
| window-parameters | alist | ポップアップ制御用のウィンドウパラメータ |

### 出力先

フレームの指定された位置（top/bottom/left/right）

## 処理フロー

### 処理シーケンス

```
1. display-buffer呼び出し
   └─ バッファ表示リクエスト
2. display-buffer-alistのマッチング
   └─ set-popup-rule!で定義されたルールを検索
3. ポップアップウィンドウの作成
   └─ +popup-display-buffer-stacked-side-window-fn
4. ウィンドウパラメータの設定
   └─ +popup--init でパラメータ設定
5. +popup-buffer-mode の有効化
   └─ ポップアップ固有の動作を有効化
6. フック実行
   └─ +popup-create-window-hook
```

### フローチャート

```mermaid
flowchart TD
    A[display-buffer呼び出し] --> B{ルールマッチ?}
    B -->|No| C[通常のウィンドウ表示]
    B -->|Yes| D[ポップアップルール取得]
    D --> E[ウィンドウ作成]
    E --> F[パラメータ設定]
    F --> G[+popup--init]
    G --> H[+popup-buffer-mode有効化]
    H --> I[フリンジ/マージン調整]
    I --> J[モードライン設定]
    J --> K{select設定?}
    K -->|Yes| L[ポップアップにフォーカス]
    K -->|No| M[元ウィンドウにフォーカス]
    L --> N[表示完了]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-35-1 | デフォルト位置 | 下部に表示（side = 'bottom） | デフォルト設定 |
| BR-35-2 | デフォルト高さ | ウィンドウの16%（height = 0.16） | デフォルト設定 |
| BR-35-3 | TTLデフォルト | 5秒後に自動クローズ | デフォルト設定 |
| BR-35-4 | ESCクローズ | ESCキーでポップアップをクローズ | quit = t |
| BR-35-5 | 同一スロット置換 | 同じslot/vslotのポップアップは置換 | slot/vslot一致時 |
| BR-35-6 | マージン幅 | ポップアップにはマージン1を設定 | +popup-margin-width = 1 |
| BR-35-7 | ヘルプバッファ | slot 2、vslot -8、サイズ0.42で右側表示 | ヘルプバッファ表示時 |
| BR-35-8 | コンパイルバッファ | vslot -2、サイズ0.3、TTL無し | コンパイル結果表示時 |

### 計算ロジック

- サイズが0-1の浮動小数点の場合、フレームサイズに対する割合として計算
- サイズが整数の場合、行数またはカラム数として使用

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

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

該当なし（データベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | サイドウィンドウエラー | サイドウィンドウの分割に失敗 | 既存ウィンドウを再利用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ポップアップの表示・非表示がスムーズであること
- 多数のルールがあっても検索が高速であること（正規表現はcase-sensitive）

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

特になし

## 備考

- +allフラグで全てのバッファをポップアップ対象にできる
- +defaultsフラグでDoomの標準ルールセットを有効化
- 各種パッケージとの統合のため+hacks.elにハックが含まれる

---

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

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

### 推奨読解順序

#### Step 1: 設定ファイルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/ui/popup/config.el` | ポップアップシステムの初期化と設定 |

**主要処理フロー**:
- **3-5行目**: `+popup-window-parameters`定義（カスタムパラメータリスト）
- **7-9行目**: `+popup-default-display-buffer-actions`定義
- **11-14行目**: `+popup-default-alist`定義（デフォルトalist）
- **16-21行目**: `+popup-default-parameters`定義
- **38-50行目**: `+popup-buffer-mode-map`定義（Evil ESCキー対応）
- **51-70行目**: `+popup-mode`定義（グローバルマイナーモード）
- **72-86行目**: `+popup-buffer-mode`定義（バッファローカルモード）
- **96-105行目**: `with-popup-rules!`マクロ
- **107-123行目**: `save-popups!`マクロ
- **129-167行目**: デフォルトポップアップルール定義

#### Step 2: ポップアップ操作関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | popup.el | `modules/ui/popup/autoload/popup.el` | ポップアップ操作関数 |

**主要処理フロー**:
- **5-11行目**: `+popup--remember`関数（ポップアップの記憶）
- **13-37行目**: `+popup--kill-buffer`関数（TTLによる自動クローズ）
- **39-82行目**: `+popup--delete-window`関数（ポップアップ削除処理）
- **149-166行目**: `+popup--init`関数（ポップアップ初期化）
- **173-180行目**: `+popup-buffer-p`関数（ポップアップバッファ判定）
- **183-190行目**: `+popup-window-p`関数（ポップアップウィンドウ判定）
- **193-212行目**: `+popup-buffer`関数（ポップアップ表示）
- **337-389行目**: `+popup/close`関数（ポップアップクローズ）
- **410-417行目**: `+popup/toggle`関数（トグル）
- **420-428行目**: `+popup/restore`関数（復元）
- **512-659行目**: `+popup-display-buffer-stacked-side-window-fn`関数（メイン表示関数）

#### Step 3: ルール設定関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | settings.el | `modules/ui/popup/autoload/settings.el` | ルール設定API |

**主要処理フロー**:
- **7-14行目**: `+popup-defaults`変数（デフォルト値定義）
- **17-38行目**: `+popup-make-rule`関数（ルール作成）
- **41-169行目**: `set-popup-rule!`関数（ルール定義API）

#### Step 4: パッケージ統合ハックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | +hacks.el | `modules/ui/popup/+hacks.el` | 各種パッケージとの統合 |

**主要処理フロー**:
- **29-36行目**: case-sensitiveマッチングのアドバイス
- **76-87行目**: eshell統合
- **91-115行目**: Evil統合
- **118-156行目**: help-mode統合
- **223-285行目**: Org統合

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

```
display-buffer
    │
    └─ display-buffer-alist マッチング
           │
           └─ +popup-display-buffer-stacked-side-window-fn
                  │
                  ├─ window--make-major-side-window (既存なし)
                  │      └─ ウィンドウ作成
                  │
                  └─ split-window (既存あり)
                         │
                         └─ +popup--init
                                │
                                ├─ set-window-parameter
                                ├─ set-window-dedicated-p
                                ├─ +popup-buffer-mode
                                └─ +popup-create-window-hook
                                       ├─ +popup-adjust-fringes-h
                                       └─ +popup-adjust-margins-h
```

### データフロー図

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

バッファ表示要求 ───▶ ルールマッチング ───▶ ポップアップ設定適用
    │                    │
ルール定義 ─────────▶ display-buffer-alist ─▶ ウィンドウ作成
    │                    │
ウィンドウパラメータ ─▶ +popup--init ───────▶ ポップアップ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/ui/popup/config.el` | ソース | メイン設定とモード定義 |
| popup.el | `modules/ui/popup/autoload/popup.el` | ソース | ポップアップ操作関数 |
| settings.el | `modules/ui/popup/autoload/settings.el` | ソース | ルール設定API |
| +hacks.el | `modules/ui/popup/+hacks.el` | ソース | パッケージ統合ハック |
| test-popup.el | `modules/ui/popup/test/test-popup.el` | テスト | テストコード |
