# 機能設計書 47-テーマ一覧

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおける「テーマ一覧」機能の設計を記述する。この機能は、CLIコマンド`+list-themes`を通じて、利用可能なテーマを一覧表示し、TTY環境ではインタラクティブなプレビュー機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Ghosttyは多数の組み込みテーマを同梱しており、ユーザーが好みのテーマを見つけて適用できることが重要である。テーマ一覧機能は、利用可能なすべてのテーマを表示し、TTY環境ではリアルタイムでプレビューできるインタラクティブなUIを提供することで、テーマ選択を効率化する。

**機能の利用シーン**：
- 利用可能なテーマの一覧を確認する
- テーマのリアルタイムプレビューを行う
- ダーク/ライトテーマのみをフィルタリングして表示する
- テーマ名をクリップボードにコピーする
- 選択したテーマを自動設定ファイルに保存する

**主要な処理内容**：
1. テーマディレクトリの検索（ユーザー/リソース）
2. テーマファイルの列挙とソート
3. TTY検出による出力モード切り替え
4. インタラクティブプレビューUI（vaxis使用）
5. ダーク/ライトフィルタリング
6. テーマの自動設定ファイルへの保存

**関連システム・外部連携**：
- ファイルシステム（テーマディレクトリ）
- vaxisライブラリ（TUI）
- zfライブラリ（ファジー検索）

**権限による制御**：特になし。すべてのユーザーがテーマ一覧を実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| なし | - | - | CLI専用機能（TUIプレビュー含む）のため画面関連なし |

## 機能種別

情報表示 / インタラクティブUI / CLI出力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | bool | No | テーマのフルパスを表示するかどうか | デフォルト: false |
| plain | bool | No | プレーンリストを強制するかどうか | デフォルト: false |
| color | ColorScheme | No | フィルタするカラースキーム（all/dark/light） | デフォルト: all |

### 入力データソース

- コマンドライン: `ghostty +list-themes [オプション]`
- テーマディレクトリ:
  1. `$XDG_CONFIG_HOME/ghostty/themes/`
  2. `<リソースディレクトリ>/themes/`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テーマ名 | []const u8 | テーマファイル名 |
| ロケーション | Location | テーマの場所（user/resources） |
| パス | []const u8 | テーマファイルのフルパス（--path指定時） |

### 出力先

- 標準出力（プレーンモード）
- TTY（インタラクティブプレビュー）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数のパース
   └─ Options構造体への値設定

2. テーマディレクトリの検索
   └─ LocationIteratorでユーザー/リソースディレクトリを走査

3. テーマファイルの列挙
   └─ ディレクトリ内のファイルを列挙
   └─ .DS_Store等を除外

4. テーマリストのソート
   └─ アルファベット順（大文字小文字無視）

5. 出力モードの決定
   └─ TTY + !plain: インタラクティブプレビュー
   └─ それ以外: プレーン出力

6. プレビューモード（TTYの場合）
   └─ vaxisでTUI初期化
   └─ キー入力ハンドリング
   └─ リアルタイムプレビュー表示

7. プレーン出力（非TTYの場合）
   └─ テーマ名とロケーションを出力
```

### フローチャート

```mermaid
flowchart TD
    A[+list-themes実行] --> B[引数パース]
    B --> C[LocationIteratorでディレクトリ取得]
    C --> D[テーマファイル列挙]
    D --> E[アルファベット順ソート]
    E --> F{TTY && !plain?}
    F -->|Yes| G[Preview.init]
    F -->|No| H[プレーン出力]
    G --> I[イベントループ]
    I --> J{イベント種別}
    J -->|key_press| K[キー処理]
    J -->|mouse| L[マウス処理]
    J -->|winsize| M[リサイズ処理]
    K --> N{終了?}
    N -->|No| I
    N -->|Yes| O[終了]
    H --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | アルファベット順ソート | テーマは大文字小文字を無視してアルファベット順でソート | 常時 |
| BR-47-02 | ダーク/ライトフィルタ | --colorオプションでダーク/ライトテーマをフィルタリング可能 | --color指定時 |
| BR-47-03 | 輝度による分類 | 背景色の輝度が0.5未満ならダーク、それ以上ならライト | フィルタ適用時 |
| BR-47-04 | 自動テーマ保存 | 'w'キーで選択テーマをauto/theme.ghosttyに保存 | プレビューモード時 |

### 計算ロジック

輝度計算:
```
luminance = 0.2126 * R/255 + 0.7152 * G/255 + 0.0722 * B/255
is_dark = luminance < 0.5
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | NoThemesFound | テーマが1つも見つからない | エラーメッセージを表示 |
| - | リソースディレクトリなし | リソースディレクトリが見つからない | 警告を表示して続行 |

### リトライ仕様

リトライなし。

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

トランザクションは使用しない。

## パフォーマンス要件

- テーマ一覧の表示は数秒以内に完了すること
- プレビューのレスポンスは即座であること

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

- テーマファイルの内容はカラー設定のみを読み取る
- 自動テーマファイルへの書き込みはユーザー設定ディレクトリのみ

## 備考

- F1キーでヘルプ画面を表示
- ESCまたはqで終了
- '/'で検索モードに入る
- 'c'でテーマ名、'C'でパスをクリップボードにコピー

---

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

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

### 推奨読解順序

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

Options構造体とThemeListElement、Preview構造体を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | list_themes.zig | `src/cli/list_themes.zig` | Options構造体（21-40行目） |
| 1-2 | list_themes.zig | `src/cli/list_themes.zig` | ThemeListElement構造体（42-67行目） |
| 1-3 | list_themes.zig | `src/cli/list_themes.zig` | Preview構造体（232-290行目） |

**読解のコツ**: Previewは複雑なステートマシンであり、mode enumでnormal/help/search/saveの状態を管理する。

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

run関数の処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | list_themes.zig | `src/cli/list_themes.zig` | run関数（69-198行目） |

**主要処理フロー**:
1. **107-114行目**: 引数パース
2. **128行目**: リソースディレクトリ確認
3. **137-168行目**: テーマファイル列挙
4. **175行目**: アルファベット順ソート
5. **177-180行目**: TTY判定とプレビュー呼び出し
6. **182-193行目**: プレーン出力

#### Step 3: インタラクティブプレビュー

Preview構造体とイベントループを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | list_themes.zig | `src/cli/list_themes.zig` | Preview.init（253-281行目） |
| 3-2 | list_themes.zig | `src/cli/list_themes.zig` | Preview.run（292-323行目） |
| 3-3 | list_themes.zig | `src/cli/list_themes.zig` | Preview.update（432-526行目） |
| 3-4 | list_themes.zig | `src/cli/list_themes.zig` | Preview.draw（598-868行目） |

**主要処理フロー**:
- **292-323行目**: vaxisイベントループ
- **432-526行目**: キー入力処理
- **598-868行目**: 描画処理（テーマリスト、プレビュー、ヘルプ）

#### Step 4: 輝度計算とフィルタリング

テーマのダーク/ライト判定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | list_themes.zig | `src/cli/list_themes.zig` | shouldIncludeTheme関数（1734-1741行目） |

**主要処理フロー**:
- **1735-1738行目**: RGB値から輝度を計算
- **1739行目**: is_dark判定
- **1740行目**: フィルタ条件に基づく包含判定

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

```
ghostty +list-themes [options]
    │
    └─ cli.list_themes.run
           │
           ├─ args.parse (Optionsへ)
           │
           ├─ themepkg.LocationIterator
           │      ├─ user ディレクトリ
           │      └─ resources ディレクトリ
           │
           ├─ ディレクトリイテレーション
           │      └─ ThemeListElement収集
           │
           ├─ sortUnstable (アルファベット順)
           │
           └─ [TTY && !plain]
                  │
                  ├─ preview関数
                  │      └─ Preview.init
                  │             └─ Preview.run
                  │                    ├─ vaxis.Loop
                  │                    ├─ update (イベント処理)
                  │                    └─ draw (描画)
                  │
                  └─ [else] プレーン出力
```

### データフロー図

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

コマンドライン ──────▶ Options解析 ────────▶ フラグ
     │                     │
     │                     ▼
テーマディレクトリ ──▶ ファイル列挙 ────────▶ ThemeListElement[]
     │                     │
     │                     ▼
     │              sortUnstable
     │                     │
     │                     ▼
     └──────────────▶ [TTY]
                          │
                          ├─ Preview (TUI)
                          │      ├─ テーマリスト表示
                          │      ├─ プレビュー表示
                          │      └─ キー入力処理
                          │
                          └─ [非TTY] stdout出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| list_themes.zig | `src/cli/list_themes.zig` | ソース | テーマ一覧コマンドの実装 |
| theme.zig | `src/config/theme.zig` | ソース | テーマ検索とLocationIterator |
| Config.zig | `src/config/Config.zig` | ソース | テーマ設定の読み込み |
| tui.zig | `src/cli/tui.zig` | ソース | TUI機能の共通ユーティリティ |
| vaxis | 外部ライブラリ | ライブラリ | ターミナルUI描画 |
| zf | 外部ライブラリ | ライブラリ | ファジー検索 |
