# 機能設計書 62-プロンプトジャンプ

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおけるシェルプロンプト間のジャンプ機能の設計を記述する。

### 本機能の処理概要

プロンプトジャンプ機能は、端末のスクロールバック履歴内でシェルプロンプト（コマンド入力行）間を前方・後方にジャンプする機能である。シェル統合機能が提供するセマンティックプロンプトマーキング情報を利用して、ユーザーが過去のコマンド実行位置に素早く移動できるようにする。

**業務上の目的・背景**：長時間稼働するターミナルセッションでは、大量のコマンド出力が蓄積され、過去のコマンドや結果を確認するために多くのスクロール操作が必要となる。プロンプトジャンプ機能により、ユーザーはコマンド出力を読み飛ばして直接プロンプト位置に移動でき、作業効率が大幅に向上する。これは特にログ確認やデバッグ作業において有用である。

**機能の利用シーン**：
- 過去に実行したコマンドの出力を確認するためにスクロールバック履歴を遡る場合
- 長い出力を持つコマンドの前後のプロンプトに素早く移動したい場合
- コマンド履歴を効率的にナビゲートしたい場合

**主要な処理内容**：
1. キーバインドアクション`jump_to_prompt`の受信
2. デルタ値（正：前進、負：後退）に基づく方向決定
3. 現在のビューポート位置からのプロンプト検索
4. セマンティックプロンプトマーカーを持つ行の特定
5. ビューポートの目的位置へのスクロール
6. レンダラーへの再描画通知

**関連システム・外部連携**：
- シェル統合: プロンプトのセマンティックマーキングを提供（OSC 133シーケンス）
- Bash/Zsh/Fish/Elvish/Nushell: 各シェルがプロンプト位置をマークする

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインターミナルウィンドウ | 主機能 | プロンプトジャンプ操作の実行 |

## 機能種別

ナビゲーション処理 / スクロール制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| delta | i16 | Yes | ジャンプするプロンプト数（正：前進、負：後退） | -32768から32767 |

### 入力データソース

- キーバインドアクション: `jump_to_prompt`
- デフォルトキーバインド:
  - macOS: `Cmd+Shift+Up` (前のプロンプト)、`Cmd+Shift+Down` (次のプロンプト)
  - Linux: `Ctrl+Shift+PageUp` (前のプロンプト)、`Ctrl+Shift+PageDown` (次のプロンプト)

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| viewport | Viewport | 更新されたビューポート位置（pin、active、topのいずれか） |

### 出力先

- ターミナルビューポート状態の更新
- レンダラーへの再描画リクエスト

## 処理フロー

### 処理シーケンス

```
1. キーバインドアクション受信
   └─ Surface.performBindingAction(.jump_to_prompt)

2. IOスレッドへのメッセージ送信
   └─ termio.message.jump_to_prompt = delta

3. Termio.jumpToPrompt(delta)実行
   └─ レンダラー状態のロック取得
   └─ terminal.screens.active.scroll(.{ .delta_prompt = delta })
   └─ ロック解放

4. PageList.scroll(.delta_prompt)
   └─ scrollPrompt(delta)呼び出し

5. scrollPrompt内部処理
   └─ ビューポート起点の決定
   └─ プロンプト行の検索（前方または後方）
   └─ ビューポート更新（pin、active、または変更なし）

6. レンダラー通知
   └─ renderer_wakeup.notify()
```

### フローチャート

```mermaid
flowchart TD
    A[jump_to_promptアクション] --> B{delta値確認}
    B -->|delta > 0| C[前方検索]
    B -->|delta < 0| D[後方検索]
    B -->|delta = 0| E[何もしない]

    C --> F[現在のビューポート+1行から開始]
    D --> G[現在のビューポート-1行から開始]

    F --> H[ページを順方向に走査]
    G --> I[ページを逆方向に走査]

    H --> J{セマンティックプロンプト発見?}
    I --> J

    J -->|Yes| K[残りデルタを減算]
    J -->|No| L{次のページあり?}

    K --> M{デルタ=0?}
    M -->|Yes| N[ビューポートをその位置に設定]
    M -->|No| H

    L -->|Yes| H
    L -->|No| O[最も近いプロンプトで停止]

    N --> P[レンダラー通知]
    O --> P
    E --> Q[終了]
    P --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-62-01 | 前進ジャンプ | 正のdelta値は新しいプロンプト（時系列的に後）へジャンプ | delta > 0 |
| BR-62-02 | 後退ジャンプ | 負のdelta値は古いプロンプト（時系列的に前）へジャンプ | delta < 0 |
| BR-62-03 | ゼロデルタ | delta=0の場合は何もしない | delta = 0 |
| BR-62-04 | 端点クランプ | 要求されたプロンプト数を超える場合、最も端のプロンプトで停止 | プロンプト数がdeltaより少ない |
| BR-62-05 | シェル統合依存 | セマンティックプロンプトマーキングはシェル統合が必要 | シェル統合が有効 |

### 計算ロジック

プロンプトの検出は、各行の`semantic_prompt`フィールドが`.prompt`であるかを確認することで行われる。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | プロンプト未発見 | シェル統合が無効またはプロンプトがマークされていない | 何もしない（ビューポート位置維持） |

### リトライ仕様

該当なし

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

- レンダラー状態のミューテックスロックを取得してビューポートを更新
- ロックは最小限の期間保持される

## パフォーマンス要件

- プロンプト検索は即座に完了すること（スクロールバックサイズに関わらず）
- ページリストの走査はO(n)だが、通常のユースケースでは数ページ程度で完了

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

該当なし

## 備考

- セマンティックプロンプトマーキングはOSC 133エスケープシーケンスで実現される
- 各シェルの統合スクリプトがプロンプト表示時にこのシーケンスを出力する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PageList.zig | `src/terminal/PageList.zig` | Scroll unionのdelta_prompt定義（2445行目） |
| 1-2 | Screen.zig | `src/terminal/Screen.zig` | Screen.Scroll enumのdelta_prompt定義（1257行目） |
| 1-3 | message.zig | `src/termio/message.zig` | jump_to_promptメッセージ定義（63行目） |

**読解のコツ**: Zigのunion型は、複数の型を一つの変数で扱える。`Scroll`は様々なスクロール方法を表現し、`delta_prompt`はプロンプトジャンプ専用のバリアントである。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Binding.zig | `src/input/Binding.zig` | jump_to_promptアクション定義（490行目） |
| 2-2 | Surface.zig | `src/Surface.zig` | performBindingActionでのjump_to_prompt処理（5555-5558行目） |

**主要処理フロー**:
1. **490行目**: `jump_to_prompt: i16`アクション定義
2. **5555行目**: アクションのマッチングとIOスレッドへのメッセージ送信
3. **5557行目**: `queueIo(.{ .jump_to_prompt = @intCast(delta) })`

#### Step 3: IOスレッド処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Thread.zig | `src/termio/Thread.zig` | メッセージハンドリング（332行目） |
| 3-2 | Termio.zig | `src/termio/Termio.zig` | jumpToPrompt実装（649-657行目） |

**主要処理フロー**:
- **332行目**: `.jump_to_prompt => |v| try io.jumpToPrompt(v)`
- **649-654行目**: ミューテックスロック取得とスクロール実行
- **656行目**: レンダラーへの通知

#### Step 4: スクロール実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | PageList.zig | `src/terminal/PageList.zig` | scroll関数（2567行目）とscrollPrompt関数（2666行目） |

**主要処理フロー**:
- **2567行目**: `.delta_prompt => |n| self.scrollPrompt(n)`
- **2666-2668行目**: delta=0チェック
- **2669-2676行目**: 開始位置の決定とdeltaの絶対値計算
- **後続行**: ページ走査とプロンプト検索ロジック

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

```
キーバインドトリガー (例: Cmd+Shift+Up)
    │
    └─ Surface.performBindingAction
           │
           └─ .jump_to_prompt => queueIo
                  │
                  └─ termio.Thread メッセージ処理
                         │
                         └─ Termio.jumpToPrompt(delta)
                                │
                                ├─ renderer_state.mutex.lock()
                                │
                                └─ terminal.screens.active.scroll
                                       │
                                       └─ PageList.scroll(.delta_prompt)
                                              │
                                              └─ PageList.scrollPrompt
                                                     │
                                                     ├─ ページ走査
                                                     │
                                                     └─ semantic_prompt == .prompt チェック
```

### データフロー図

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

キーイベント ───────────▶ Binding.Parser ───▶ Action判定
                                │
                                ▼
delta値 (i16) ─────────▶ Surface.performBindingAction
                                │
                                ▼
                        termio.message.jump_to_prompt
                                │
                                ▼
                        Termio.jumpToPrompt
                                │
                                ▼
                        Screen.scroll(.delta_prompt)
                                │
                                ▼
                        PageList.scrollPrompt ───▶ ビューポート更新
                                                       │
                                                       ▼
                        renderer_wakeup.notify() ───▶ 画面再描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Binding.zig | `src/input/Binding.zig` | ソース | jump_to_promptアクション定義 |
| Surface.zig | `src/Surface.zig` | ソース | バインディングアクション実行 |
| Thread.zig | `src/termio/Thread.zig` | ソース | IOスレッドメッセージ処理 |
| message.zig | `src/termio/message.zig` | ソース | IOスレッドメッセージ定義 |
| Termio.zig | `src/termio/Termio.zig` | ソース | jumpToPrompt実装 |
| Screen.zig | `src/terminal/Screen.zig` | ソース | スクロール処理ラッパー |
| PageList.zig | `src/terminal/PageList.zig` | ソース | scrollPrompt実装 |
| Config.zig | `src/config/Config.zig` | ソース | デフォルトキーバインド設定 |
