# 機能設計書 52-マークの追加

## 概要

本ドキュメントは、Windows Terminal における「マークの追加」機能の設計を記述する。AddMark アクションにより、現在のカーソル位置またはテキスト選択位置にスクロールバーマークを追加する機能である。

### 本機能の処理概要

**業務上の目的・背景**：ターミナルでの作業中、特定の位置にブックマークのようなマークを付けておくことで、後からその位置に素早く戻ることができる。長い出力ログの中で重要な箇所を記録したり、作業の区切りを視覚的に示すために利用する。スクロールバー上にマークが色付きで表示されるため、バッファ全体の中での重要箇所が一目で分かる。

**機能の利用シーン**：ユーザーがターミナル作業中に、現在のカーソル位置に目印を付けたい場合に利用する。任意の色を指定してマークを追加でき、後から ScrollToMark アクションでマーク位置に戻ることができる。

**主要な処理内容**：
1. ユーザーが AddMark アクションを実行（キーバインドまたはコマンドパレット経由）
2. ActionArgs から AddMarkArgs を取得し、オプションの色情報を読み取る
3. ControlCore がテキスト選択中であれば選択アンカー位置、そうでなければカーソル位置を取得
4. ScrollbarData にマーク情報を設定し、Terminal::AddMarkFromUI で TextBuffer にマークを追加
5. スクロールバーの再描画を通知

**関連システム・外部連携**：シェル統合機能で自動的に付与されるマーク（コマンドプロンプト位置）と同じ仕組みを使用する。テキストバッファの ScrollbarData として管理される。

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleAddMarkにより現在位置にマークを追加 |

## 機能種別

データ登録操作（インメモリ）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Color | IReference<Color> | No | マークの色。Nullable。指定しない場合は色情報なし | Windows.UI.Color 型 |

### 入力データソース

キーバインド設定またはコマンドパレットからの AddMark アクション。ActionArgs 経由で AddMarkArgs として色パラメータを受け取る。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Handled | bool | アクションが処理されたかどうか（常に true） |
| マーク | ScrollbarData | TextBuffer に追加されるマーク情報 |

### 出力先

TextBuffer の ScrollbarData としてインメモリに保存される。スクロールバーに色付きマークとして表示される。

## 処理フロー

### 処理シーケンス

```
1. TerminalPage::_HandleAddMark がアクションイベントを受信
   └─ ActionArgs から AddMarkArgs を取得
2. _ApplyToActiveControls でアクティブなコントロールに処理を適用
3. ControlCore::AddMark が実行される
   └─ ターミナルのロックを取得（LockForReading）
4. ScrollbarData を構築
   ├─ Color が指定されている場合: mark.Color に設定
   └─ Color が未指定の場合: HasValue = false
5. マーク位置の決定
   ├─ テキスト選択中: GetSelectionAnchor().y
   └─ 非選択時: GetTextBuffer().GetCursor().GetPosition().y
6. Terminal::AddMarkFromUI(mark, row) を呼び出し
   ├─ Alt Buffer 中は処理をスキップ（return）
   ├─ _activeBuffer().SetScrollbarData(mark, y) でバッファにマーク設定
   └─ _NotifyScrollEvent() でスクロールバー再描画通知
```

### フローチャート

```mermaid
flowchart TD
    A[AddMark アクション受信] --> B[AddMarkArgs から色情報取得]
    B --> C[_ApplyToActiveControls]
    C --> D[ControlCore::AddMark]
    D --> E{Color 指定あり?}
    E -->|Yes| F[mark.Color に色設定]
    E -->|No| G[mark.Color.HasValue = false]
    F --> H{テキスト選択中?}
    G --> H
    H -->|Yes| I[row = GetSelectionAnchor.y]
    H -->|No| J[row = GetCursor.GetPosition.y]
    I --> K[Terminal::AddMarkFromUI]
    J --> K
    K --> L{Alt Buffer 中?}
    L -->|Yes| M[処理スキップ]
    L -->|No| N[SetScrollbarData でマーク追加]
    N --> O[_NotifyScrollEvent でスクロールバー再描画]
    O --> P[終了]
    M --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-1 | 色のオプション | 色指定は任意。未指定の場合は色情報なしのマークとなる | 常時 |
| BR-52-2 | 位置決定ルール | テキスト選択中はアンカー位置、非選択時はカーソル位置にマーク | 常時 |
| BR-52-3 | Alt Buffer 制限 | 代替バッファ使用中はマーク追加を無視する | Alt Buffer アクティブ時 |

### 計算ロジック

特になし。

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

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

本機能はデータベース操作を行わない。TextBuffer のインメモリ ScrollbarData にマークを追加する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | Alt Buffer 制限 | 代替バッファ使用中にマーク追加を試みた場合 | 静かにスキップ（エラー通知なし） |
| なし | ActionArgs 取得失敗 | AddMarkArgs へのキャストが失敗 | 処理をスキップし、Handled=true を返す |

### リトライ仕様

リトライ処理は不要。

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

本機能にトランザクション制御はない。ターミナルの読み取りロック（LockForReading）を取得して一貫性を確保する。

## パフォーマンス要件

単一マーク追加の処理であり、O(1) で完了する。スクロールバー再描画通知は非同期。

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

特になし。ユーザーのローカルターミナルバッファ内の操作のみ。

## 備考

- AddMark アクションは AllShortcutActions.h で定義されている
- シェル統合機能によるマーク自動追加は別の経路（VT シーケンス経由）で行われるが、同じ TextBuffer のマーク機構を使用する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ICoreState.idl | `src/cascadia/TerminalControl/ICoreState.idl` | ScrollMark 構造体（Row, Color）の定義 |
| 1-2 | ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | AddMarkArgs の定義（Color プロパティ、IReference<Color> 型） |
| 1-3 | Terminal.hpp | `src/cascadia/TerminalCore/Terminal.hpp` | AddMarkFromUI の宣言（ScrollbarData, CoordType） |

**読解のコツ**: WinRT の `IReference<T>` は Nullable 型を表す。`Color` が null の場合、色なしマークとなる。`ScrollbarData` は `::ScrollbarData` として C++ ネイティブ構造体。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleAddMark メソッド（392-411行目） |

**主要処理フロー**:
1. **392-411行目**: AddMarkArgs を取得し、ScrollMark を構築して control.AddMark(mark) を呼び出す
2. **398-407行目**: 色の有無に基づいて mark.Color を設定

#### Step 3: ControlCore のマーク追加処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | AddMark メソッド（2562-2576行目） |

**主要処理フロー**:
- **2562-2576行目**: ScrollbarData 構築、選択/カーソル位置に基づくマーク行決定、Terminal::AddMarkFromUI 呼び出し

#### Step 4: Terminal コアのマーク登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Terminal.cpp | `src/cascadia/TerminalCore/Terminal.cpp` | AddMarkFromUI メソッド（1439-1452行目） |

**主要処理フロー**:
- **1439-1452行目**: Alt Buffer チェック、SetScrollbarData でバッファにマーク追加、_NotifyScrollEvent で再描画通知

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

```
TerminalPage::_HandleAddMark (AppActionHandlers.cpp:392)
    │
    ├─ ActionArgs.try_as<AddMarkArgs>() → 色パラメータ取得
    │
    └─ _ApplyToActiveControls
           │
           └─ ControlCore::AddMark (ControlCore.cpp:2562)
                  │
                  ├─ IsSelectionActive() → 位置決定
                  │
                  └─ Terminal::AddMarkFromUI (Terminal.cpp:1439)
                         │
                         ├─ _inAltBuffer() チェック
                         ├─ _activeBuffer().SetScrollbarData(mark, y)
                         └─ _NotifyScrollEvent()
```

### データフロー図

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

AddMarkArgs         ───▶ TerminalPage                ───▶ TextBuffer に
(Color: optional)        ::_HandleAddMark                  ScrollbarData 追加
                              │
                              ▼
                         ControlCore::AddMark
                              │
                              ├─ カーソル/選択位置取得
                              │
                              ▼
                         Terminal::AddMarkFromUI
                              │
                              ▼
                         SetScrollbarData ────────────▶ スクロールバー再描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleAddMark アクションハンドラー |
| ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ソース | AddMark の実装（位置決定・マーク構築） |
| ControlCore.h | `src/cascadia/TerminalControl/ControlCore.h` | ヘッダー | AddMark メソッド宣言 |
| ICoreState.idl | `src/cascadia/TerminalControl/ICoreState.idl` | IDL | ScrollMark 構造体定義 |
| ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | IDL | AddMarkArgs 定義 |
| AllShortcutActions.h | `src/cascadia/TerminalSettingsModel/AllShortcutActions.h` | ヘッダー | AddMark アクション登録 |
| Terminal.cpp | `src/cascadia/TerminalCore/Terminal.cpp` | ソース | AddMarkFromUI の実装 |
| Terminal.hpp | `src/cascadia/TerminalCore/Terminal.hpp` | ヘッダー | AddMarkFromUI 宣言 |
| TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ソース | TermControl の AddMark ラッパー |
