# 画面設計書 31-Smooth Scroll

## 概要

本ドキュメントは、Doom Emacsのsmooth-scrollモジュールによって提供されるスムーズスクロール機能の画面設計について記載する。このモジュールはEmacs 29.1以降で利用可能なピクセル単位のスクロール機能を実現する。

### 本画面の処理概要

Smooth Scrollは、Emacsのスクロール体験を大幅に向上させるUI機能モジュールである。従来のEmacsでは行単位でスクロールが行われるため、特にトラックパッドやマウスホイール使用時にガタつきが発生していた。本モジュールはピクセル単位のスクロールを実現し、モダンなアプリケーションと同等のスムーズなスクロール体験を提供する。

**業務上の目的・背景**：Emacsのデフォルトスクロールは行単位で動作するため、特にトラックパッドやマウスホイールを使用する際にカクつきが発生する。これはコード閲覧や長文ドキュメントの編集時にユーザー体験を損なう原因となる。本モジュールは、ultra-scrollパッケージを使用してピクセル単位のスムーズスクロールを実現し、視覚的な快適性を向上させる。また、+interpolateフラグを有効にすることで、PgUp/PgDown等の大きな移動コマンドでも補間されたスムーズなスクロールアニメーションを提供する。

**画面へのアクセス方法**：本機能は画面ではなく、すべての編集バッファに適用されるUI動作である。Doom Emacsの設定ファイル（init.el）で`:ui smooth-scroll`モジュールを有効にすることで自動的に適用される。有効化後、最初の入力イベントまたは最初のファイル読み込み時にultra-scroll-modeが自動的に起動する。

**主要な操作・処理内容**：
1. トラックパッドスワイプ：ピクセル単位でバッファ内容をスムーズにスクロール
2. マウスホイールスクロール：ピクセル精度でスクロール位置を制御
3. PgUp/PgDown（+interpolate有効時）：目的位置まで補間アニメーションでスクロール
4. C-d/C-u（Evil使用時、+interpolate有効時）：半ページスクロールを補間アニメーションで実行

**画面遷移**：本機能は画面遷移を伴わない。すべてのバッファ（編集バッファ、ヘルプバッファ、コンパイル結果バッファなど）で動作するUI機能であり、他画面からの遷移元・遷移先という概念は適用されない。

**権限による表示制御**：本機能に権限による表示制御はない。モジュールが有効な場合、すべてのバッファで一律にスムーズスクロール機能が動作する。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | UI 設定 | 主機能 | スムーズスクロール制御、ピクセル単位スクロール処理 |

## 画面種別

UI機能（全バッファ適用型）

## URL/ルーティング

該当なし（EmacsはWebアプリケーションではないため、URL/ルーティングの概念は適用されない）

## 入出力項目

### 入力項目

| 項目名 | 型 | 説明 | 必須 |
|--------|------|------|------|
| スクロール入力イベント | scroll-event | トラックパッド/マウスホイールからの入力 | - |
| スクロールコマンド | command | scroll-up, scroll-down等のコマンド | - |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|------|------|
| バッファ表示位置 | point | スクロール後のバッファ表示位置 |
| ウィンドウスタート位置 | window-start | ウィンドウの先頭表示行 |

## 表示項目

本機能は表示項目を持たない。スクロール動作の挙動を変更するUI機能である。

## イベント仕様

### 1-トラックパッド/マウスホイールスクロール

**トリガー**：ユーザーがトラックパッドをスワイプ、またはマウスホイールを回転

**処理フロー**：
1. ultra-scroll-modeがスクロールイベントを受信
2. ピクセル単位でスクロール量を計算
3. バッファ表示位置をピクセル単位で更新
4. 画面を再描画

### 2-PgUp/PgDownスクロール（+interpolate有効時）

**トリガー**：ユーザーがPgUpまたはPgDownキーを押下

**処理フロー**：
1. good-scroll-modeがscroll-up/scroll-downコマンドをインターセプト
2. スクロール量をピクセル単位に変換（good-scroll--convert-line-to-step関数）
3. good-scroll-move関数で補間アニメーションを開始
4. タイマーによって段階的に表示位置を更新
5. 目的位置に到達後、アニメーション終了

### 3-Evil C-d/C-uスクロール（+interpolate有効時）

**トリガー**：Evilモードでユーザーが`C-d`（半ページ下）または`C-u`（半ページ上）を押下

**処理フロー**：
1. evil-scroll-down/evil-scroll-upがscroll-down/scroll-upを呼び出し
2. good-scrollのアドバイス関数がインターセプト
3. 半ページ分のスクロール量を補間アニメーションで実行
4. 目的位置に到達

## データベース更新仕様

該当なし（本機能はデータベースを使用しない）

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|----------|
| エラー | "Emacs <= 29 detected. The :ui smooth-scroll module will not function" | Emacs 29未満で使用しようとした場合（doom doctorで表示） |

## 例外処理

| 例外 | 対応 |
|------|------|
| Emacs 29未満で実行 | モジュールが機能しない。doctor.elで警告メッセージを表示 |
| ウィンドウ境界外エラー | +smooth-scroll--fix-out-of-bounds-error-a関数でエラーを回避（ledger-mode等で発生） |
| good-scroll-modeとultra-scroll-modeの競合 | +smooth-scroll-coexist-with-ultra-scroll-h関数でマウスホイール処理を分離 |

## 備考

- Emacs 29.1以降が必須要件
- ネイティブコンパイル（native-compilation）を使用すると最適なパフォーマンスを得られる
- MacOSユーザーはemacs-macフォークを使用することでさらに良い体験が得られる可能性がある
- +interpolateフラグを有効にするとアイドル時のCPU使用率が増加する場合がある

---

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

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

### 推奨読解順序

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

本モジュールは特別なデータ構造を定義していない。スクロールイベントとピクセル値を直接処理する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | packages.el | `modules/ui/smooth-scroll/packages.el` | 使用する外部パッケージ（ultra-scroll, good-scroll）の定義を確認 |

**読解のコツ**: Doom Emacsのpackages.elは依存パッケージを定義するファイル。`package!`マクロでパッケージ名、レシピ、ピンバージョンを指定している。

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

処理の起点はDoom Emacsのモジュール読み込み時に実行されるconfig.el。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.el | `modules/ui/smooth-scroll/config.el` | モジュールの設定と初期化処理を理解 |

**主要処理フロー**:
1. **3-11行目**: ultra-scrollパッケージの設定。`pixel-scroll-precision-mode`が利用可能な場合のみ有効化
2. **5-6行目**: `doom-first-input`と`doom-first-file`フックでultra-scroll-modeを起動
3. **8-11行目**: スクロール中に一時停止する機能（hl-todo-mode, diff-hl-flydiff-mode等）を登録
4. **14-58行目**: +interpolateフラグ有効時のgood-scroll設定

#### Step 3: ultra-scroll設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | config.el | `modules/ui/smooth-scroll/config.el` | ultra-scrollの設定部分（3-11行目） |

**主要処理フロー**:
- **3行目**: `use-package!`マクロでultra-scrollパッケージを設定
- **4行目**: `:when`節でEmacs 29以降のみ有効化（`pixel-scroll-precision-mode`の存在チェック）
- **5-6行目**: `:hook`でモード起動タイミングを設定
- **8-11行目**: `:config`内でスクロール中に一時停止する機能を登録

#### Step 4: good-scroll設定を理解する（+interpolate時）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | config.el | `modules/ui/smooth-scroll/config.el` | good-scrollの設定部分（14-58行目） |

**主要処理フロー**:
- **14-15行目**: `+interpolate`フラグ時のみgood-scrollを有効化
- **21-25行目**: ultra-scrollとの競合回避処理
- **34-39行目**: ウィンドウ境界外エラーの修正アドバイス
- **41-46行目**: 行数からピクセルへの変換関数
- **48-58行目**: scroll-up/scroll-downコマンドのアドバイス

#### Step 5: 診断機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | doctor.el | `modules/ui/smooth-scroll/doctor.el` | モジュール診断処理 |

**主要処理フロー**:
- **3-4行目**: Emacs 29未満の場合にエラーメッセージを表示

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

```
[Doom Emacs起動]
    |
    +-- [doom-first-input hook / doom-first-file hook]
           |
           +-- ultra-scroll-mode (有効化)
                  |
                  +-- ultra-scroll-hide-functions
                         +-- hl-todo-mode (スクロール中停止)
                         +-- diff-hl-flydiff-mode (スクロール中停止)
                         +-- jit-lock-mode (スクロール中停止)
                         +-- good-scroll-mode (スクロール中停止)

[+interpolate フラグ有効時]
    |
    +-- good-scroll-mode (有効化)
           |
           +-- scroll-up (アドバイス)
           |      +-- good-scroll--scroll-up
           |             +-- good-scroll--convert-line-to-step
           |             +-- good-scroll-move
           |
           +-- scroll-down (アドバイス)
                  +-- good-scroll--scroll-down
                         +-- good-scroll--convert-line-to-step
                         +-- good-scroll-move
```

### データフロー図

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

スクロールイベント -----> ultra-scroll-mode -----------> ピクセル単位の
(トラックパッド/               |                          バッファスクロール
 マウスホイール)               |
                              v
                    +------------------+
                    | pixel-scroll-    |
                    | precision-mode   |
                    +------------------+

scroll-up/down    -----> good-scroll アドバイス -------> 補間アニメーション
コマンド                       |                          スクロール
(PgUp/PgDown, C-d/C-u)        |
                              v
                    +------------------+
                    | good-scroll-move |
                    | (タイマー駆動)   |
                    +------------------+
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/ui/smooth-scroll/config.el` | ソース | モジュールのメイン設定ファイル。ultra-scrollとgood-scrollの設定 |
| packages.el | `modules/ui/smooth-scroll/packages.el` | 設定 | 依存パッケージ（ultra-scroll, good-scroll）の定義 |
| doctor.el | `modules/ui/smooth-scroll/doctor.el` | 診断 | モジュール診断（Emacs 29未満チェック） |
| README.org | `modules/ui/smooth-scroll/README.org` | ドキュメント | モジュールの説明、使用方法、トラブルシューティング |
