# 機能設計書 16-閉じたタブ・ペインの復元

## 概要

本ドキュメントは、Windows Terminalにおける最後に閉じたタブまたはペインを復元する機能（RestoreLastClosed アクション）の設計を記述する。

### 本機能の処理概要

直前に閉じられたタブまたはペインを復元する機能である。閉じられたペイン/タブの構成情報（プロファイル、引数、分割状態など）がスタック構造で保存されており、RestoreLastClosedアクション実行時にスタックから最後のエントリを取り出し、保存されたアクションを順番に再実行することで復元を行う。

**業務上の目的・背景**：誤ってタブやペインを閉じてしまった場合に、ユーザーが迅速に復元できるようにする。Webブラウザの「閉じたタブを開く」機能と同様のUXを提供し、作業の中断を最小限に抑える。

**機能の利用シーン**：ユーザーが誤ってCtrl+WやCloseアクションでタブ/ペインを閉じた後、Ctrl+Shift+Tなどのキーバインドで復元する場面で使用される。複数回連続して実行することで、複数のタブ/ペインを順に復元できる。

**主要な処理内容**：
1. RestoreLastClosedアクションの受信
2. _previouslyClosedPanesAndTabs スタックから最後のエントリを取得
3. 保存されたActionAndArgsリストを順番にDoActionで再実行
4. スタックからエントリを削除（pop_back）
5. 復元されたタブ/ペインの表示

**関連システム・外部連携**：外部連携なし。内部のアクションディスパッチシステムを再利用。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleRestoreLastClosedにより直前に閉じたタブ/ペインを復元 |

## 機能種別

UI操作 / 状態復元

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | RestoreLastClosedアクションにパラメータなし | - |

### 入力データソース

キーバインドまたはコマンドパレットからのアクション実行。復元データは _previouslyClosedPanesAndTabs スタックから取得。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 復元されたタブ/ペイン | Tab/Pane | 閉じた時点の構成で復元されたタブまたはペイン |

### 出力先

TerminalPage のタブバーおよびペインレイアウト

## 処理フロー

### 処理シーケンス

```
1. _HandleRestoreLastClosed が呼び出される
2. _previouslyClosedPanesAndTabs.size() > 0 を確認
   ├─ 0の場合 → 何もしない（args.Handled は設定されない）
   └─ 1以上の場合 → 以下の処理を実行
3. スタックの末尾（back）から復元アクションリストを取得
   └─ const auto restoreActions = _previouslyClosedPanesAndTabs.back()
4. 復元アクションリストの各アクションを順番に実行
   └─ for (const auto& action : restoreActions)
       └─ _actionDispatch->DoAction(action)
5. スタックから末尾エントリを削除
   └─ _previouslyClosedPanesAndTabs.pop_back()
6. args.Handled(true) を設定
```

### フローチャート

```mermaid
flowchart TD
    A[RestoreLastClosed アクション受信] --> B{復元スタックが空?}
    B -->|Yes| C[何もしない]
    B -->|No| D[スタック末尾から復元アクション取得]
    D --> E[各アクションを順番に DoAction で実行]
    E --> F[スタックから末尾エントリ削除]
    F --> G[Handled = true]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-16-01 | スタック管理 | 閉じたペイン/タブの情報はスタック（LIFO）で管理され、最後に閉じたものが最初に復元される | 常時 |
| BR-16-02 | 空スタック時の処理 | スタックが空の場合、何も実行せず Handled も設定しない | _previouslyClosedPanesAndTabs.size() == 0 の場合 |
| BR-16-03 | バッファ容量制限 | スタックのサイズが150を超えた場合、古いエントリ50件を削除して100件に維持する | _AddPreviouslyClosedPaneOrTab 呼び出し時 |
| BR-16-04 | 復元データの構成 | 復元データはSplitPaneアクションを先頭とするActionAndArgsのリストとして保存される | _HandleClosePaneRequested 呼び出し時 |
| BR-16-05 | アクション再実行 | 復元はDoAction経由で保存されたアクションを順番に実行することで行われる | 常時 |

### 計算ロジック

バッファ容量制限: size > 150 の場合、先頭から (size - 100) 件を削除して100件に調整する。

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

データベース操作なし。復元データはメモリ上のスタック（std::vector）として保持される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | 復元スタック空 | 復元可能なタブ/ペインがない場合 | Handled を設定せず、処理をスキップ |

### リトライ仕様

リトライ不要。

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

トランザクション管理なし。復元アクションは順番に実行されるが、途中で失敗した場合のロールバック機構はない。

## パフォーマンス要件

復元処理は即座に実行されること。バッファの容量制限により、メモリ使用量は制限される。

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

特になし。

## 備考

- 復元データにはプロセスの状態（コマンド出力内容など）は含まれない。あくまでプロファイル設定と分割構成の復元である
- 閉じたタブが復元される場合、新しいシェルプロセスが起動される
- BuildStartupActions で復元アクションを構築する際、最初のペインはSplitPaneアクションとして保存される
- 復元されたペインは最後に作成されたペインがフォーカスを受ける

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | **256行目**: _previouslyClosedPanesAndTabs の型定義。std::vector<std::vector<ActionAndArgs>> 型 |

**読解のコツ**: 二重vectorで、外側のvectorがスタック（各閉じ操作ごとのエントリ）、内側のvectorが1つの復元に必要なアクションのリストを表す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | **103-117行目**: _HandleRestoreLastClosed の実装。スタックからの取得、DoAction実行、pop_back |

**主要処理フロー**:
1. **106行目**: スタックが空でないことを確認
2. **108行目**: スタック末尾から復元アクションリストを取得
3. **109-112行目**: 各アクションを _actionDispatch->DoAction で実行
4. **113行目**: pop_back でスタックからエントリを削除
5. **115行目**: args.Handled(true) を設定

#### Step 3: 復元データの保存処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | **749-770行目**: _HandleClosePaneRequested。ペイン閉じ時にBuildStartupActionsで復元アクションを構築し保存 |
| 3-2 | TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | **378-391行目**: _AddPreviouslyClosedPaneOrTab。バッファ容量制限（150件超過時に50件削除） |

**主要処理フロー**:
- **757行目**: pane->BuildStartupActions で復元用アクションを生成
- **759-764行目**: SplitPaneアクションを先頭に追加
- **766行目**: _AddPreviouslyClosedPaneOrTab で保存
- **769行目**: pane->Close() で実際にペインを閉じる

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

```
TerminalPage::_HandleRestoreLastClosed (AppActionHandlers.cpp:103)
    |
    +-- _previouslyClosedPanesAndTabs.back() で復元アクション取得
    |
    +-- _actionDispatch->DoAction(action) [各アクションをループ実行]
    |       |
    |       +-- SplitPaneAction → _HandleSplitPane → 新ペイン作成
    |       +-- (その他の復元アクション)
    |
    +-- _previouslyClosedPanesAndTabs.pop_back()

[保存側]
TerminalPage::_HandleClosePaneRequested (TabManagement.cpp:749)
    |
    +-- Pane::BuildStartupActions() で復元アクション生成
    |
    +-- _AddPreviouslyClosedPaneOrTab(args)
    |       +-- 容量制限チェック (>150 → 50件削除)
    |       +-- emplace_back で保存
    |
    +-- Pane::Close()
```

### データフロー図

```
[保存]                          [ストレージ]                    [復元]

ペイン/タブ閉じ操作     _previouslyClosedPanesAndTabs    RestoreLastClosed
        |                   (スタック: LIFO)                    |
        v                                                       v
BuildStartupActions() --> emplace_back ---- back() --> DoAction(各アクション)
        |                                                       |
  ActionAndArgs リスト                                   pop_back
  生成・保存                                             (復元後削除)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleRestoreLastClosed の実装 |
| TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | ソース | _HandleClosePaneRequested / _AddPreviouslyClosedPaneOrTab の実装 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダー | _previouslyClosedPanesAndTabs の宣言 |
| Pane.h | `src/cascadia/TerminalApp/Pane.h` | ヘッダー | BuildStartupActions の宣言 |
| Pane.cpp | `src/cascadia/TerminalApp/Pane.cpp` | ソース | BuildStartupActions の実装 |
