# 通知設計書 21-compilation-scroll-output

## 概要

本ドキュメントは、Doom Emacsにおけるコンパイル出力の自動スクロール機能（compilation-scroll-output）の通知設計を定義する。

### 本通知の処理概要

compilation-scroll-output通知は、コンパイルプロセスの実行中に出力バッファを自動的にスクロールし、ユーザーにリアルタイムでコンパイル状況を通知する機能である。

**業務上の目的・背景**：開発者がコードをコンパイルする際、コンパイル出力は長大になることが多い。すべての出力を手動でスクロールして確認するのは非効率であり、特にエラーが発生した場合、最初のエラー箇所を迅速に特定することが重要である。この通知機能により、開発者は最初のエラーが発生した時点で自動的にその箇所を確認でき、デバッグ効率が大幅に向上する。

**通知の送信タイミング**：コンパイルプロセスが実行され、出力がコンパイルバッファに書き込まれるたびに、継続的にスクロールが実行される。特に`first-error`設定では、最初のエラーが検出された時点でスクロールが停止し、その位置にフォーカスが当たる。

**通知の受信者**：コンパイルを実行した開発者本人。Emacsのウィンドウ内でコンパイルバッファを表示しているユーザーが対象。

**通知内容の概要**：コンパイル出力のリアルタイム表示。エラー、警告、情報メッセージがANSIカラーで色分けされて表示される。

**期待されるアクション**：最初のエラーが表示された時点で、開発者はエラー内容を確認し、対象のソースコードに移動して修正を行う。`compile-goto-error`等のコマンドでエラー箇所へジャンプすることが期待される。

## 通知種別

アプリ内通知（Emacsバッファ内表示）

## 送信仕様

### 基本情報

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

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

コンパイルを実行したバッファと関連付けられた`*compilation*`バッファに出力される。表示ウィンドウの決定は`display-buffer-alist`の設定に従う。

## 通知テンプレート

### バッファ内通知の場合

| 項目 | 内容 |
|-----|------|
| バッファ名 | `*compilation*`または`*Compile-Log*` |
| 表示形式 | ANSIカラー対応テキスト |
| モードライン | compilation-mode |

### 本文テンプレート

```
-*- mode: compilation; default-directory: "/project/path/" -*-
Compilation started at {timestamp}

{compiler-command}

{compilation-output}

Compilation {finished|exited abnormally|interrupted} at {timestamp}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| timestamp | コンパイル開始/終了時刻 | current-time | Yes |
| compiler-command | 実行されたコンパイルコマンド | compile-command | Yes |
| compilation-output | コンパイラの出力 | プロセス標準出力 | Yes |
| default-directory | コンパイル実行ディレクトリ | default-directory | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ユーザー操作 | compile/recompile実行 | compilation-mode有効 | M-x compile等でコンパイル開始 |
| フック | compilation-filter-hook | バッファ出力時 | 出力フィルタリング時にスクロール |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| compilation-scroll-output = nil | スクロール機能無効時 |
| バッファ非表示 | ウィンドウに表示されていない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[compile実行] --> B[compilation-start]
    B --> C[compilation-mode有効化]
    C --> D[プロセス出力受信]
    D --> E{compilation-filter-hook}
    E --> F[ANSI色変換]
    F --> G{compilation-scroll-output設定}
    G -->|first-error| H[最初のエラーまでスクロール]
    G -->|t| I[末尾までスクロール]
    G -->|nil| J[スクロールなし]
    H --> K[comint-truncate-buffer]
    I --> K
    J --> K
    K --> L{出力継続?}
    L -->|Yes| D
    L -->|No| M[終了]
```

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

### 参照テーブル一覧

該当なし（ファイルシステムベースの処理）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| プロセス異常終了 | コンパイラエラー | 終了ステータスをモードラインに表示 |
| バッファオーバーフロー | 出力過多 | comint-truncate-bufferで切り詰め |
| ANSI変換エラー | 不正なエスケープシーケンス | エラーを無視して継続 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（ユーザー操作に応じて即時実行）

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

- コンパイル出力にはソースコードパスが含まれる可能性があるため、画面共有時は注意が必要
- 環境変数やシークレットがビルドログに出力されないよう、ビルドスクリプト側での対策が必要

## 備考

- `compilation-scroll-output`は`first-error`に設定されており、最初のエラーで自動的にスクロールが停止する
- `compilation-always-kill`が`t`に設定されており、新規コンパイル開始時に既存プロセスは自動終了する
- Emacs 28以降では`ansi-color-compilation-filter`が使用され、それ以前は`doom-apply-ansi-color-to-compilation-buffer-h`が使用される

---

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

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

### 推奨読解順序

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

compilation-modeはEmacs組み込み機能であり、Doom Emacsでは設定のカスタマイズのみを行っている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | doom-ui.el | `lisp/doom-ui.el` | compilation-scroll-outputの設定値と関連フックの定義 |

**読解のコツ**: `(after! compile ...)`ブロック内の設定を中心に読む。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | doom-ui.el | `lisp/doom-ui.el` | compileパッケージのカスタマイズ |

**主要処理フロー**:
1. **410行目**: `(after! compile ...)` でcompileモード読み込み後に設定適用
2. **411行目**: `compilation-always-kill`を`t`に設定
3. **412行目**: `compilation-ask-about-save`を`nil`に設定
4. **413行目**: `compilation-scroll-output`を`'first-error`に設定
5. **414-417行目**: compilation-filter-hookにANSIカラー変換関数を追加
6. **420-421行目**: comint-truncate-bufferを追加してバッファ肥大化を防止

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | doom-ui.el | `lisp/doom-ui.el` | compilation-filter-hookの設定 |

**主要処理フロー**:
- **414-421行目**: 出力フィルタリングとバッファ管理

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

```
compile (Emacs組み込み)
    │
    ├─ compilation-start
    │      └─ compilation-mode
    │             └─ compilation-filter-hook
    │                    ├─ ansi-color-compilation-filter (Emacs 28+)
    │                    │  └─ doom-apply-ansi-color-to-compilation-buffer-h (Emacs 27)
    │                    │
    │                    └─ comint-truncate-buffer
    │
    └─ compilation-scroll-output (スクロール制御)
```

### データフロー図

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

compile-command ───▶ compilation-start ───▶ *compilation*バッファ
                            │
                            ▼
                     プロセス出力受信
                            │
                            ▼
                   compilation-filter-hook
                            │
                   ┌────────┴────────┐
                   ▼                 ▼
          ANSIカラー変換    バッファ切り詰め
                   │                 │
                   └────────┬────────┘
                            ▼
              compilation-scroll-output
                     (first-error)
                            │
                            ▼
                   最初のエラー位置で停止
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| doom-ui.el | `lisp/doom-ui.el` | ソース | compilation-modeのカスタマイズ設定 |
| +hacks.el | `modules/ui/popup/+hacks.el` | ソース | compilationバッファのポップアップ連携 |
