# 機能設計書 34-入力の送信

## 概要

本ドキュメントは、Windows Terminal における「入力の送信」機能（SendInput アクション）の設計を記述する。指定されたテキスト文字列をターミナルに直接送信する機能であり、ショートカットキーへのテキスト割り当て、スニペット実行、サジェスチョン選択時のコマンド送信などに使用される。

### 本機能の処理概要

**業務上の目的・背景**：キーバインドやアクションに任意のテキストを紐付けて、ワンタッチでコマンドやテキストをターミナルに送信する機能である。頻繁に使用するコマンドの登録、特殊キーシーケンスの送信、スニペット管理などに活用される。

**機能の利用シーン**：ユーザーがキーバインドに割り当てた SendInput アクションを実行したとき、スニペットペインからスニペットを選択したとき、サジェスチョンコントロールから候補を選択したとき、マークダウンペインからコードブロックを実行したときに使用される。

**主要な処理内容**：
1. _HandleSendInput で ActionEventArgs を受信し、SendInputArgs から入力テキストを取得
2. _senderOrActiveControl で対象の TermControl を特定
3. TermControl.SendInput で入力プレビューを解除し、StringSent イベントを発火
4. RawWriteString でテキストをターミナル接続に送信

**関連システム・外部連携**：ターミナル接続（ConPTY等）を経由してシェルプロセスの標準入力にテキストが送信される。スニペットペイン、サジェスチョンコントロール、マークダウンペインなど複数のUIコンポーネントから呼び出される。

**権限による制御**：読み取り専用モードの場合、ControlCore.SendInput で入力が拒否され読み取り専用警告が表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | TermControl（ターミナル表示） | 主画面 | SendInput によりテキストをターミナルに送信 |
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleSendInput でアクションを処理 |
| 8 | MarkdownPaneContent（Markdownビューア） | 参照画面 | コードブロック実行時にターミナルへテキストを送信 |
| 9 | SnippetsPaneContent（スニペット管理） | 参照画面 | スニペット選択時にターミナルへコマンドを送信 |
| 11 | SuggestionsControl（サジェスト） | 参照画面 | サジェスチョン選択時にターミナルへコマンドを送信 |

## 機能種別

テキスト操作 / 入力送信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Input | String | Yes | ターミナルに送信するテキスト文字列。エスケープシーケンスを含むことが可能 | 空文字でない |

### 入力データソース

- SendInputArgs のキーバインドアクション設定
- スニペットペインのスニペットデータ
- サジェスチョンコントロールの選択候補

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | - | テキストがターミナル接続に送信される |

### 出力先

- ターミナル接続（ConPTY等）を経由してシェルプロセスの標準入力

## 処理フロー

### 処理シーケンス

```
1. _HandleSendInput が sender と ActionEventArgs を受信
   └─ args が nullptr の場合は handled = false
2. SendInputArgs にキャストして Input プロパティを取得
3. _senderOrActiveControl で対象 TermControl を特定
   └─ sender が TermControl であればそれを使用、そうでなければアクティブコントロール
4. TermControl.SendInput を呼び出し
   └─ PreviewInput(hstring{}) で入力プレビューを解除
   └─ StringSent イベントを発火（リスナーがある場合）
   └─ RawWriteString で実際の入力を送信
5. RawWriteString → ControlCore.SendInput
   └─ _isReadOnly チェック
   └─ _sendInputToConnection でターミナル接続に書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[SendInput アクション受信] --> B{args が null?}
    B -->|Yes| Z[handled = false]
    B -->|No| C{SendInputArgs 取得成功?}
    C -->|No| Z
    C -->|Yes| D[_senderOrActiveControl で TermControl 取得]
    D --> E{TermControl 取得成功?}
    E -->|No| Z
    E -->|Yes| F[PreviewInput を解除]
    F --> G{StringSent リスナーあり?}
    G -->|Yes| H[StringSent イベント発火]
    G -->|No| I[RawWriteString 呼び出し]
    H --> I
    I --> J{読み取り専用?}
    J -->|Yes| K[読み取り専用警告]
    J -->|No| L[_sendInputToConnection]
    L --> M[handled = true]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-01 | null 引数チェック | args が nullptr の場合は handled = false として処理をスキップ | args == nullptr |
| BR-34-02 | sender 優先 | sender が TermControl の場合はそれを対象とし、それ以外の場合はアクティブコントロールを対象とする | 常に適用 |
| BR-34-03 | 読み取り専用保護 | 読み取り専用モードでは入力が拒否される | _isReadOnly が true |
| BR-34-04 | 空文字チェック | 空文字列の場合は SendInput が早期リターンする | 入力テキストが空 |

### 計算ロジック

なし

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 引数 null | args が nullptr | handled = false として処理をスキップ |
| - | コントロール未取得 | アクティブな TermControl がない | 何もしない |
| - | 読み取り専用 | 読み取り専用モードで SendInput を実行 | 読み取り専用警告を表示し入力を拒否 |

### リトライ仕様

リトライは行わない。

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

SendInput は接続への書き込みを行うため、ターミナルロックを保持しない状態で実行される。

## パフォーマンス要件

テキスト送信は即座に行われること。大量のテキスト送信時でもUIスレッドをブロックしないこと。

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

- SendInput は任意のテキストをターミナルに送信するため、設定ファイルに保存されたコマンドの安全性はユーザーの責任
- エスケープシーケンスを含むテキストも送信可能であるため、VTシーケンスインジェクションのリスクがある

## 備考

- SendInput は settings.json でアクションとして設定され、任意のキーバインドに紐付けることができる
- スニペット管理機能（No.113, No.114）と密接に連携している
- サジェスチョン機能（No.74）からのコマンド実行にも使用される
- PreviewInput の解除は、サジェスチョン選択前にプレビュー表示されていたテキストをクリアするためのもの

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: `SendInputArgs(String input)` コンストラクタで入力テキストを受け取り、`Input` プロパティでアクセスする。

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

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

**主要処理フロー**:
1. **177-192行目**: args の null チェック、SendInputArgs へのキャスト、_senderOrActiveControl でコントロール取得、termControl.SendInput(realArgs.Input()) 呼び出し

#### Step 3: TermControl 層

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | SendInput メソッドの実装 |

**主要処理フロー**:
- **910-922行目**: PreviewInput 解除、StringSent イベント発火（リスナーがある場合）、RawWriteString 呼び出し

#### Step 4: ControlCore 層

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | SendInput で空文字チェック、読み取り専用チェック、接続への送信 |

**主要処理フロー**:
- **489-508行目**: 空文字チェック、_terminal->_assertUnlocked() でロック未保持を確認、_isReadOnly チェック、_sendInputToConnection 呼び出し

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

```
TerminalPage::_HandleSendInput (AppActionHandlers.cpp:177)
    |
    +-- TermControl::SendInput (TermControl.cpp:910)
           |
           +-- PreviewInput(hstring{})
           +-- StringSent イベント発火
           +-- RawWriteString
                  |
                  +-- ControlCore::SendInput (ControlCore.cpp:489)
                         |
                         +-- _sendInputToConnection
```

### データフロー図

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

SendInputArgs.Input  --> _HandleSendInput                --> TermControl 特定
  (テキスト文字列)       |
                         v
                     TermControl::SendInput              --> StringSent イベント
                         |
                         v
                     ControlCore::SendInput              --> _sendInputToConnection
                         |                                      |
                         v                                      v
                     読み取り専用チェック                  --> ターミナル接続
                                                              (シェルの標準入力)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleSendInput アクションハンドラ |
| TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ソース | SendInput の実装 |
| TermControl.h | `src/cascadia/TerminalControl/TermControl.h` | ヘッダ | SendInput 宣言 |
| ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ソース | SendInput のコア実装 |
| ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | IDL | SendInputArgs の型定義 |
| SnippetsPaneContent.cpp | `src/cascadia/TerminalApp/SnippetsPaneContent.cpp` | ソース | スニペット実行時の呼び出し元 |
| SuggestionsControl.cpp | `src/cascadia/TerminalApp/SuggestionsControl.cpp` | ソース | サジェスチョン選択時の呼び出し元 |
| MarkdownPaneContent.cpp | `src/cascadia/TerminalApp/MarkdownPaneContent.cpp` | ソース | コードブロック実行時の呼び出し元 |
