# 通知設計書 9-doom-switch-window-hook

## 概要

本ドキュメントは、Doom Emacsにおける`doom-switch-window-hook`機能の設計を記載する。このフックは、同一フレーム内でウィンドウ切り替えが発生した際に登録された関数を実行するための通知メカニズムである。

### 本通知の処理概要

doom-switch-window-hookは、同一フレーム内でウィンドウが切り替わった際に発火するカスタムフックである。ウィンドウ固有の処理（カーソル表示の変更、ウィンドウ固有のUIの更新など）を実装するための拡張ポイントを提供する。

**業務上の目的・背景**：Emacsでは複数のウィンドウで異なるバッファを表示できるが、フォーカスされているウィンドウに応じてUIを変更したい場合がある。例えば、非アクティブウィンドウでのカーソル非表示、アクティブウィンドウでのハイライト表示などが考えられる。doom-switch-window-hookは、このようなウィンドウフォーカス変更に応じた処理を容易に実装できるようにする。

**通知の送信タイミング**：`window-selection-change-functions`がトリガーされた際に、特定の条件（同一フレーム内での切り替え、ミニバッファでない等）を満たす場合に`doom-run-switch-window-hooks-h`が呼び出され、`doom-switch-window-hook`が実行される。

**通知の受信者**：`doom-switch-window-hook`に登録された関数群。ユーザーコードやパッケージ設定から追加可能。

**通知内容の概要**：フック関数に引数は渡されない。現在のウィンドウは`(selected-window)`で取得可能。

**期待されるアクション**：フック関数はウィンドウ切り替えに応じた処理（UIの更新、状態の同期など）を実行する。

## 通知種別

アプリ内通知（フック実行による内部通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 中 |
| リトライ | 無 |

### 送信先決定ロジック

`doom-switch-window-hook`に登録された全ての関数が順次実行される。

## 通知テンプレート

### フック実行の場合

| 項目 | 内容 |
|-----|------|
| 対象 | doom-switch-window-hookに登録された関数 |
| 引数 | なし |

### 本文テンプレート

該当なし（フック実行）

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| selected-window | 現在選択中のウィンドウ | (selected-window)で取得 | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 関数呼び出し | window-selection-change-functions | 下記条件を全て満たす | ウィンドウ選択変更 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| minibufferp | ミニバッファ選択時は抑止 |
| フレーム変更 | 異なるフレームへの移動時は抑止 |
| ミニバッファウィンドウからの移動 | ミニバッファウィンドウが前のウィンドウの場合は抑止 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ウィンドウ切り替え] --> B[window-selection-change-functions発火]
    B --> C[doom-run-switch-window-hooks-h]
    C --> D{ミニバッファ?}
    D -->|Yes| E[フック実行なし]
    D -->|No| F{同一フレーム?}
    F -->|No| E
    F -->|Yes| G{前ウィンドウがミニバッファ?}
    G -->|Yes| E
    G -->|No| H[gc-cons-threshold最大化]
    H --> I[run-hooks 'doom-switch-window-hook]
    I --> J[各フック関数実行]
    E --> K[終了]
    J --> K
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（Emacs Lisp変数のみ使用）

### 変数参照詳細

| 変数名 | 用途 | 取得条件 |
|--------|------|---------|
| doom-switch-window-hook | フック関数リスト | 常時参照可能 |
| gc-cons-threshold | GC閾値 | 一時的にmost-positive-fixnumに設定 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| フック関数内エラー | フック関数の実装エラー | run-hooksにより伝播 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限なし | ウィンドウ切り替えごとに実行（条件を満たす場合） |

### 配信時間帯

制限なし

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

- フック関数はローカルで実行され、外部通信はない
- パフォーマンス影響を考慮し、フック関数は軽量に実装すべき

## 備考

- `gc-cons-threshold`を一時的に最大化してGCによる遅延を防止
- `old-selected-frame`と`old-selected-window`を使用して、前の状態と比較
- ミニバッファ関連の操作は除外してノイズを削減

---

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

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

### 推奨読解順序

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

フック変数の定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | doom-ui.el | `lisp/doom-ui.el` | doom-switch-window-hook定義（93-94行目）を確認 |

**読解のコツ**: `defcustom`でカスタムフックを定義。ユーザーが関数を追加可能。

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

フック実行関数を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | doom-ui.el | `lisp/doom-ui.el` | doom-run-switch-window-hooks-h関数（110-116行目）を確認 |

**主要処理フロー**:
1. **110行目**: `doom-run-switch-window-hooks-h`関数定義
2. **111行目**: docstring「Trigger `doom-switch-window-hook' when selecting a window in the same frame.」
3. **112-114行目**: 抑止条件のチェック（ミニバッファ、フレーム変更、前ウィンドウがミニバッファ）
4. **115行目**: `gc-cons-threshold`を`most-positive-fixnum`に設定
5. **116行目**: `run-hooks 'doom-switch-window-hook`でフック実行

#### Step 3: フック登録処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | doom-ui.el | `lisp/doom-ui.el` | doom-init-ui-h関数内のフック登録（741行目）を確認 |

**主要処理フロー**:
- **741行目**: `window-selection-change-functions`に`doom-run-switch-window-hooks-h`を追加

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

```
[ウィンドウ切り替え]
    |
    +-- window-selection-change-functions
            |
            +-- doom-run-switch-window-hooks-h
                    |
                    +-- [条件チェック]
                    |       |
                    |       +-- minibufferp
                    |       +-- old-selected-frame比較
                    |       +-- old-selected-window比較
                    |
                    +-- [条件OK時]
                            |
                            +-- run-hooks 'doom-switch-window-hook
                                    |
                                    +-- [登録されたフック関数群]
```

### データフロー図

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

ウィンドウ切り替え ──▶ window-selection-change-functions
                              │
                              ▼
                    doom-run-switch-window-hooks-h
                              │
                              ▼
old-selected-frame ───▶ [フレーム比較]
                              │
old-selected-window ──▶ [ウィンドウ比較]
                              │
                              ▼
                    [条件を満たす場合]
                              │
                              ▼
                    run-hooks 'doom-switch-window-hook
                              │
                              ▼
                    [フック関数実行]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| doom-ui.el | `lisp/doom-ui.el` | ソース | doom-switch-window-hookの定義と実行処理 |
