# 機能設計書 4-他のタブを閉じる

## 概要

本ドキュメントは、Windows Terminal における「他のタブを閉じる」機能の設計を記述する。指定されたタブ以外のすべてのタブを閉じる機能の詳細を定義する。

### 本機能の処理概要

**業務上の目的・背景**：多数のタブを開いて作業している場合に、1つのタブだけを残して他のすべてのタブを一括で閉じたい場面がある。この機能は、タブの整理を効率的に行い、不要なセッションを一括終了させることで、システムリソースの解放と作業画面の簡素化を実現する。

**機能の利用シーン**：多数のタブが開かれた状態で、特定のタブのみを残して作業を続けたい場合に使用される。タブの右クリックコンテキストメニューや、コマンドパレットから実行される。

**主要な処理内容**：
1. CloseOtherTabs アクションの受信と引数（CloseOtherTabsArgs）の解析
2. 残すタブのインデックス決定（引数指定またはフォーカスタブ）
3. 閉じるタブのスナップショット作成（非同期処理のため）
4. _RemoveTabs による一括削除処理

**関連システム・外部連携**：ConPTY 接続の切断、複数シェルプロセスの終了がある。

**権限による制御**：読み取り専用ペインが含まれるタブは個別に確認ダイアログが表示される可能性がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleCloseOtherTabs により指定タブ以外を閉じる |

## 機能種別

CRUD操作（タブの一括削除）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Index | IReference<UInt32> | No | 残すタブのインデックス。未指定の場合はフォーカスタブを使用 | 指定する場合は 0 以上 _tabs.Size() 未満であること |

### 入力データソース

- アクション引数: CloseOtherTabsArgs 経由の Index
- フォーカスタブ: Index 未指定時に _GetFocusedTabIndex() で取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | - | 指定タブ以外のすべてのタブが閉じられる |

### 出力先

- タブバー（TabView）からの複数タブアイテム削除
- タブ管理リスト（_tabs, _mruTabs）からの削除

## 処理フロー

### 処理シーケンス

```
1. _HandleCloseOtherTabs がアクションイベントを受信
   └─ CloseOtherTabsArgs から Index を取得
2. インデックスの決定
   └─ Index が指定されている場合: その値を使用
   └─ Index が未指定の場合: _GetFocusedTabIndex() でフォーカスタブのインデックスを取得
   └─ どちらも取得できない場合: Handled(false) で処理を中断
3. 閉じるタブのスナップショット作成
   └─ index より前のタブを tabsToRemove に追加（index > 0 の場合）
   └─ index より後のタブを tabsToRemove に追加（index + 1 < _tabs.Size() の場合）
4. _RemoveTabs の呼び出し
   └─ tabsToRemove 内の各タブを順次 _HandleCloseTabRequested で閉じる（非同期コルーチン）
```

### フローチャート

```mermaid
flowchart TD
    A[_HandleCloseOtherTabs 受信] --> B{Index 指定?}
    B -->|Yes| C[指定インデックスを使用]
    B -->|No| D{フォーカスタブあり?}
    D -->|Yes| E[フォーカスタブのインデックスを使用]
    D -->|No| F[Handled=false で終了]
    C --> G[閉じるタブのスナップショット作成]
    E --> G
    G --> H{index > 0?}
    H -->|Yes| I[前方タブを追加]
    H -->|No| J[前方タブなし]
    I --> K{index+1 < _tabs.Size?}
    J --> K
    K -->|Yes| L[後方タブを追加]
    K -->|No| M[後方タブなし]
    L --> N[_RemoveTabs で一括削除]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | インデックス指定優先 | Index が指定されている場合、その値を残すタブのインデックスとして使用する | CloseOtherTabsArgs.Index() が有効値の場合 |
| BR-02 | フォーカスタブのフォールバック | Index が未指定の場合、現在フォーカスされたタブを残す対象とする | Index が null の場合 |
| BR-03 | スナップショット方式 | _RemoveTabs は非同期処理のため、閉じるタブのリストを事前にスナップショットとして作成する | 常時 |
| BR-04 | 非同期逐次処理 | タブは _RemoveTabs のコルーチン内で1つずつ順次閉じられる | 常時 |

### 計算ロジック

閉じるタブの収集：
- 前方タブ: `std::copy(begin(_tabs), begin(_tabs) + index, std::back_inserter(tabsToRemove))`
- 後方タブ: `std::copy(begin(_tabs) + index + 1, end(_tabs), std::back_inserter(tabsToRemove))`

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

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Handled=false | インデックス未決定 | Index 未指定かつフォーカスタブなし | アクションを未処理として返却 |

### リトライ仕様

リトライは行わない。個別のタブ閉じが失敗した場合、コルーチンが中断される（co_return）。

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

一括削除はトランザクションとして管理されない。各タブは個別に閉じられるため、途中で失敗した場合は一部のタブのみが閉じられた状態になる。

## パフォーマンス要件

多数のタブを一括で閉じる場合でも、UIの応答性を維持する必要がある。非同期コルーチン（safe_void_coroutine）で実装されており、各タブの閉じ処理を逐次実行する。

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

特別なセキュリティ考慮事項はない。各タブの閉じ処理で読み取り専用確認が個別に行われる。

## 備考

- _RemoveTabs は safe_void_coroutine で実装された非同期処理であり、各タブを co_await で順次閉じる
- スナップショット方式を採用しているのは、非同期処理中に _tabs コレクションが変化する可能性があるため

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | CloseOtherTabsArgs の定義（323-327行目）。IReference<UInt32> 型の Index プロパティ |

**読解のコツ**: CloseOtherTabsArgs と CloseTabsAfterArgs（No.5）は似た構造を持つが、処理対象（残すタブの前後 vs 指定インデックス以降）が異なる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleCloseOtherTabs（769-806行目）がエントリーポイント |

**主要処理フロー**:
1. **769-770行目**: _HandleCloseOtherTabs の定義
2. **772行目**: CloseOtherTabsArgs へのキャスト
3. **774-788行目**: インデックスの決定（引数指定 or フォーカスタブ）
4. **791行目**: スナップショット用 vector の作成
5. **792-800行目**: 前方・後方のタブを std::copy でスナップショットに収集
6. **802行目**: `_RemoveTabs(tabsToRemove)` で一括削除

#### Step 3: 一括削除ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | _RemoveTabs（846-865行目） |

**主要処理フロー**:
- **846行目**: safe_void_coroutine として定義（非同期コルーチン）
- **850-863行目**: 各タブについて _HandleCloseTabRequested を呼び出し、co_await で完了を待つ
- **858-861行目**: action が null の場合（ページが破棄済みの場合）は co_return で中断

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

```
_HandleCloseOtherTabs (AppActionHandlers.cpp:769)
    |
    +-- CloseOtherTabsArgs.Index() -- インデックス取得
    |
    +-- _GetFocusedTabIndex() -- フォールバック
    |
    +-- std::copy() -- 閉じるタブのスナップショット作成
    |
    +-- _RemoveTabs (TabManagement.cpp:846)
            |
            +-- [loop] _HandleCloseTabRequested -- 各タブを順次閉じる
                    |
                    +-- co_await action -- 完了を待つ
```

### データフロー図

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

CloseOtherTabsArgs -----> _HandleCloseOtherTabs
  Index（optional）         |
                          インデックス決定
                            |
_tabs ------------------> スナップショット作成 ----> tabsToRemove
                            |
                          _RemoveTabs
                            |
                          [各タブ] --> _HandleCloseTabRequested --> タブ削除
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleCloseOtherTabs エントリーポイント |
| TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | ソース | _RemoveTabs の実装 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダー | TerminalPage クラスのメソッド宣言 |
| ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | IDL | CloseOtherTabsArgs の WinRT インターフェース定義 |
