# 機能設計書 100-画面書き出し

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおける「画面書き出し」機能の設計を記述する。本機能により、現在表示されている画面（ビューポート）の内容を一時ファイルに保存し、その後の処理（コピー、ペースト、開く）を実行できる。

### 本機能の処理概要

画面書き出し機能は、現在のターミナルビューポート（表示されている画面）の内容を一時ファイルに書き出す。スクロールバック書き出しとは異なり、現在表示されている範囲のみを対象とする。書き出し形式はプレーンテキスト、ANSI/VTシーケンス、HTMLから選択可能。

**業務上の目的・背景**：現在の画面表示をそのまま保存したい場合がある。例えば、コマンド実行結果のスクリーンショット的な保存や、現在の作業状態の記録。スクロールバック全体ではなく、見えている部分だけを効率的に取得できる。

**機能の利用シーン**：
- 現在のコマンド実行結果を保存する場合
- 画面の状態をドキュメントに添付する場合
- 現在表示されている内容を他のツールで確認する場合

**主要な処理内容**：
1. ユーザーがwrite_screen_fileアクションをパラメータ付きで実行
2. 一時ディレクトリを作成
3. 現在の画面内容を指定形式でファイルに書き出し
4. アクションに応じて後処理を実行（copy/paste/open）
5. 一時ファイルとディレクトリは自動的にクリーンアップされる

**関連システム・外部連携**：
- システムの一時ディレクトリ
- クリップボード（copyアクション）
- OS標準のファイルオープン機能（openアクション）

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

## 関連画面

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

## 機能種別

ファイル出力 / データエクスポート

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| action | WriteScreen.Action | Yes | 後処理アクション（copy/paste/open） | enum値 |
| emit | WriteScreen.Format | No | 出力形式（plain/vt/html）、デフォルトplain | enum値 |

### 入力データソース

- キーバインド設定（例: `keybind = cmd+shift+e=write_screen_file:copy`）
- コマンドパレットからの選択

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ファイル | File | 一時ファイル（.txt または .html） |
| パス | string | 一時ファイルの絶対パス |

### 出力先

- システム一時ディレクトリ内のファイル
- クリップボード（copyアクションの場合）
- ターミナル入力（pasteアクションの場合）

## 処理フロー

### 処理シーケンス

```
1. ユーザーがwrite_screen_file:action[,format]を実行
   └─ 例: write_screen_file:copy または write_screen_file:open,html
2. Surface.writeScreenFile(.screen, params)を呼び出し
3. 一時ディレクトリを作成
   └─ TempDir.init()
4. ファイル名を決定
   └─ "screen.txt" または "screen.html"
5. ファイルを作成し、画面内容を書き出し
   └─ dumpString()で現在のビューポート内容を取得
6. アクションに応じた後処理を実行
   └─ copy: ファイルパスをクリップボードにコピー
   └─ paste: ファイルパスをターミナルにペースト
   └─ open: OSのデフォルトアプリでファイルを開く
```

### フローチャート

```mermaid
flowchart TD
    A[write_screen_file実行] --> B[一時ディレクトリ作成]
    B --> C[ファイル作成]
    C --> D{出力形式}
    D -->|plain| E[プレーンテキストで書き出し]
    D -->|vt| F[ANSIシーケンス付きで書き出し]
    D -->|html| G[HTML形式で書き出し]
    E --> H{アクション}
    F --> H
    G --> H
    H -->|copy| I[ファイルパスをクリップボードにコピー]
    H -->|paste| J[ファイルパスをターミナルにペースト]
    H -->|open| K[OSでファイルを開く]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-100-1 | 対象範囲 | 現在のビューポート（表示画面）のみを対象 | 常時 |
| BR-100-2 | 形式デフォルト | formatを省略した場合はplain形式 | 常時 |
| BR-100-3 | ファイル拡張子 | plain/vtは.txt、htmlは.html | 常時 |
| BR-100-4 | 一時ファイル | システムの一時ディレクトリに作成 | 常時 |
| BR-100-5 | 代替スクリーン対応 | 代替スクリーン（vim等）でも動作 | 常時 |

### 計算ロジック

```
ファイル名 = "screen" + (format == .html ? ".html" : ".txt")
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル作成エラー | 一時ディレクトリの権限不足 | エラーログ出力 |

### リトライ仕様

リトライ不要

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

トランザクション不要

## パフォーマンス要件

画面サイズに応じて処理時間は変動（通常の画面サイズなら100ms以内）

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

- 一時ファイルの権限は0600（所有者のみ読み書き可能）
- 機密情報が画面に表示されている場合は注意が必要

## 備考

- `write_scrollback_file`はスクロールバック履歴全体を、`write_selection_file`は選択範囲を保存
- Ghostty 1.3以前はformat指定なしのみサポート

---

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

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

### 推奨読解順序

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

アクションとWriteScreen構造体を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Binding.zig | `src/input/Binding.zig` | write_screen_file定義（518行目） |
| 1-2 | Binding.zig | `src/input/Binding.zig` | WriteScreen構造体（1068-1126行目） |

**読解のコツ**: WriteScreenはaction（copy/paste/open）とemit（plain/vt/html）の2つのフィールドを持つ構造体。write_scrollback_fileと共有。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Surface.zig | `src/Surface.zig` | write_screen_file処理（5561-5564行目） |

**主要処理フロー**:
1. **5561行目**: write_screen_fileアクションのマッチング
2. **5562-5563行目**: writeScreenFile(.screen, v)を呼び出し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Surface.zig | `src/Surface.zig` | writeScreenFile関数（5962-6030行目付近） |

**主要処理フロー**:
- **5968行目**: TempDir.init()で一時ディレクトリ作成
- **5972-5982行目**: ファイル名決定（screen.txt/html）
- **5985-5992行目**: ファイル作成（権限0600）
- **6000-6030行目**: 画面内容を書き出し（.screenの場合はビューポートを対象）
- 後処理（copy/paste/open）の実行

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

```
Surface.performBindingAction
    │
    └─ write_screen_fileアクションを検出
           │
           └─ writeScreenFile(.screen, params)
                  │
                  ├─ TempDir.init()
                  │
                  ├─ ファイル作成（screen.txt/html）
                  │
                  ├─ dumpString()で画面内容取得
                  │
                  └─ 後処理（copy/paste/open）
                         │
                         ├─ copy: クリップボードにパスをコピー
                         ├─ paste: ターミナルにパスをペースト
                         └─ open: OSでファイルを開く
```

### データフロー図

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

キーバインド ───▶ Surface.performBindingAction ───▶ 一時ファイル
                        │
                        ▼
               writeScreenFile(.screen)
                        │
                        ├─ 一時ディレクトリ作成
                        ├─ ファイル作成
                        ├─ 画面内容書き出し
                        └─ 後処理 ───▶ クリップボード/ターミナル/OS
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Binding.zig | `src/input/Binding.zig` | ソース | write_screen_file定義、WriteScreen構造体 |
| command.zig | `src/input/command.zig` | ソース | コマンドパレット用コマンド（274-340行目付近） |
| Surface.zig | `src/Surface.zig` | ソース | アクション処理、writeScreenFile関数 |
| Screen.zig | `src/terminal/Screen.zig` | ソース | dumpString関数（画面内容取得） |
| TempDir.zig | `src/os/TempDir.zig` | ソース | 一時ディレクトリ管理 |
