# 機能設計書 5-以降のタブを閉じる

## 概要

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

### 本機能の処理概要

**業務上の目的・背景**：タブが多数開かれている場合に、特定のタブ以降のタブを一括で閉じたい場面がある。この機能は、特定の位置を境界として不要なタブを効率的に整理し、作業の焦点を維持するために使用される。ブラウザの「以降のタブを閉じる」と同様のUXパターンを提供する。

**機能の利用シーン**：タブバーの後半に一時的に開いた不要なタブが溜まった場合や、特定のタブ以降の作業が完了した場合に使用される。タブの右クリックコンテキストメニューやコマンドパレットから実行される。

**主要な処理内容**：
1. CloseTabsAfter アクションの受信と引数（CloseTabsAfterArgs）の解析
2. 基準タブのインデックス決定（引数指定またはフォーカスタブ）
3. 基準インデックス以降のタブのスナップショット作成
4. _RemoveTabs による一括削除処理

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

**権限による制御**：特別な権限制御はない。各タブの閉じ処理で読み取り専用確認が個別に行われる。

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

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

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | - | 指定インデックスより後のすべてのタブが閉じられる |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. _HandleCloseTabsAfter がアクションイベントを受信
   └─ CloseTabsAfterArgs から Index を取得
2. インデックスの決定
   └─ Index が指定されている場合: その値を使用
   └─ Index が未指定の場合: _GetFocusedTabIndex() でフォーカスタブのインデックスを取得
   └─ どちらも取得できない場合: Handled(false) で処理を中断
3. 閉じるタブのスナップショット作成
   └─ index + 1 以降のタブを tabsToRemove に追加
4. _RemoveTabs の呼び出し
   └─ tabsToRemove 内の各タブを順次閉じる
```

### フローチャート

```mermaid
flowchart TD
    A[_HandleCloseTabsAfter 受信] --> B{Index 指定?}
    B -->|Yes| C[指定インデックスを使用]
    B -->|No| D{フォーカスタブあり?}
    D -->|Yes| E[フォーカスタブのインデックスを使用]
    D -->|No| F[Handled=false で終了]
    C --> G[index+1 以降のタブをスナップショット]
    E --> G
    G --> H[_RemoveTabs で一括削除]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | インデックス指定優先 | Index が指定されている場合、その値を基準タブのインデックスとして使用する | CloseTabsAfterArgs.Index() が有効値の場合 |
| BR-02 | フォーカスタブのフォールバック | Index が未指定の場合、現在フォーカスされたタブを基準とする | Index が null の場合 |
| BR-03 | 基準タブは保持 | 基準タブ自体は閉じず、そのタブより後ろのタブのみを閉じる | 常時 |
| BR-04 | スナップショット方式 | 非同期処理のため閉じるタブを事前にスナップショットとして作成 | 常時 |

### 計算ロジック

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

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

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

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

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

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

該当なし。

## エラー処理

### エラーケース一覧

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

### リトライ仕様

リトライは行わない。

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

一括削除はトランザクションとして管理されない。

## パフォーマンス要件

非同期コルーチンで実装されており、UIの応答性を維持しながら処理を行う。

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

特別なセキュリティ考慮事項はない。

## 備考

- TODO: GH#7182 - フォーカス中のタブが基準インデックスより前にある場合、タブの幅が全体を埋めてしまい、マウスオーバーイベントまでリサイズされない問題が報告されている
- No.4（他のタブを閉じる）と処理構造が類似しており、同じ _RemoveTabs メソッドを使用している

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: CloseTabsAfterArgs は CloseOtherTabsArgs と同じ構造だが、処理内容が異なる。Index は「これ以降を閉じる」基準点を指す。

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

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

**主要処理フロー**:
1. **808-809行目**: _HandleCloseTabsAfter の定義
2. **811行目**: CloseTabsAfterArgs へのキャスト
3. **813-827行目**: インデックスの決定（引数指定 or フォーカスタブ）
4. **830-831行目**: `begin(_tabs) + index + 1` から `end(_tabs)` までをスナップショットに収集
5. **832行目**: `_RemoveTabs(tabsToRemove)` で一括削除
6. **834-838行目**: TODO: GH#7182 のタブリサイズ問題に関するコメント

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

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

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

```
_HandleCloseTabsAfter (AppActionHandlers.cpp:808)
    |
    +-- CloseTabsAfterArgs.Index() -- インデックス取得
    |
    +-- _GetFocusedTabIndex() -- フォールバック
    |
    +-- std::copy() -- 閉じるタブのスナップショット作成（index+1以降）
    |
    +-- _RemoveTabs (TabManagement.cpp:846)
            |
            +-- [loop] _HandleCloseTabRequested -- 各タブを順次閉じる
```

### データフロー図

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

CloseTabsAfterArgs -----> _HandleCloseTabsAfter
  Index（optional）         |
                          インデックス決定
                            |
_tabs ------------------> index+1以降のスナップショット --> tabsToRemove
                            |
                          _RemoveTabs
                            |
                          [各タブ] --> _HandleCloseTabRequested --> タブ削除
```

### 関連ファイル一覧

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