# 画面設計書 11-SuggestionsControl（サジェスト）

## 概要

本ドキュメントは、Windows Terminal の SuggestionsControl（サジェスト）画面の設計仕様を記述する。SuggestionsControl は、ターミナル入力時にコマンド候補を表示し、ユーザーの入力補完を支援するフローティングパネルである。

### 本画面の処理概要

SuggestionsControl は、ユーザーがターミナル上でコマンドを入力する際に、コマンド履歴・タスク（sendInput スニペット）・クイックフィックスなどの候補をリスト表示し、選択・実行を可能にするコントロールである。

**業務上の目的・背景**：ターミナル操作において、過去に実行したコマンドの再利用やよく使うスニペットの呼び出しは頻繁に行われる操作である。SuggestionsControl は、これらのコマンド候補をカーソル位置付近にポップアップ表示することで、コマンド入力の効率を大幅に向上させる。また、シェル統合機能と連携してエラー発生時のクイックフィックス候補を提示する機能も備え、ユーザーの問題解決を支援する。

**画面へのアクセス方法**：TerminalPage 上でサジェスチョンアクション（`_HandleSuggestions`）が発動されることで表示される。具体的には、アクション設定でサジェスチョンに割り当てられたキーバインドの押下、またはシェル統合による自動提案イベントによりトリガーされる。

**主要な操作・処理内容**：
1. コマンド候補リストの表示：コマンド履歴、タスク（sendInput コマンド）、クイックフィックスを集約しリスト表示する
2. フィルタリング検索：検索ボックスへのテキスト入力により候補をリアルタイムでフィルタリングする
3. 候補の選択と実行：リストから候補を選択（クリックまたはキーボード操作）すると、対応するコマンドがターミナルへ送信される
4. ネストされたコマンドのナビゲーション：サブコマンドを持つ候補の展開と「戻る」ボタンによる階層移動
5. 説明パネルの表示：選択中の候補に説明やコメントがある場合、下部に説明領域を表示する

**画面遷移**：TerminalPage から入力時やキーバインド操作でサジェストパネルが表示される。候補選択後はパネルが閉じてターミナル（TermControl）にフォーカスが戻る。ESC キーやフォーカス喪失でもパネルは閉じる。

**権限による表示制御**：特になし。全ユーザーが利用可能。ただし、コマンド履歴はシェル統合が有効な場合のみ取得可能。クイックフィックスもシェル統合連携時のみ表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 74 | サジェスチョン | 主機能 | コマンド履歴・タスク・クイックフィックスからの候補表示 |
| 75 | クイックフィックス | 主機能 | シェル統合と連携しエラー修正候補を表示 |
| 34 | 入力の送信 | 補助機能 | サジェスチョン選択時にターミナルへコマンドを送信 |

## 画面種別

ツール（フローティングパネル / オーバーレイ）

## URL/ルーティング

該当なし（XAMLコントロールとして TerminalPage 内に配置される UserControl）

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| commands | 入力 | IVector\<Command\> | Yes | 表示するコマンド候補のリスト |
| mode | 入力 | SuggestionsMode | Yes | 表示モード（Palette / Menu） |
| filterText | 入力 | String | No | 初期フィルタテキスト（現在のコマンドライン） |
| anchor | 入力 | Point | Yes | パネルの表示位置（カーソル位置） |
| space | 入力 | Size | Yes | 利用可能な表示領域サイズ |
| characterHeight | 入力 | Single | Yes | 文字の高さ（ピクセル） |
| DispatchCommandRequested | 出力 | Event | - | コマンド実行要求イベント |
| PreviewAction | 出力 | Event | - | コマンドプレビューイベント |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| _searchBox | TextBox | フィルタリング用の検索テキストボックス（Palette モード時に表示） |
| _parentCommandText | TextBlock | 現在のネストされたコマンドの親コマンド名 |
| _parentCommandBackButton | Button | ネストされたコマンドから戻るためのボタン |
| _filteredActionsView | ListView | フィルタリングされたコマンド候補リスト |
| _noMatchesText | Border/TextBlock | 一致する候補がない場合のメッセージ |
| _descriptionTitle | TextBlock | 選択中コマンドの説明タイトル |
| _descriptionComment | TextBlock | 選択中コマンドの説明コメント |
| アイコン | ContentPresenter | 各コマンドのアイコン（16x16） |
| ハイライトテキスト | HighlightedTextControl | 検索一致部分がハイライトされたコマンド名 |

## イベント仕様

### 1-Open（パネル表示）

Open メソッドが呼び出されると、モードに応じた初期化（`_switchToMode`）が行われ、表示方向（TopDown / BottomUp）が設定される。コマンドリストが `_allCommands` にセットされ、フィルタリングが実行される。パネルの位置がアンカーポイントと利用可能スペースに基づいて計算され、Visibility が Visible に設定される。

### 2-フィルタテキスト変更

`_filterTextChanged` により検索ボックスのテキスト変更が検知されると、`_updateFilteredActions` が呼び出される。入力テキストで `_allCommands`（または `_currentNestedCommands`）をフィルタリングし、スコアの高い順にソートして `_filteredActions` に反映する。

### 3-候補選択（クリック）

`_listItemClicked` により、ListView のアイテムがクリックされると `_dispatchCommand` が呼び出される。選択されたコマンドにサブコマンドがある場合はネストされたコマンドリストに遷移し、ない場合は `DispatchCommandRequested` イベントを発火してパネルを閉じる。

### 4-キーボード操作

`_previewKeyDownHandler` により、以下のキー操作が処理される：
- **Enter**: 選択中の候補を実行
- **Escape**: パネルを閉じる
- **Up/Down**: 候補リスト内の選択を移動
- **Backspace**（検索ボックス空時）: ネストされたコマンドから親に戻る

### 5-フォーカス喪失

`_lostFocusHandler` により、パネルからフォーカスが外れるとパネルが閉じられる。

### 6-選択変更

`_listItemSelectionChanged` により、ListView の選択が変更されると、選択されたコマンドの説明パネル（`_descriptionsView`）が更新される。`PreviewAction` イベントも発火される。

## データベース更新仕様

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

該当なし。本画面はデータベースを直接操作しない。コマンド候補はメモリ上のデータ（設定ファイルの ActionMap、シェル統合のコマンド履歴）から取得される。

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|----------|---------------|
| NoMatchesText | 情報 | フィルタ結果が0件のとき | 候補が見つからない旨のメッセージ |
| SearchBoxPlaceholderText | プレースホルダ | 検索ボックスが空のとき | 検索テキストのプレースホルダ |

## 例外処理

- コマンドコレクションが null の場合：`_OpenSuggestions` 内で早期リターンし、パネルは表示されない（TerminalPage.cpp 行5219-5222）
- コマンドコレクションが空の場合：パネルの Visibility を Collapsed に設定して早期リターン（TerminalPage.cpp 行5223-5230）
- アクティブなコントロールがない場合：早期リターン（TerminalPage.cpp 行5232-5236）

## 備考

- SuggestionsControl は CommandPalette と類似の構造を持つが、カーソル位置付近にポップアップ表示される点が異なる
- SuggestionsMode には Palette と Menu の2つのモードがあり、Palette モードでは検索ボックスが表示され、Menu モードでは非表示となる
- SuggestionsDirection により上から下（TopDown）または下から上（BottomUp）の表示方向が制御される
- パネルの最大幅は300px、最大高さは300px に制限されている（XAML定義）
- 説明パネルはコマンドリストの下部に表示され、最大高さ64pxまでスクロール可能

---

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

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

### 推奨読解順序

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

SuggestionsControl で扱われる主要なデータ型（SuggestionsMode、FilteredCommand、Command）を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SuggestionsControl.idl | `src/cascadia/TerminalApp/SuggestionsControl.idl` | SuggestionsMode 列挙型（Palette / Menu）、SuggestionsDirection（TopDown / BottomUp）、公開プロパティとイベントの定義を確認（行10-15, 22-44） |
| 1-2 | FilteredCommand.idl | `src/cascadia/TerminalApp/FilteredCommand.idl` | FilteredCommand 構造体の定義。Item（Command）と NameHighlights の関係を理解する |

**読解のコツ**: IDL ファイルは WinRT コンポーネントのインターフェース定義であり、C++ 実装のパブリック API を把握するのに最適である。

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

TerminalPage から SuggestionsControl がどのように呼び出されるかを追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | `_HandleSuggestions` メソッド（行1447）がアクションのエントリーポイント。SuggestionsArgs から source を取得し、各ソースに応じたコマンド収集を行う |
| 2-2 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_OpenSuggestions` メソッド（行5209）で SuggestionsControl の Open を呼び出す。カーソル位置の座標変換ロジックも確認（行5240-5244） |

**主要処理フロー**:
1. **行1447**: `_HandleSuggestions` で SuggestionsArgs を受け取る
2. **行1460-1541**: `_doHandleSuggestions` で QuickFixes、Tasks、CommandHistory の各ソースからコマンドを収集
3. **行5209-5253**: `_OpenSuggestions` でカーソル位置を計算し、SuggestionsControl.Open を呼び出す

#### Step 3: XAML レイアウトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SuggestionsControl.xaml | `src/cascadia/TerminalApp/SuggestionsControl.xaml` | UI 構造を理解する。_backdrop（メインパネル）と _descriptionsBackdrop（説明パネル）の2つの Grid で構成される。DataTemplate（GeneralItemTemplate / NestedItemTemplate）によるリスト項目のレンダリングを確認 |

#### Step 4: コントロールの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SuggestionsControl.h | `src/cascadia/TerminalApp/SuggestionsControl.h` | クラス宣言。_filteredActions、_allCommands、_nestedActionStack 等のメンバ変数を確認（行69-76） |
| 4-2 | SuggestionsControl.cpp | `src/cascadia/TerminalApp/SuggestionsControl.cpp` | Open メソッドでモード設定・方向設定・コマンドセット・フィルタリングを行う。_updateFilteredActions でフィルタロジック、_dispatchCommand でコマンド実行ロジックを確認 |

**主要処理フロー**:
- **コンストラクタ**: InitializeComponent、テンプレートセレクターとリストアイテムテンプレートのルックアップ、コレクション初期化
- **Open**: モード設定 → 方向設定 → コマンド設定 → フィルタリング → 位置計算 → 表示
- **_filterTextChanged**: テキスト変更 → `_updateFilteredActions` → `_filteredActions` 更新
- **_dispatchCommand**: サブコマンド有無判定 → ネスト遷移 or DispatchCommandRequested 発火

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

```
TerminalPage::_HandleSuggestions (AppActionHandlers.cpp:1447)
    |
    +-- TerminalPage::_doHandleSuggestions (AppActionHandlers.cpp:1460)
    |       |
    |       +-- Command::HistoryToCommands (QuickFixes)
    |       +-- ActionMap::FilterToSnippets (Tasks)
    |       +-- Command::HistoryToCommands (CommandHistory)
    |       |
    |       +-- TerminalPage::_OpenSuggestions (TerminalPage.cpp:5209)
    |               |
    |               +-- TerminalPage::LoadSuggestionsUI (TerminalPage.cpp:2171)
    |               +-- SuggestionsControl::Open
    |                       |
    |                       +-- _switchToMode
    |                       +-- _setDirection
    |                       +-- SetCommands
    |                       +-- _updateFilteredActions
    |                       +-- _recalculateTopMargin
    |
    +-- SuggestionsControl::_dispatchCommand
            |
            +-- _updateCurrentNestedCommands (nested)
            +-- DispatchCommandRequested.raise (leaf)
```

### データフロー図

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

SuggestionsArgs          TerminalPage                        SuggestionsControl
  (Source flags)    -->  ::_doHandleSuggestions        -->   ::Open
                         |                                    |
CommandHistory      -->  Command::HistoryToCommands     -->  _allCommands
Tasks (ActionMap)   -->  ActionMap::FilterToSnippets    -->  _filteredActions (filtered)
QuickFixes          -->  Command::HistoryToCommands     -->  ListView display
                                                             |
UserInput (filter)  -->  _filterTextChanged             -->  _updateFilteredActions
                                                             |
UserSelection       -->  _listItemClicked               -->  DispatchCommandRequested
                         _dispatchCommand                    (Command sent to terminal)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SuggestionsControl.xaml | `src/cascadia/TerminalApp/SuggestionsControl.xaml` | ソース（XAML） | UI レイアウト定義 |
| SuggestionsControl.h | `src/cascadia/TerminalApp/SuggestionsControl.h` | ソース（ヘッダー） | クラス宣言・メンバ変数定義 |
| SuggestionsControl.cpp | `src/cascadia/TerminalApp/SuggestionsControl.cpp` | ソース（実装） | コントロールの動作ロジック |
| SuggestionsControl.idl | `src/cascadia/TerminalApp/SuggestionsControl.idl` | ソース（IDL） | WinRT インターフェース定義 |
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース（実装） | `_HandleSuggestions` / `_doHandleSuggestions` のエントリーポイント |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース（実装） | `_OpenSuggestions` / `LoadSuggestionsUI` 呼び出し元 |
| TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | ソース（XAML） | SuggestionsElement の配置定義（行170-176） |
| FilteredCommand.idl | `src/cascadia/TerminalApp/FilteredCommand.idl` | ソース（IDL） | FilteredCommand データ型定義 |
| HighlightedTextControl.idl | `src/cascadia/TerminalApp/HighlightedTextControl.idl` | ソース（IDL） | 検索ハイライト表示コントロール定義 |
| Resources.resw | `src/cascadia/TerminalApp/Resources/en-US/Resources.resw` | リソース | 各種文字列リソース |
