# 機能設計書 39-バージョン管理状態をガターに表示

## 概要

本ドキュメントは、Doom Emacsにおけるバージョン管理状態をガターに表示する機能の設計を記載する。この機能は、diff-hlパッケージを使用して、Git等のバージョン管理システムでの変更箇所（追加、削除、変更行）をフリンジ領域に色分け表示する。

### 本機能の処理概要

**業務上の目的・背景**：コードの変更状況をリアルタイムに把握することは、効率的な開発において重要である。VC Gutter機能は、バッファ内の各行がバージョン管理上どのような状態（追加、変更、削除）にあるかを視覚的に表示し、変更の確認、ハンクの取り消し、ステージングなどの操作を支援する。

**機能の利用シーン**：
- コード編集中に変更箇所を確認する場合
- 変更を取り消す（リバート）場合
- 変更をステージングする場合
- Diredでディレクトリの変更状態を確認する場合
- Magit操作後に変更状態を確認する場合

**主要な処理内容**：
1. diff-hlパッケージの初期化と設定
2. グローバルモードによる自動有効化
3. フリンジビットマップのカスタマイズ（+prettyフラグ時）
4. Flydiffモードによるリアルタイム更新
5. Magit連携による操作後の更新
6. ハンク操作（ステージ、リバート、次/前へ移動）

**関連システム・外部連携**：
- diff-hlパッケージ
- Gitおよびその他のVCシステム
- Magit

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | VC Gutter | 主機能 | Git差分行の色分け表示 |

## 機能種別

UI表示 / バージョン管理支援

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| diff-hl-global-modes | list | No | diff-hlを有効にするモード | デフォルトで除外モードを指定 |
| diff-hl-flydiff-delay | float | No | Flydiff更新遅延（秒） | 0.5 |

### 入力データソース

- バッファの内容
- Gitリポジトリの状態
- VCファイルプロパティ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| フリンジ表示 | bitmap | 変更状態を示すビットマップ |
| 変更ハイライト | face | 追加（緑）、削除（赤）、変更（青/黄）の色分け |

### 出力先

ウィンドウのフリンジ領域（左または右）

## 処理フロー

### 処理シーケンス

```
1. doom-first-file-hook で global-diff-hl-mode 有効化
   └─ 最初のファイル読み込み時
2. バッファごとの diff-hl-mode 有効化
   └─ vc-dir-mode でも有効化
3. Flydiff モードの有効化（macOS以外）
   └─ リアルタイム更新
4. 変更検出とフリンジ表示
   └─ diff-hl-update による更新
5. ユーザー操作への応答
   └─ ハンク操作コマンド
```

### フローチャート

```mermaid
flowchart TD
    A[ファイルオープン] --> B[doom-first-file-hook]
    B --> C[global-diff-hl-mode]
    C --> D[diff-hl-mode有効化]
    D --> E{macOS?}
    E -->|Yes| F[Flydiff無効]
    E -->|No| G[diff-hl-flydiff-mode有効]
    F --> H[保存時のみ更新]
    G --> I[リアルタイム更新]
    H --> J{変更検出?}
    I --> J
    J -->|Yes| K[フリンジにビットマップ表示]
    J -->|No| L[表示なし]
    K --> M[ユーザー操作待機]
    M -->|stage| N[diff-hl-stage-current-hunk]
    M -->|revert| O[diff-hl-revert-hunk]
    M -->|next/prev| P[diff-hl-next/previous-hunk]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-1 | 除外モード | image-mode、pdf-view-modeでは無効 | diff-hl-global-modes |
| BR-39-2 | Flydiff遅延 | 0.5秒の遅延で更新 | diff-hl-flydiff-delay = 0.5 |
| BR-39-3 | 非同期更新 | Emacs 30以降またはスレッドで非同期更新 | diff-hl-update-async |
| BR-39-4 | ステージ非表示 | ステージ済み変更は表示しない | diff-hl-show-staged-changes = nil |
| BR-39-5 | histogramアルゴリズム | より高速なdiffアルゴリズムを使用 | vc-git-diff-switches |
| BR-39-6 | macOSでのFlydiff無効 | macOSではプロセス管理の問題でFlydiff無効 | featurep :system 'macos |
| BR-39-7 | Flycheck右フリンジ | +prettyフラグ時、Flycheckは右フリンジを使用 | modulep! +pretty |

### 計算ロジック

+prettyフラグ時のビットマップサイズ計算:
- 高さ = (frame-char-height * scale) + line-spacing
- 幅 = min(fringe-width, diff-hl-bmp-max-width) / 2

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | TRAMPプロンプト | リモートファイルでの一時ファイル作成 | tramp-allow-unsafe-temporary-files設定 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 編集操作を妨げないこと
- 非同期更新によるUI応答性の維持
- histogramアルゴリズムによるdiff高速化

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

特になし

## 備考

- diff-hlパッケージのピン留めバージョン: 3eefe68941933c8549049502007411ed2bf70387
- +prettyフラグでスリムなビットマップスタイルを使用

---

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

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

### 推奨読解順序

#### Step 1: パッケージ定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | packages.el | `modules/ui/vc-gutter/packages.el` | diff-hlパッケージの依存定義 |

**読解のコツ**: `:pin`でコミットハッシュが固定されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.el | `modules/ui/vc-gutter/config.el` | diff-hlの設定 |

**主要処理フロー**:
- **10-59行目**: +prettyフラグ時のビットマップカスタマイズ
  - **11行目**: fringe-mode設定（8ピクセル）
  - **14-37行目**: `+vc-gutter-define-thin-bitmaps-a`アドバイス
  - **38-42行目**: `+vc-gutter-type-at-pos-fn`関数
  - **45-50行目**: フェイスの透明化
  - **54-58行目**: Flycheck右フリンジ設定
- **65-68行目**: `use-package!`によるdiff-hl基本設定
- **70-78行目**: diredモード用フック
- **80-85行目**: macOS以外でのFlydiff有効化
- **88行目**: ポップアップルール設定
- **90-98行目**: 各種設定値
- **105-108行目**: TRAMP対策
- **111-122行目**: Evilキーマップ
- **125-140行目**: ESC/ウィンドウ切り替え時の更新フック
- **142-143行目**: Magit連携
- **147-155行目**: リバートポップアップのサイズ調整
- **158-163行目**: Evilインサートモード終了時の更新
- **167-172行目**: リバート時のカーソル位置保持

#### Step 3: autoload関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | diff-hl.el | `modules/ui/vc-gutter/autoload/diff-hl.el` | ハンク操作関数 |

**主要処理フロー**:
- **4行目**: `+vc-gutter/stage-hunk`（ステージング）
- **6行目**: `+vc-gutter/next-hunk`（次のハンクへ）
- **8行目**: `+vc-gutter/previous-hunk`（前のハンクへ）
- **12-16行目**: `+vc-gutter/revert-hunk`（リバート）
- **19-22行目**: `+vc-gutter/save-and-revert-hunk`（確認なしリバート）

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

```
doom-first-file-hook
    │
    └─ global-diff-hl-mode
           │
           ├─ diff-hl-mode (各バッファ)
           │      │
           │      └─ diff-hl-flydiff-mode (macOS以外)
           │
           ├─ diff-hl-dired-mode (diredバッファ)
           │
           └─ diff-hl-update
                  │
                  ├─ vc-git-diff (差分取得)
                  │
                  └─ フリンジビットマップ表示
                         │
                         └─ +vc-gutter-define-thin-bitmaps-a (+pretty時)

ユーザー操作
    │
    ├─ +vc-gutter/stage-hunk
    │      └─ diff-hl-stage-current-hunk
    │
    ├─ +vc-gutter/revert-hunk
    │      └─ diff-hl-revert-hunk
    │
    └─ +vc-gutter/next-hunk / +vc-gutter/previous-hunk
           └─ diff-hl-next-hunk / diff-hl-previous-hunk
```

### データフロー図

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

バッファ内容 ───────▶ diff計算 ──────────▶ 変更ハンク検出
    │                    │
Git状態 ────────────▶ vc-git-diff ─────▶ 差分データ
    │                    │
差分データ ─────────▶ ビットマップ生成 ─▶ フリンジ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/ui/vc-gutter/config.el` | ソース | diff-hl設定 |
| diff-hl.el | `modules/ui/vc-gutter/autoload/diff-hl.el` | ソース | ハンク操作関数 |
| packages.el | `modules/ui/vc-gutter/packages.el` | 設定 | 依存パッケージ定義 |
