# 機能設計書 93-ページスクロール

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおける「ページスクロール」機能の設計を記述する。本機能により、ユーザーはターミナル画面を1ページ（表示行数）単位で上下にスクロールできる。

### 本機能の処理概要

ページスクロール機能は、ターミナルのビューポートを1画面分（表示可能な行数）ずつ上下に移動させる機能である。スクロールバック履歴を持つターミナルにおいて、過去の出力を効率的に閲覧できる。

**業務上の目的・背景**：ターミナルでの作業では、長い出力ログやビルドログなどを確認する必要がある。1行ずつスクロールするのは非効率であるため、ページ単位のスクロールにより大量の出力を素早く確認できる。伝統的なターミナル操作であるPage Up/Page Downキーの動作を提供する。

**機能の利用シーン**：
- コンパイルエラーやログを遡って確認する場合
- 長いファイル内容（cat/less出力）を閲覧する場合
- コマンド履歴を確認する場合

**主要な処理内容**：
1. ユーザーがscroll_page_upまたはscroll_page_downアクションを実行
2. 現在の表示行数を取得
3. ビューポートを表示行数分だけ上下に移動
4. 画面が再描画される

**関連システム・外部連携**：特になし

**権限による制御**：特になし。全ユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインターミナルウィンドウ | 主画面 | スクロール操作が行われる画面 |

## 機能種別

UI制御 / ビューポート操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | scroll_page_up/scroll_page_downはパラメータなし | - |

### 入力データソース

- キーバインド設定（`keybind = scroll_page_up` / `keybind = scroll_page_down`）
- コマンドパレットからの選択

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ビューポート位置 | isize | 新しいスクロール位置（行数） |

### 出力先

- 画面表示（ビューポートの移動）

## 処理フロー

### 処理シーケンス

```
1. ユーザーがscroll_page_up/scroll_page_downを実行
   └─ キーバインド経由（通常Page Up/Page Downキー）
2. Surface.performBindingActionでアクションを処理
   └─ 現在のグリッドサイズから行数を取得
3. queueIoでscroll_viewportメッセージを送信
   └─ delta値を正（下）または負（上）で指定
4. termioがビューポートを移動
   └─ スクロールバック履歴内で位置を更新
5. 画面が再描画される
```

### フローチャート

```mermaid
flowchart TD
    A[scroll_page_up/down実行] --> B[表示行数を取得]
    B --> C{スクロール方向}
    C -->|up| D[delta = -rows]
    C -->|down| E[delta = +rows]
    D --> F[scroll_viewportメッセージ送信]
    E --> F
    F --> G[ビューポート位置更新]
    G --> H[画面再描画]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-93-1 | スクロール単位 | 1ページ = 現在の表示行数 | 常時 |
| BR-93-2 | 上限制限 | スクロールバックの先頭で停止 | scroll_page_up時 |
| BR-93-3 | 下限制限 | 最新出力位置で停止 | scroll_page_down時 |

### 計算ロジック

```
scroll_page_up:  delta = -1 * rows（負の値で上方向）
scroll_page_down: delta = +rows（正の値で下方向）

rows = self.size.grid().rows（現在の表示行数）
```

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

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | なし | スクロール範囲外へのスクロール要求 | 自動的に範囲内に制限される |

### リトライ仕様

リトライ不要

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

トランザクション不要（メモリ上の状態更新のみ）

## パフォーマンス要件

スクロール操作は即座に反映されること（16ms以内、60fps相当）

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

特になし

## 備考

- `scroll_page_fractional`で小数ページ単位のスクロールも可能
- `scroll_page_lines`で行単位のスクロールが可能

---

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

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

### 推奨読解順序

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

スクロール関連のアクション定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Binding.zig | `src/input/Binding.zig` | scroll_page_up/scroll_page_down定義（430-433行目） |

**読解のコツ**: scroll_page_upとscroll_page_downはパラメータなしのアクション。内部でグリッドサイズを使って移動量を計算する。

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

Surfaceでのアクション処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Surface.zig | `src/Surface.zig` | scroll_page_up処理（5527-5532行目） |
| 2-2 | Surface.zig | `src/Surface.zig` | scroll_page_down処理（5534-5539行目） |

**主要処理フロー**:
1. **5527行目**: scroll_page_upアクションのマッチング
2. **5528行目**: `self.size.grid().rows`で表示行数を取得
3. **5529-5531行目**: scroll_viewportメッセージをdelta = -rowsで送信
4. **5534行目**: scroll_page_downアクションのマッチング
5. **5535行目**: 同様に表示行数を取得
6. **5536-5538行目**: scroll_viewportメッセージをdelta = +rowsで送信

#### Step 3: termioの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Termio.zig | `src/termio/Termio.zig` | scroll_viewportメッセージの処理 |

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

```
Surface.performBindingAction
    │
    ├─ scroll_page_upアクションを検出
    │      │
    │      ├─ rows = self.size.grid().rows
    │      │
    │      └─ queueIo(.scroll_viewport = .{ .delta = -rows })
    │
    └─ scroll_page_downアクションを検出
           │
           ├─ rows = self.size.grid().rows
           │
           └─ queueIo(.scroll_viewport = .{ .delta = +rows })
                  │
                  └─ termio.scrollViewport(delta)
                         │
                         └─ Screen.scroll(.delta)
```

### データフロー図

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

キーバインド ───▶ Surface.performBindingAction ───▶ IOメッセージキュー
(Page Up/Down)           │
                         ▼
               グリッド行数取得
                         │
                         ▼
               scroll_viewportメッセージ ───▶ ビューポート移動
                                                    │
                                                    ▼
                                              画面再描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Binding.zig | `src/input/Binding.zig` | ソース | scroll_page_up/down定義 |
| command.zig | `src/input/command.zig` | ソース | コマンドパレット用コマンド（262-272行目） |
| Surface.zig | `src/Surface.zig` | ソース | アクション処理のエントリーポイント |
| Termio.zig | `src/termio/Termio.zig` | ソース | IOスレッドでのスクロール処理 |
| Screen.zig | `src/terminal/Screen.zig` | ソース | スクリーンのスクロール状態管理 |
