# 機能設計書 39-選択テキストの色付け

## 概要

本ドキュメントは、Windows Terminal における「選択テキストの色付け」機能（ColorSelection アクション）の設計を記述する。選択されたテキストの前景色と背景色を設定する機能であり、選択範囲のみまたはバッファ全体で一致するテキストすべてに色を適用できる。

### 本機能の処理概要

**業務上の目的・背景**：ターミナル上のテキストに視覚的なハイライトを施す機能を提供する。ログ分析やデバッグ時に、特定のテキストパターンを色付けして視認性を向上させる用途に使用される。選択範囲だけでなく、マッチモードを使用して同じテキストのすべての出現箇所を一括で色付けすることも可能である。

**機能の利用シーン**：ターミナル上でテキストを選択した状態でキーバインドを実行し、前景色や背景色を設定する。例えば、エラーメッセージを赤色でハイライトしたり、特定のキーワードを緑色で目立たせたりする場合に利用される。

**主要な処理内容**：
1. _HandleColorSelection で ActionEventArgs を受信し、ColorSelectionArgs から色情報とマッチモードを取得
2. _ApplyToActiveControls で全アクティブコントロールに適用
3. TermControl.ColorSelection → ControlCore.ColorSelection を呼び出し
4. TextAttribute を作成して前景色と背景色を設定
5. マッチモードに応じた色適用（None: 選択範囲のみ、All: バッファ全体の一致テキスト）
6. 選択をクリアし、マッチモードが All の場合は全画面を再描画

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | TermControl（ターミナル表示） | 主画面 | ColorSelection により選択テキストの色を設定 |
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleColorSelection でアクションを処理 |

## 機能種別

テキスト操作 / 外観制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Foreground | SelectionColor | No | 前景色の設定。null の場合はデフォルト色 | SelectionColor 型 |
| Background | SelectionColor | No | 背景色の設定。null の場合はデフォルト色 | SelectionColor 型 |
| MatchMode | MatchMode | No | マッチモード（None: 選択のみ / All: 全一致テキスト） | MatchMode 列挙値 |

### 入力データソース

- ColorSelectionArgs のアクション引数
- 現在の選択範囲
- テキストバッファの内容（MatchMode.All の場合）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | - | テキストバッファの該当範囲の前景色・背景色属性が更新される |

### 出力先

- テキストバッファのテキスト属性（TextAttribute）

## 処理フロー

### 処理シーケンス

```
1. _HandleColorSelection が ActionEventArgs を受信
   └─ ColorSelectionArgs にキャストして色情報とマッチモードを取得
2. _ApplyToActiveControls で全アクティブコントロールに適用
   └─ control.ColorSelection(fg, bg, matchMode) を呼び出し
3. TermControl.ColorSelection → ControlCore.ColorSelection
   └─ LockForWriting でロック取得
4. ControlCore.ColorSelection
   └─ 選択がアクティブか確認
   └─ SelectionColor から TextColor への変換（前景・背景それぞれ）
   └─ TextAttribute を作成
5. Terminal::ColorSelection(attr, matchMode)
   ├─ [MatchMode::None] → 選択範囲の各スパンに直接色を適用
   └─ [MatchMode::All] → 選択テキストを取得し、バッファ全体で一致テキストを検索して色を適用
6. 後処理
   └─ Terminal::ClearSelection で選択解除
   └─ [MatchMode::All の場合] _renderer->TriggerRedrawAll で全画面再描画
```

### フローチャート

```mermaid
flowchart TD
    A[ColorSelection アクション受信] --> B{ColorSelectionArgs 取得成功?}
    B -->|No| Z[何もしない]
    B -->|Yes| C[_ApplyToActiveControls]
    C --> D[ControlCore.ColorSelection]
    D --> E{選択がアクティブ?}
    E -->|No| Z
    E -->|Yes| F[SelectionColor → TextColor 変換]
    F --> G[TextAttribute 作成]
    G --> H{MatchMode}
    H -->|None| I[選択スパンに直接色を適用]
    H -->|All| J[選択テキストを取得]
    J --> K[バッファ全体で SearchText]
    K --> L[全一致箇所に色を適用]
    I --> M[ClearSelection]
    L --> M
    M --> N{MatchMode == All?}
    N -->|Yes| O[TriggerRedrawAll]
    N -->|No| P[完了]
    O --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-01 | 選択必須 | 選択がアクティブでない場合は色付けができない | IsSelectionActive が false |
| BR-39-02 | MatchMode::None | 選択範囲のスパンのみに色を適用する | MatchMode が None |
| BR-39-03 | MatchMode::All | 選択テキストと同じテキストをバッファ全体から検索し、すべての一致箇所に色を適用する | MatchMode が All |
| BR-39-04 | ブロック選択時のトリム | ブロック選択の場合、検索テキストの前後の空白をトリムする | IsBlockSelection が true かつ MatchMode が All |
| BR-39-05 | 大文字小文字の区別 | 全一致検索は大文字小文字を区別しない（CaseInsensitive） | MatchMode が All |
| BR-39-06 | 選択解除 | 色適用後に選択状態をクリアする | 常に適用 |

### 計算ロジック

- テキスト検索: `textBuffer.SearchText(textView, SearchFlag::CaseInsensitive)`
- 色適用: `textBuffer.Write(OutputCellIterator(attr, spanLength), coordStartInclusive)`

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 選択なし | テキストが選択されていない状態で実行 | 何もしない |
| - | 検索テキスト空 | MatchMode::All で選択テキストが空の場合 | 色付けをスキップ |
| - | 例外 | 色適用処理で例外発生 | CATCH_LOG() で例外をキャッチしてログ記録 |

### リトライ仕様

リトライは行わない。

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

Terminal::ColorSelection の実行中は LockForWriting でロックを保持する。色適用はテキストバッファに直接書き込むため、ロック保持中に完了する。

## パフォーマンス要件

MatchMode::All の場合はバッファ全体の検索が必要となるため、大きなバッファでは処理時間が増加する可能性がある。

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

特になし。

## 備考

- ColorSelection はテキストバッファの属性を直接変更するため、永続的な変更となる
- 色付けされたテキストはコピー時にも色情報が含まれる（書式付きコピーの場合）
- MatchMode::All での検索は CaseInsensitive で行われる
- ブロック選択時のテキストは Utils::TrimPaste でトリムされてから検索に使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | ColorSelectionArgs の定義。Foreground, Background, MatchMode プロパティ |

**読解のコツ**: SelectionColor は WinRT 型で、AsTextColor() メソッドにより TextColor に変換される。MatchMode は None と All の列挙値。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleColorSelection がエントリーポイント |

**主要処理フロー**:
1. **1544-1557行目**: ColorSelectionArgs へのキャスト、_ApplyToActiveControls で全コントロールに適用

#### Step 3: ControlCore 層

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ColorSelection の SelectionColor → TextColor 変換と Terminal 呼び出し |

**主要処理フロー**:
- **2778-2815行目**: LockForWriting、選択確認、SelectionColor → TextColor 変換、TextAttribute 作成、Terminal::ColorSelection 呼び出し、ClearSelection、MatchMode::All 時の TriggerRedrawAll

#### Step 4: Terminal コア層

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Terminal.cpp | `src/cascadia/TerminalCore/Terminal.cpp` | Terminal::ColorSelection のマッチモード分岐と色適用ロジック |

**主要処理フロー**:
- **1537-1576行目**: colorSelection ラムダで範囲への色適用、_GetSelectionSpans() で選択スパン取得、MatchMode 分岐、SearchText による全一致検索

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

```
TerminalPage::_HandleColorSelection (AppActionHandlers.cpp:1544)
    |
    +-- _ApplyToActiveControls
           |
           +-- TermControl::ColorSelection (TermControl.cpp:3875)
                  |
                  +-- ControlCore::ColorSelection (ControlCore.cpp:2778)
                         |
                         +-- Terminal::ColorSelection (Terminal.cpp:1537)
                         |      |
                         |      +-- _GetSelectionSpans
                         |      +-- [None] textBuffer.Write (直接色適用)
                         |      +-- [All] textBuffer.GetPlainText → SearchText → Write
                         |
                         +-- Terminal::ClearSelection
                         +-- [All] _renderer->TriggerRedrawAll
```

### データフロー図

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

ColorSelectionArgs   --> _HandleColorSelection            --> 色情報とモード取得
  (Foreground,           |
   Background,           v
   MatchMode)        ControlCore::ColorSelection          --> TextAttribute 作成
                         |
                         v
選択範囲 +           Terminal::ColorSelection             --> テキストバッファの
テキストバッファ         |                                    属性更新
                    [None] 選択スパンに色適用
                    [All]  SearchText → 全一致に色適用
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleColorSelection アクションハンドラ |
| TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ソース | ColorSelection の委譲 |
| TermControl.h | `src/cascadia/TerminalControl/TermControl.h` | ヘッダ | ColorSelection 宣言 |
| ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ソース | ColorSelection の SelectionColor 変換と Terminal 呼び出し |
| Terminal.cpp | `src/cascadia/TerminalCore/Terminal.cpp` | ソース | Terminal::ColorSelection の色適用ロジック |
| Terminal.hpp | `src/cascadia/TerminalCore/Terminal.hpp` | ヘッダ | ColorSelection 宣言 |
| ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | IDL | ColorSelectionArgs の型定義 |
