# 機能設計書 43-次/前の一致を検索

## 概要

本ドキュメントは、Windows Terminal における「次/前の一致を検索（FindMatch）」機能の設計を記述する。検索結果の次または前の一致箇所にナビゲーションする機能である。

### 本機能の処理概要

検索ボックスで入力されたテキストに基づき、ターミナルバッファ内の一致箇所を前後に移動する機能である。検索ボックスが未表示の場合は自動的に検索ボックスを開く。

**業務上の目的・背景**：テキスト検索を実行した後、複数の一致箇所が存在する場合、ユーザーは目的の箇所を素早く見つけるために一致箇所間を移動する必要がある。本機能により、キーバインド（通常はF3/Shift+F3やCtrl+Shift+N/P）を使って検索結果間を効率的に移動でき、目的のテキスト箇所へ素早く到達できる。

**機能の利用シーン**：
- 検索結果の次の一致箇所に移動したい場合
- 検索結果の前の一致箇所に戻りたい場合
- 検索ボックスを表示していない状態からキーバインドで直接検索ナビゲーションを開始したい場合

**主要な処理内容**：
1. FindMatchアクションを受け付け、方向（Next/Previous）を取得する
2. 検索ボックスが未オープンの場合はCreateSearchBoxControlで開く
3. 検索ボックスが既に開いている場合は、現在の検索テキストとオプションで次/前の一致を検索する
4. 検索結果が見つかった場合、該当箇所にスクロールしてハイライト表示する

**関連システム・外部連携**：なし。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleFindMatchによりアクションを処理 |
| 7 | SearchBoxControl（検索ボックス） | 主画面 | 検索結果の次/前の一致箇所への移動ボタン |
| 6 | TermControl（ターミナル表示） | 主画面 | SearchMatch関数による検索実行 |

## 機能種別

テキスト検索ナビゲーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Direction | FindMatchDirection | Yes | 検索方向（Next/Previous） | 列挙値のみ（None=0, Next=1, Previous=2） |

### 入力データソース

- キーバインド設定からのFindMatchアクション（FindMatchArgs）
- 検索ボックスの「次」「前」ボタンクリック
- 現在の検索テキスト・オプション（検索ボックスのText/CaseSensitive/RegularExpression）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 検索結果表示 | SearchResults | 総一致件数と現在のインデックスを含む検索結果情報 |

### 出力先

ターミナル画面上の検索ハイライトおよびスクロール位置の更新。検索ボックスのステータス表示（一致件数/現在位置）。

## 処理フロー

### 処理シーケンス

```
1. ユーザーがFindMatchアクションを実行（キーバインドまたは検索ボックスボタン）
   └─ _HandleFindMatch (AppActionHandlers.cpp) が呼ばれる
2. FindMatchArgsからDirectionを取得
   └─ Direction == Next → goForward = true
3. アクティブなTermControlを取得
   └─ _GetActiveControl()
4. TermControl::SearchMatch(goForward)を呼び出す
   └─ TermControl.cppのSearchMatch関数へ
5. 検索ボックスの状態を確認
   └─ 検索ボックスが未オープン → CreateSearchBoxControlで開く
   └─ 検索ボックスが開いている → 次のステップへ
6. ControlCore::Searchを実行
   └─ SearchRequestを構築（Text, GoForward, CaseSensitive, RegularExpression, ExecuteSearch=true, ScrollIntoView=true）
7. 検索エンジンが一致を検索
   └─ _searcher.FindNext(!request.GoForward) で次/前の一致を特定
8. 結果をハイライト表示し、該当箇所にスクロール
   └─ _terminal->ScrollToSearchHighlight()
```

### フローチャート

```mermaid
flowchart TD
    A[FindMatchアクション発火] --> B[Direction取得]
    B --> C[アクティブTermControl取得]
    C --> D{検索ボックスIsOpen?}
    D -->|No| E[CreateSearchBoxControl]
    D -->|Yes| F[SearchRequest構築]
    E --> G[終了]
    F --> H[ControlCore::Search実行]
    H --> I[_searcher.FindNext]
    I --> J[検索ハイライト更新]
    J --> K[該当箇所にスクロール]
    K --> L[検索結果ステータス更新]
    L --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-43-01 | 検索ボックス未表示時の動作 | 検索ボックスが未表示の場合、まず検索ボックスを開く（検索実行はしない） | 検索ボックス未オープン時 |
| BR-43-02 | ラップアラウンド | 検索は末尾から先頭（または先頭から末尾）にラップアラウンドする | 最後/最初の一致を超えた場合 |
| BR-43-03 | 大文字小文字区別 | 検索ボックスのCaseSensitiveオプションに従う | 検索実行時 |
| BR-43-04 | 正規表現対応 | 検索ボックスのRegularExpressionオプションに従う | 検索実行時 |
| BR-43-05 | ステータス表示上限 | 総一致件数が999を超える場合は「999+」と表示 | 検索結果ステータス表示時 |

### 計算ロジック

SearchRequestの構築:
- `Text`: 検索ボックスの現在のテキスト
- `GoForward`: Direction == Next
- `CaseSensitive`: 検索ボックスのオプション
- `RegularExpression`: 検索ボックスのオプション
- `ExecuteSearch`: true（検索を実行する）
- `ScrollIntoView`: true（一致箇所にスクロールする）
- `ScrollOffset`: _searchScrollOffset（検索ボックスのスクロールオフセット）

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

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

本機能ではデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無操作 | アクティブなTermControlが存在しない | 何も起こらずに終了 |
| - | 無操作 | 検索テキストが空 | 何も起こらずに終了 |
| - | 無操作 | TermControlがクロージング中 | 何も起こらずに終了（_IsClosingチェック） |

### リトライ仕様

リトライは不要。

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

ControlCore::Search内でターミナルの書き込みロック（LockForWriting）を取得して検索を実行する。

## パフォーマンス要件

検索はバッファ全体を対象とするため、バッファサイズに比例した時間がかかる可能性があるが、通常のバッファサイズでは即時応答。

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

特になし。

## 備考

- SearchBoxControlのMaximumTotalResultsToShowInStatusは999に設定されている。
- 検索が「stale」（テキストやフラグが変更された）場合は検索インデックスを再構築する。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | FindMatchDirection列挙型（None=0, Next=1, Previous=2）とFindMatchArgsの定義 |
| 1-2 | SearchBoxControl.h | `src/cascadia/TerminalControl/SearchBoxControl.h` | SearchBoxControlの構造。MaximumTotalResultsToShowInStatus=999 |

**読解のコツ**: FindMatchDirectionはFindアクションではなくFindMatchアクション専用の列挙型であり、検索ボックスのボタンクリックとキーバインドの両方で使用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleFindMatch関数（430-440行目）- FindMatchArgsからDirectionを取得しSearchMatchを呼ぶ |

**主要処理フロー**:
1. **430-433行目**: FindMatchArgsにキャストしDirectionを取得
2. **435-437行目**: アクティブなTermControlを取得
3. **437行目**: control.SearchMatch(Direction == Next)を呼び出し

#### Step 3: TermControl層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | SearchMatch関数（705-727行目）- 検索ボックス未オープンならCreateSearchBoxControl、オープンならCore::Searchを実行 |

**主要処理フロー**:
- **705-710行目**: クロージング中チェック
- **711-713行目**: 検索ボックス未オープンならCreateSearchBoxControlで開く
- **717-726行目**: SearchRequestを構築してControlCore::Searchを呼び出す

#### Step 4: ControlCore層（検索エンジン）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | Search関数（1739-1779行目）- 検索フラグ設定、検索インデックス構築、FindNext実行、ハイライト更新 |

**主要処理フロー**:
- **1741行目**: 書き込みロック取得
- **1743-1745行目**: 検索フラグ設定（CaseInsensitive、RegularExpression）
- **1746行目**: 検索が「stale」かチェック
- **1752-1756行目**: staleなら検索インデックスを再構築
- **1759-1762行目**: ExecuteSearchならFindNextで次/前の一致を検索
- **1764-1765行目**: ハイライトフォーカス更新とレンダー通知
- **1768-1771行目**: ScrollIntoViewなら該当箇所にスクロール

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

```
TerminalPage::_HandleFindMatch (AppActionHandlers.cpp:430)
    ├─ FindMatchArgs::Direction() → goForward判定
    └─ TermControl::SearchMatch (TermControl.cpp:705)
           ├─ [検索ボックス未オープン] CreateSearchBoxControl()
           └─ [検索ボックスオープン]
                  └─ ControlCore::Search (ControlCore.cpp:1739)
                         ├─ _searcher.IsStale() → 検索インデックスチェック
                         ├─ _searcher.Reset() → インデックス再構築
                         ├─ _searcher.FindNext() → 次/前の一致
                         ├─ _terminal->SetSearchHighlightFocused()
                         ├─ _renderer->TriggerSearchHighlight()
                         └─ _terminal->ScrollToSearchHighlight()
```

### データフロー図

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

FindMatchArgs         →  _HandleFindMatch             →  検索一致箇所の
  (Direction)              └─ SearchMatch                   ハイライト表示
                                ├─ SearchRequest構築
検索ボックスの状態     →        │   (Text, Options)      →  検索ステータス
  (Text, CaseSensitive,       └─ ControlCore::Search        (N/M件目)
   RegularExpression)               ├─ _searcher.FindNext
                                    └─ ScrollToSearchHighlight → ビューポート
                                                                  スクロール
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleFindMatchアクションハンドラー |
| TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ソース | SearchMatch関数の実装 |
| TermControl.h | `src/cascadia/TerminalControl/TermControl.h` | ヘッダー | SearchMatch関数の宣言 |
| ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ソース | Search関数のコアロジック |
| ControlCore.h | `src/cascadia/TerminalControl/ControlCore.h` | ヘッダー | Search関数の宣言 |
| SearchBoxControl.h | `src/cascadia/TerminalControl/SearchBoxControl.h` | ヘッダー | SearchBoxControlクラス定義 |
| SearchBoxControl.cpp | `src/cascadia/TerminalControl/SearchBoxControl.cpp` | ソース | SearchBoxControlの実装 |
| ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | IDL | FindMatchArgs/FindMatchDirectionの定義 |
| AllShortcutActions.h | `src/cascadia/TerminalSettingsModel/AllShortcutActions.h` | ヘッダー | FindMatchアクションの登録 |
