# 機能設計書 29-スプリット(分割)

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおける「スプリット(分割)」機能の設計を記述する。スプリット機能は、1つのタブまたはウィンドウ内でターミナル画面を水平・垂直に分割し、複数のターミナルセッションを同時に表示する機能である。

### 本機能の処理概要

**業務上の目的・背景**：
開発作業では、コード編集、ビルド出力、ログ監視など、複数のターミナルを同時に参照する必要がある。スプリット機能により、1つの画面内で複数のターミナルペインを配置でき、視線移動を最小限に抑えながら複数のコンテキストを同時に把握できる。これにより、作業効率が大幅に向上する。

**機能の利用シーン**：
- コード編集とビルド出力の同時表示
- ログ監視とコマンド実行の並行
- 複数サーバーの並列接続
- 比較作業（diffなど）

**主要な処理内容**：
1. 新規スプリット作成（new_split）
2. スプリット間のフォーカス移動（goto_split）
3. スプリットのリサイズ（resize_split）
4. スプリットの均等化（equalize_splits）
5. スプリットの閉じる処理（close_surface）

**関連システム・外部連携**：
- SplitTree データ構造によるスプリット管理
- レンダラーとの連携（各ペインの描画）
- キーバインドシステム

**権限による制御**：
本機能に特別な権限制御はない。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | スプリットビュー | 主画面 | スプリットの作成、操作、表示 |

## 機能種別

UI管理 / レイアウト管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| direction | SplitDirection | Yes | 分割方向（right/down/left/up/auto） | enum値 |
| focus_direction | SplitFocusDirection | Yes | フォーカス移動方向 | enum値 |
| resize_direction | SplitResizeDirection | Yes | リサイズ方向 | enum値 |
| resize_amount | u16 | Yes | リサイズ量（ピクセル） | 0以上 |

### 入力データソース

- キーバインドアクション
- マウスによるスプリッター操作

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| split_tree | SplitTree | スプリットの木構造 |
| focused_handle | Node.Handle | フォーカス中のノードハンドル |

### 出力先

- レンダラー（各ペインの描画）
- UI（スプリッターの表示）

## 処理フロー

### 処理シーケンス

```
1. スプリットアクション受信
   └─ new_split/goto_split/resize_split等

2. SplitTree更新
   └─ 不変データ構造として新しいツリーを生成

3. レイアウト計算
   └─ 各ペインのサイズと位置を計算

4. UI更新
   └─ 各ペインとスプリッターの描画
```

### フローチャート

```mermaid
flowchart TD
    A[スプリットアクション] --> B{アクション種別}

    B -->|new_split| C[分割方向判定]
    B -->|goto_split| D[移動先判定]
    B -->|resize_split| E[リサイズ処理]
    B -->|equalize_splits| F[均等化処理]

    C --> G{auto?}
    G -->|Yes| H[現在のペインサイズから方向決定]
    G -->|No| I[指定方向で分割]
    H --> I

    I --> J[SplitTree.split()]
    J --> K[新規Surface作成]

    D --> L{方向}
    L -->|previous/next| M[順序ベース移動]
    L -->|spatial| N[空間ベース移動]

    M --> O[フォーカス更新]
    N --> O

    E --> P[SplitTree.resize()]
    P --> Q[比率更新]

    F --> R[全ペインの比率を1:1に]

    K --> S[レイアウト再計算]
    O --> S
    Q --> S
    R --> S

    S --> T[UI更新]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-1 | auto方向 | 現在のペインが横長なら左右、縦長なら上下に分割 | new_split:auto |
| BR-29-2 | 空間ナビゲーション | 最も近い隣接ペインに移動 | goto_split:left/right/up/down |
| BR-29-3 | 順序ナビゲーション | 作成順序でペインを移動 | goto_split:previous/next |
| BR-29-4 | リサイズ制限 | 最小サイズ以下にはリサイズ不可 | resize_split |

### 計算ロジック

**SplitTree構造**:
```
Node = Leaf(View) | Split(Layout, ratio, left, right)
Layout = horizontal | vertical
ratio = 0.0 ~ 1.0 (左/上ペインの比率)
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 移動先なし | 空間ナビゲーションで隣接ペインなし | 処理をスキップ |
| - | リサイズ不可 | 最小サイズに達している | 処理をスキップ |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- スプリット作成/移動: 即時（ミリ秒オーダー）
- リサイズ: ドラッグ中もスムーズな更新

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

- 各スプリットは独立したPTYセッションを持つ
- スプリット間でのセキュリティ分離は維持

## 備考

- SplitTreeは不変データ構造であり、undo/redo機能と連携可能
- スプリットズーム機能（No.30）との連携

---

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

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

### 推奨読解順序

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

SplitTreeのデータ構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | split_tree.zig | `src/datastruct/split_tree.zig` | SplitTree generic構造体（44行目〜） |
| 1-2 | split_tree.zig | `src/datastruct/split_tree.zig` | Node union定義（74-77行目） |
| 1-3 | split_tree.zig | `src/datastruct/split_tree.zig` | Split struct定義（101-108行目） |

**読解のコツ**: SplitTreeがジェネリック構造であること、Nodeがleaf（View）とsplit（分割ノード）のunionであることを理解する。

#### Step 2: アクション定義を理解する

スプリット関連のアクション定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Binding.zig | `src/input/Binding.zig` | new_splitアクション（594行目） |
| 2-2 | Binding.zig | `src/input/Binding.zig` | SplitDirection enum（987-994行目） |
| 2-3 | Binding.zig | `src/input/Binding.zig` | goto_splitアクション（599行目） |
| 2-4 | Binding.zig | `src/input/Binding.zig` | SplitFocusDirection enum（997-1036行目） |
| 2-5 | Binding.zig | `src/input/Binding.zig` | resize_splitアクション（624行目） |

**主要処理フロー**:
1. **594行目**: new_splitはSplitDirectionをパラメータに取る
2. **987-994行目**: SplitDirectionにauto値が存在
3. **997-1036行目**: SplitFocusDirectionにprevious/next/spatial方向が存在

#### Step 3: SplitTree操作を理解する

SplitTreeの主要操作を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | split_tree.zig | `src/datastruct/split_tree.zig` | init関数（112-126行目） |
| 3-2 | split_tree.zig | `src/datastruct/split_tree.zig` | isSplit関数（176-184行目） |
| 3-3 | split_tree.zig | `src/datastruct/split_tree.zig` | goto関数（253-271行目） |
| 3-4 | split_tree.zig | `src/datastruct/split_tree.zig` | deepest関数（276-293行目） |

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

```
キーバインド
    │
    ├─ new_split(direction)
    │      │
    │      └─ SplitTree.split()
    │             │
    │             ├─ 新規Node作成
    │             │
    │             └─ Surface.init()
    │
    ├─ goto_split(direction)
    │      │
    │      └─ SplitTree.goto()
    │             │
    │             ├─ previous/next
    │             │
    │             └─ spatial(left/right/up/down)
    │
    ├─ resize_split(direction, amount)
    │      │
    │      └─ SplitTree.resize()
    │             │
    │             └─ ratio更新
    │
    └─ equalize_splits
           │
           └─ 全Splitノードのratio=0.5
```

### データフロー図

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

new_split ────────▶ SplitTree.split() ──────▶ 新しいSplitTree
(direction)               │                        │
                          ▼                        ▼
                   Surface.init() ────────▶ 新規ペイン追加
                                                   │
                                                   ▼
                                           レイアウト再計算

goto_split ───────▶ SplitTree.goto() ──────▶ フォーカス移動
(direction)               │
                          ▼
                   previous/next/spatial判定

resize_split ─────▶ ratio更新 ─────────────▶ 新しいSplitTree
(direction, amount)                               │
                                                  ▼
                                          レイアウト再計算
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| split_tree.zig | `src/datastruct/split_tree.zig` | ソース | SplitTreeデータ構造 |
| Binding.zig | `src/input/Binding.zig` | ソース | スプリット関連アクション定義 |
| action.zig | `src/apprt/action.zig` | ソース | apprtスプリットアクション |
| split_tree.zig | `src/apprt/gtk/class/split_tree.zig` | ソース | GTKスプリットツリー実装 |
| Surface.zig | `src/Surface.zig` | ソース | Surface管理 |
